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
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)
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)
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)
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.
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)
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
Hkplus, you are saying the code above calculates which crc8 correctly now?
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)
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.
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)
Sounds like something to go for. The latest github version now has enough code to simulate these. lf simfsk
Yes
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...
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
Or holiman might be able to whip up a lua script for that.
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
He won't know
With the latest version on github there is, yes.
Currently, however it will not stop simulating until the button on the pm3 is pressed (or power is cycled). But I can change that.
lf simfsk [c <clock>] ['i'] ['H' <fcHigh>] ['L' <fcLow>] ['d' <hexdata>]
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)
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
I am pretty sure he shared the source code for the windows GUI.
The command was published in the code yesterday. The manual needs a lot of updating.
http://www.proxmark.org/forum/viewtopic … 681#p14681 for more info about the Sim commands
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
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)
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)
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)
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
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)
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"
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...
Oh and I'd like the vb for the algo definitely .
Last edited by marshmellow (2015-03-12 00:19:39)
Excellent