Research, development and trades concerning the powerful Proxmark3 device.
Remember; sharing is caring. Bring something back to the community.
"Learn the tools of the trade the hard way." +Fravia
You are not logged in.
Time changes and with it the technology
Proxmark3 @ discord
Users of this forum, please be aware that information stored on this site is not private.
I actually wrote a VB.NET program to do the CRC bit by bit. The program does a bit wise CRC 8 generation and tries every polynomial from 0x00 to 0xFF. It even has an option to feed the bits in of the message from LSB to MSB or MSB to LSB. I can't find a polynomial that seems to work either. I am assuming that I have the message input wrong. I am going to keep working on it its becoming an obsession at this point. The cracking device is still cracking away and there is every ID number found in site code zero at this point from ID 0 to ID 51000....will have discovered at least a complete set of one facility code, which is not bad. Now if this checksum could be found... this is driving me crazy!@ Wish I had an electronic way to emulate a card that I could pile through checksums against a real reader... this would be much faster.
ICEMAN, what are you using for a message to generate the CRC? I am using data bytes 0 - 12 with the parity bits.
Last edited by hkplus (2015-03-03 06:06:22)
Offline
Here is something for you guys to mess with (VB.NET) (doing it Wikipedia/steampunk style?):
Module Module1
Sub Main()
Dim message As Byte() = {1, 1, 1, 1, 1, 1, 1, 1, 1, &H40, 1, 1, 7}
Dim Invert As Boolean = False
Dim binomial As Byte = &HD5
Dim remainderToFInd As String = "64"
For binomialTrial As Integer = &H0 To &HFF
Dim CRC8 As String = ComputeCRC8(message, binomialTrial, Invert)
Dim ChecksumByte As String = AddOddParity(Convert.ToInt32(CRC8, 16)).Trim
'Console.Write(binomialTrial.ToString("X") & "-" & ChecksumByte)
If ChecksumByte.IndexOf(remainderToFInd) <> -1 Then
Console.WriteLine("&h" & binomialTrial.ToString("X"))
End If
'Console.WriteLine()
Next
Console.WriteLine("*** END OF SEARCH ***")
Console.ReadKey()
End Sub
Function ComputeCRC8(ByVal message As Byte(), ByVal binomial As Byte, ByVal Invert As Boolean) As String
'can someone double check that this is working correctly?
Dim numberOfSignificantBits As Integer = 8 * message.Length
'convert message to a character array of bits
Dim temp As String = ""
For i As Integer = 0 To message.Length - 1
temp = temp & Convert.ToString(message(i), 2).PadLeft(8, "0"c)
Next i
Dim MessageBits As Char() = temp.ToCharArray
If Invert = True Then
'invert all of the bits
Dim tempArray As Char()
ReDim tempArray(MessageBits.Length - 1)
For i As Integer = 0 To MessageBits.Length - 1
tempArray(MessageBits.Length - 1 - i) = MessageBits(i)
Next
Array.Copy(tempArray, MessageBits, tempArray.Length)
End If
'OutputCharArray(MessageBits)
'OutputNumberOfElements(MessageBits)
'Console.WriteLine("-------")
'Console.ReadKey()
'add seven bits to the end of the bit array in order to leave room for the remainder
ReDim Preserve MessageBits(MessageBits.Length - 1 + 7)
'fill the message bits array with the remainder zeros
For i As Integer = MessageBits.Length - 7 To MessageBits.Length - 1
MessageBits(i) = "0"
Next i
'convert the bionomial byte to a char array of bits
Dim BinomialBits As Char() = Convert.ToString(binomial, 2).PadLeft(8, "0"c).ToCharArray
'OutputCharArray(BinomialBits)
'OutputNumberOfElements(BinomialBits)
'let start doing the xor with the binomial
For messageBitPosition As Integer = 0 To numberOfSignificantBits - 1
If MessageBits(messageBitPosition) = "1" Then
'ArrayMonitor(MessageBits, BinomialBits, messageBitPosition)
'time to do the xor over all of the binomial bits
For binomialBitPosition As Integer = 0 To 7
'character based xor
If BinomialBits(binomialBitPosition) = "1" Then
If MessageBits(messageBitPosition + binomialBitPosition) = "1" Then MessageBits(messageBitPosition + binomialBitPosition) = "0" Else MessageBits(messageBitPosition + binomialBitPosition) = "1"
End If
Next binomialBitPosition
End If
Next
'now output the result
Dim remainder As String = ""
For i As Integer = MessageBits.Length - 1 - 7 To MessageBits.Length - 1
remainder = remainder & MessageBits(i)
Next
'Console.WriteLine(remainder)
Dim remainderVal As Integer = Convert.ToInt32(remainder, 2)
Return remainderVal.ToString("X")
End Function
Function AddOddParity(ByVal Checksum As Integer) As String
Dim temp As String = Convert.ToString(Checksum, 2).PadLeft(7, "0"c)
'count the number of ones in the string
Dim numberOfOnes = 0
For i As Integer = 0 To temp.Length - 1
If temp(i) = "1" Then numberOfOnes += 1
Next
Dim parityBit As String = "0"
If numberOfOnes Mod 2 = 0 Then parityBit = "1" Else parityBit = "0"
temp = temp & parityBit
'convert temp to a value
Dim tempval As Integer = Convert.ToInt32(temp, 2)
Return tempval.ToString("X")
End Function
Sub ArrayMonitor(ByVal MessageBits As Char(), ByVal BinomialBits As Char(), ByVal messageBitPosition As Integer)
'Console.WriteLine()
'Console.WriteLine(messageBitPosition + 1)
OutputCharArray(MessageBits)
For spaces = 0 To messageBitPosition - 1
Console.Write(" ")
Next
OutputCharArray(BinomialBits)
'Console.ReadKey()
End Sub
Sub OutputCharArray(ByVal elements As Char())
For i As Integer = 0 To elements.Length - 1
Console.Write(elements(i))
Next i
Console.WriteLine()
End Sub
Sub OutputNumberOfElements(ByVal elements As Char())
Console.WriteLine(elements.Length)
End Sub
End Module
Last edited by hkplus (2015-03-03 06:11:56)
Offline
Probably should remove the parities. That is how I would expect it to be. As I showed in post 45
Last edited by marshmellow (2015-03-03 06:22:58)
Offline
You could be right, but the patent does not indicate this. It says that CRC is calculated over data bytes 0 to 12, and this is after the patent talks about adding in the parity bits.
Offline
I checked crc the 04000001 styled messages..
Offline
My posted code is wrong...i only appended 7 zeroes instead of 8...and used a key with 8 bits. CRC8 actually uses a 9 bit binomial and an 8 bit remainder. I was assuming the last bit in the crc byte was an odd party bit...i am not sure that it is at this point. Going to work on the code more... to fix this.
Last edited by hkplus (2015-03-04 03:48:08)
Offline
Hi guys, here is corrected CRC 8 code. I tried the code against various examples on the internet and it provides correct values.
Module Module1
Sub Main()
'04000001
Dim message As Byte() = {1, 1, 1, 1, 1, 1, 1, 1, 1, &H40, 1, 1, 2, 1}
'message = {&H8F, &H97, &H43, &H61, 1, 1, 1, 1, 1, 1, 1, 1, 1}
Dim Invert As Boolean = True
' Dim binomial As UInt16 = &H1D5
Dim remainderToFind As String = "C7"
'Dim CRC8 As String = ComputeCRC8(message, binomial, Invert)
'Console.WriteLine(CRC8)
For binomialTrial As Integer = &H100 To &H1FF
Dim CRC8 As String = ComputeCRC8(message, binomialTrial, Invert)
If CRC8 = remainderToFind Then Console.WriteLine(CRC8.PadLeft(2, "0"c) & "-&h" & binomialTrial.ToString("X"))
Next
Console.WriteLine("*** END OF SEARCH ***")
Console.ReadKey()
End Sub
Function ComputeCRC8(ByVal message As Byte(), ByVal binomial As UInt16, ByVal Invert As Boolean) As String
'can someone double check that this is working correctly?
Dim numberOfSignificantBits As Integer = 8 * message.Length
'convert message to a character array of bits
Dim temp As String = ""
For i As Integer = 0 To message.Length - 1
temp = temp & Convert.ToString(message(i), 2).PadLeft(8, "0"c)
Next i
Dim MessageBits As Char() = temp.ToCharArray
If Invert = True Then
'invert all of the bits
Dim tempArray As Char()
ReDim tempArray(MessageBits.Length - 1)
For i As Integer = 0 To MessageBits.Length - 1
tempArray(MessageBits.Length - 1 - i) = MessageBits(i)
Next
Array.Copy(tempArray, MessageBits, tempArray.Length)
End If
'OK
'OutputCharArray(MessageBits)
'OutputNumberOfElements(MessageBits)
'Console.WriteLine("-------")
'Console.ReadKey()
'add eight bits to the end of the bit array in order to leave room for the remainder
ReDim Preserve MessageBits(MessageBits.Length - 1 + 8)
'fill the message bits array with the remainder zeros
For i As Integer = MessageBits.Length - 8 To MessageBits.Length - 1
MessageBits(i) = "0"
Next i
'convert the bionomial int to a char array of bits
Dim BinomialBits As Char() = Convert.ToString(binomial, 2).PadLeft(8, "0"c).ToCharArray
'OutputCharArray(BinomialBits)
'OutputNumberOfElements(BinomialBits)
'Console.ReadKey()
'let start doing the xor with the binomial
Dim messageBitPosition As Integer = 0
'For messageBitPosition = 0 To numberOfSignificantBits - 1
Do While messageBitPosition + 9 < MessageBits.Length
If MessageBits(messageBitPosition) = "1" Then
'ArrayMonitor(MessageBits, BinomialBits, messageBitPosition)
'time to do the xor over all of the binomial bits
For binomialBitPosition As Integer = 0 To 8
'character based xor
If BinomialBits(binomialBitPosition) = "1" Then
If MessageBits(messageBitPosition + binomialBitPosition) = "1" Then MessageBits(messageBitPosition + binomialBitPosition) = "0" Else MessageBits(messageBitPosition + binomialBitPosition) = "1"
End If
Next binomialBitPosition
End If
messageBitPosition += 1
'are you in the last column? If you are make sure that the value of residue is larger than the binomial value
If messageBitPosition + 9 = MessageBits.Length Then
'you are in the last column
'Console.WriteLine("last")
Dim residueStr As String = ""
For i As Integer = messageBitPosition To messageBitPosition + 8
residueStr = residueStr & MessageBits(i)
Next
'Console.WriteLine(residueStr) : Console.ReadKey()
Dim residueVal As UInt16
residueVal = Convert.ToUInt16(residueStr, 2)
If residueVal < binomial Then Exit Do
End If
Loop
'Next
'ArrayMonitor(MessageBits, BinomialBits, messageBitPosition)
'now output the result
Dim remainder As String = ""
For i As Integer = MessageBits.Length - 1 - 7 To MessageBits.Length - 1
remainder = remainder & MessageBits(i)
Next
'Console.WriteLine("***")
'Console.WriteLine(remainder)
Dim remainderVal As Integer = Convert.ToInt32(remainder, 2)
Return remainderVal.ToString("X")
End Function
Function AddOddParity(ByVal Checksum As Integer) As String
Dim temp As String = Convert.ToString(Checksum, 2).PadLeft(7, "0"c)
'count the number of ones in the string
Dim numberOfOnes = 0
For i As Integer = 0 To temp.Length - 1
If temp(i) = "1" Then numberOfOnes += 1
Next
Dim parityBit As String = "0"
If numberOfOnes Mod 2 = 0 Then parityBit = "1" Else parityBit = "0"
temp = temp & parityBit
'convert temp to a value
Dim tempval As Integer = Convert.ToInt32(temp, 2)
Return tempval.ToString("X")
End Function
Sub ArrayMonitor(ByVal MessageBits As Char(), ByVal BinomialBits As Char(), ByVal messageBitPosition As Integer)
'Console.WriteLine()
'Console.WriteLine(messageBitPosition + 1)
OutputCharArray(MessageBits)
For spaces = 0 To messageBitPosition - 1
Console.Write(" ")
Next
OutputCharArray(BinomialBits)
Console.WriteLine("-------------------------------------------------------------")
'Console.ReadKey()
End Sub
Sub OutputCharArray(ByVal elements As Char())
For i As Integer = 0 To elements.Length - 1
Console.Write(elements(i))
Next i
Console.WriteLine()
End Sub
Sub OutputNumberOfElements(ByVal elements As Char())
Console.WriteLine(elements.Length)
End Sub
End Module
Offline
I never got the hang on what bytes you are calculating the crc-8 on.
Offline
Hkplus, you are saying the code above calculates which crc8 correctly now?
Offline
The crc8 code posted correctly finds CRC8 checksum results verified against other example calculations on the web. It also searches through every possible binomial combination. The problem is that no one knows what the source message from the Farpointe card data should be or what bit order that source message is put through the checksum process. It's a tool for trying to figure this out...I was hoping that others could help in the search for the right message input through the use of this tool...There are 16 bytes in the Farpointe 26 bit format. The first two bytes are sync bytes (the top bytes are 00000000 00000001), the next 13 bytes are data bytes D12 - D0 and the last byte is the checksum value byte, according to my current understanding. D0 - D12 is what I believe is used to generate the checksum, but can't figure out if parity bits are included, and if not, how does this 8 bit data transform into useful 7 bit data...I need a new hobby I guess.
Last edited by hkplus (2015-03-05 15:07:53)
Offline
Usually the parity bits just drops off.
I.e: 000p110p01
Would translate into 00011001 = 25 (0x19)
And the 0x19 would be used for CRC.
Offline
unfortunately there are almost infinite possibilities. to get 7 bits instead of the 8 they could just drop the MSB, or they could bitshift once right.
more problematic though is what CRC calculation do they actually use. they might use one of many calculations publicly known or they may have taken one and altered it just a little to change the results. they could invert the bitstream before running it or after running it through the CRC. they could use a CRC16 and take only the right 7 bits from the output.
Offline
It can be difficult, but there are ways to get around these problems. We know that the seven MSB in the last block is the CRC and the eight bit is an odd parity. If the reader needs to use the checksum in order to see if the swipe is valid, that means that if you were to add the seven digits to the end of a message and run the crc process again the remainder should be zero (assuming that there are no bit inversions in the crc value and crc is actually being used). You need all of the crc bits to find the zero remainder to check the data, which means that you can't just shift or drop data. If the remainder is 7 bits, then the binomial has to be 8 bits and start with a 1 in the MSB. We could use the crc code posted to take the crc check value, append it to a (sequentially generated) message and sequentially generated binomial between 128 and 255, and output every message and binomial that the crc remainder = 0. Once you have this, you can look over the messages output and see if any of them resemble patterns in the original card data that used that particular crc value. If this works out you would know the binomial and how the message is generated, then flip this information around and finish the algorithm. This method still makes a lot of assumptions, but is worth a try and is the direction that I am going to work in next.
Last edited by hkplus (2015-03-10 02:17:48)
Offline
Sounds like something to go for. The latest github version now has enough code to simulate these. lf simfsk
Offline
Simulate a card to a reader?
Offline
Yes
Offline
Yes
I need to actually get a Proxmark...if I could feed it continuous commands to keep trying card data, that would be awesome. I don't know how the device really works...
Offline
Biggest current issue with automating a lf sim attack is a little programming to stop the simulation without the need to press the button on the pm3. ( which is the current method to stop Sim). But not that hard to adjust
Offline
Or holiman might be able to whip up a lua script for that.
Offline
I almost have a complete code book for all of FC 0, 26 bit Farpointe. There are some errors in the book, and missing entries i'm looking to fill. If there was a way to speed simulation up using Proxmark as a card emulator, this would allow the code book to be built more quickly that is for sure. Also running attack against the CRC as described in an earlier post, but this attack is taking more clock cycles than anticipated
Offline
There was a guy in the forums several years ago named MnBadger. Probably a snowballs chance in hell this guy knows how to generate the checksum for Farpointe?
Offline
He won't know
Offline
Is there a way to load HEX into a ProxMark and make it emulate a tag? Does not seem to be an easy way without firmware mod...
Offline
With the latest version on github there is, yes.
Offline
Currently, however it will not stop simulating until the button on the pm3 is pressed (or power is cycled). But I can change that.
Offline
lf simfsk [c <clock>] ['i'] ['H' <fcHigh>] ['L' <fcLow>] ['d' <hexdata>]
Offline
It would be great if the command was re-issued, then the next hex set is emulated. I wonder how fast this would happen emulation-wise and can I write software to talk with the Proxmark over the USB COM port connection for this? I should pick one of these things up and continue the righteous hacking lol...what are all of the other arguments in the command for? This command does not seem fully documented in the manual or am i missing something?
Last edited by hkplus (2015-03-11 05:36:49)
Offline
Might not have to talk directly with the pm3 over USB, but could use what gaucho did in vb.net? To emulate a command prompt and control the pm3 from the existing client and parse the responses. (Windows client gui -see aspers sticky post)
That coupled with a minor change to set the length of the Sim and you'd be in business
Offline
I am pretty sure he shared the source code for the windows GUI.
Offline
The command was published in the code yesterday. The manual needs a lot of updating.
Offline
http://www.proxmark.org/forum/viewtopic … 681#p14681 for more info about the Sim commands
Offline
Emulating a command prompt seems more difficult than sending a command to a serial port...i will have to review his code... Can commands be sent directly?
Offline
If you are only looking to send one or two commands then you might be right, serial port might be the way to go, but you will have to dig into the usbcmd driver code in the pm3 to see how commands are built. I don't think there is any documentation for that
Offline
Regarding the CRC, I used this tool https://github.com/sitsec/bruteforce-crc. It's a nice tool, however, I am not sure if I used the 'correct' indata. I just took the numbers, as in
0 0 C7
converted into binary
00000000000011000111
xxxxxxxxxxxxxxcccccccc
and then pointed the last 8 bytes as CRC of the previous 12. It's quite easy to run through some variations, if someone can explain to me a bit more these discussions about parity bits and whatnot. Should I try to remove some bits? Which?
Edit: Oh yeah, no crc was found..
Last edited by holiman (2015-03-11 22:28:10)
Offline
Yes, determining the correct message to run CRC on is a problem.
The 26 bit Farpointe card, FC 0 ID 0 has the following Atmel 5577 hex register values:
BLOCK 0: 80107080 (rf block)
SYNC 0 SYNC 1 D12 D11
BLOCK 1: 00010101 = 00000000 00000001 00000001 00000001
D10 D9 D8 D7
BLOCK 2: 01010101 = 00000001 00000001 00000001 00000001
D6 D5 D4 D3
BLOCK 3: 01010140 = 00000001 00000001 00000001 01000000
D2 D1 D0 EC
BLOCK 4: 010102C7 = 00000001 00000001 00000010 11000111
The first two bytes in Block 1 are syncronization blocks, these are 00000000 00000001
In the rest of the bytes, the least significant bit in each block is an odd parity over the previous 7 bits.
The third byte in BLOCK 1, Farpointe calls 'D12'...and summarily the remaining data blocks are labelled 'D11'...'D10' etc.
The checksum byte is called 'EC'.
The last byte in BLOCK 4 (EC) contains the checksum and a parity bit. The checksum value is the first 7 bits of the last byte in BLOCK4. The last bit in the last block in block 4 is also an odd parity bit over the 7 previous checksum bits.
In block 3, in the last byte, is a start bit that marks the start of the 26 bit stream. The next bit is the Wiegand even
parity which equals zero because there are no bits in the upper part of the wiegand format that are a 1.
Since FC = 0, the next 8 data bits are all zero. Since ID = 0, the next 16 data bits are zero. The 1 in the third byte of BLOCK 4
is the wiegand odd parity. The odd byte parity in BLOCK 4 is a zero because of the Wiegand 1 parity.
According to their patents, the CRC is calculated with D0 first up to D12. At this point no one knows the polynomial or if there are any other tricks like inversion done on the bit data.
Last edited by hkplus (2015-03-11 23:28:52)
Offline
0 1 2 3
B1: 00 01 01 01 = 00000000 00000001 00000001 00000001
B2: 01 01 01 01 = 00000001 00000001 00000001 00000001
B3: 01 01 01 40 = 00000001 00000001 00000001 01000000
B4: 01 01 02 C7 = 00000001 00000001 00000010 11000111
If I take away the B1[0-1] = preample
and use rest.
Starting D0 == B1[2]
giving:
0101 01010101 01010140 010102
Using the:
CRC-8/MAXIM
Gives the checksum: C7
Can you provide some more samples? With it I can see if this is a correct asupmtion
Last edited by iceman (2015-03-11 23:28:35)
Offline
FC 0 ID 1:
BLOCK 1: 00010101 = 00000000 00000001 00000001 00000001
D10 D9 D8 D7
BLOCK 2: 01010101 = 00000001 00000001 00000001 00000001
D6 D5 D4 D3
BLOCK 3: 01010140 = 00000001 00000001 00000001 01000000
D2 D1 D0 EC
BLOCK 4: 0101041A = 00000001 00000001 00000100 00011010
Offline
Yes!!
I get 0x1A
Offline
Holy shit I think you have it....the EC block does not have a parity...the whole thing is a Maxim CRC8 checksum! Damn good work man, Farpointe is cracked. Now to look at MaxSecure! lol
Last edited by hkplus (2015-03-11 23:41:53)
Offline
It is in little endian byte order, and the CRC is called: CRC-8/MAXIM
0101 01010101 01010140 010104 == 1A
width=8 poly=0x31 init=0x00 refin=true refout=true xorout=0x00 check=0xa1 name="CRC-8/MAXIM"
Offline
Yeah, I have been having some luck with CRC checksums lately
However, all work was done by you and @marshmellow
Offline
You don't know how much this problem was tormenting me over the last three weeks lol!
Offline
@hkplus, if you contact me (my mail is in the forum), we can test a bit more values.
Offline
Earlier in this thread I posted a ton of checksum values...i can get you a full breakdown of other bit values also. If you want, when it's finished I can post some vb.net code that calculates the maxim crc code if you guys want it.
Thanks for all of your help with this, my obsession has been relieved!
Perhaps I can post some future work on MaxSecure that I'm going to mess with...
Offline
Oh and I'd like the vb for the algo definitely .
Last edited by marshmellow (2015-03-12 00:19:39)
Offline
I tried some more of the earlier post, it still fits.
i think there some crc-8 in the pm3 source, should be able to use the poly to generate it.
Offline
Super work Iceman !
Offline
Excellent
Offline
We had great lock with this format. Do you guys want to start new hack threads for other formats?
Offline