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.
Not sure if there is a list thread, feel free to update and delete this thread as needed.
I got a white cloner to play with today.
It does not seem to do anything special, but did have 3 passwords in its writes, none of which was it the password file i have.
I have confirmed the following.
It sets the password to :
00434343
It also tried a password write with two other passwords, so I assume they have been used at some point
44B44CAE and 88661858
I tested this by creating a tag with each and got the cloner to write to it, it updated the card and changed the password to the one it set.
Edit:
Update
Seems that the white (English) Cloner puts different passwords on the card on write. The 44B44CAE and 88661858 are always in the first write commands so believe them to be common old ones.
I have started to play with how it knows the old password (if not the above 2). Early testing shows its based on the data/id.
The unit does not allow you to enter full id number ranges (it works in decimal), but I can set the customer ID to 0/1/2 and nothing seems to change in the password (more testing needed). But early bit testing does show things changing with the customer data bits.
Last edited by mwalker (2019-05-23 03:37:18)
Offline
These things are so frustrating! How is this for a laugh.
I ended up with one back in 2014 that shows correct ID's for HID and EM tags. You should even enter the ID like 103345 and get a HID chip programmed with SC: 10 ID: 3345.
Then in 2016 I got 4 more passed on to me that were totally different PCB revisions - they obfuscated the ID shown on the display so it was totally meaningless and similarly the ID entered to program would be scrambled. Go figure.
The only one I see worth playing with now is:
https://www.amazon.com/English-Version-Duplicator-Function-Machine/dp/B077HTDMK6
Apparently it has tag password management etc built in and storage for tag ID's.
Also if you look inside one of these colour screen ones that you are talking about - they are basically a proxmark3 with a screen and buttons. Same ARM chip - same FPGA and similar RF front end.... Crazy, just crazy..
Last edited by Tom5ive (2019-06-11 06:53:52)
Offline
LOL yeah, I got them for a play and to help me learn. Always good to have a goal when learning.
The white one I have is different but same button layout and speaks to you.
I spent some time and got it to spit out the "snoop" data for 0 1 2 4 ... max bit. so all the password for a single bit set.
Then based on that put to together my initial "password generator"
It almost worked with my test data. i.e. it was the 2 middle digits in the password that were a little out (but it could get worse).
My code worked for 00's and ff's and some others but not all.
Some bits seem to change nothing (as single bits) while others can change 2 bits.
If what you say is right (have not pulled to cover off yet), I might be better turning into a proxmark
So that said, If the goal is to "reuse" a card, then, with mine, all that I need to do is send a card ID of 0 (or any other known password) and then I know that password.
Offline
The algo probably uses some simple bit math. If you share your dataset the community could comment.
Offline
The raw data set.
My initial (random tests) seem to show that the "customer id" did not change the password. Just the 32 Bit User data
The decimal id was logged as thats what the programmer/cloner wants it keyed in as.
for Reference, bit order/index 32 31 .... 2 1
Dec. ID Binary ID Binary Password
0 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001 0000 0011 0000 0011
1 0000 0000 0000 0000 0000 0000 0000 0001 0000 0000 0000 0001 0000 0011 0000 0011
2 0000 0000 0000 0000 0000 0000 0000 0010 0000 0000 0000 0001 0000 0011 0000 0011
4 0000 0000 0000 0000 0000 0000 0000 0100 0000 0000 0000 0001 0000 0111 0000 0111
8 0000 0000 0000 0000 0000 0000 0000 1000 0000 0000 0000 0001 0000 1011 0000 1011
16 0000 0000 0000 0000 0000 0000 0001 0000 0000 0000 0000 0001 0000 0011 0000 0011
32 0000 0000 0000 0000 0000 0000 0010 0000 0000 0000 0000 0001 0010 0011 0010 0011
64 0000 0000 0000 0000 0000 0000 0100 0000 0000 0000 0000 0001 0100 0011 0100 0011
128 0000 0000 0000 0000 0000 0000 1000 0000 0000 0000 0000 0001 1000 0011 1000 0011
256 0000 0000 0000 0000 0000 0001 0000 0000 0000 0000 0000 0001 0000 0011 0000 0011
512 0000 0000 0000 0000 0000 0010 0000 0000 0000 0000 0000 0001 0000 0011 0000 0011
1024 0000 0000 0000 0000 0000 0100 0000 0000 0000 0000 0000 0001 0000 0011 0000 0011
2048 0000 0000 0000 0000 0000 1000 0000 0000 0000 0000 0000 0001 0000 0011 0000 0011
4096 0000 0000 0000 0000 0001 0000 0000 0000 0000 0000 0000 0001 0000 0011 0000 0011
8192 0000 0000 0000 0000 0010 0000 0000 0000 0000 0000 0000 0001 0000 0011 0000 0011
16384 0000 0000 0000 0000 0100 0000 0000 0000 0000 0000 0000 0001 0000 0011 0000 0011
32768 0000 0000 0000 0000 1000 0000 0000 0000 0000 0000 0000 0001 0000 0011 0000 0011
65536 0000 0000 0000 0001 0000 0000 0000 0000 0000 0000 0000 0001 0000 0011 0000 0011
131072 0000 0000 0000 0010 0000 0000 0000 0000 0000 0000 0000 0011 0000 0011 0000 0011
262144 0000 0000 0000 0100 0000 0000 0000 0000 0000 0000 0000 0101 0000 0011 0000 0011
524288 0000 0000 0000 1000 0000 0000 0000 0000 0000 0000 0000 1001 0000 0011 0000 0011
1048576 0000 0000 0001 0000 0000 0000 0000 0000 0000 0000 0000 0001 0000 0011 0000 0011
2097152 0000 0000 0010 0000 0000 0000 0000 0000 0000 0000 0010 0001 0000 0011 0000 0011
4194304 0000 0000 0100 0000 0000 0000 0000 0000 0000 0000 0100 0001 0000 0011 0000 0011
8388608 0000 0000 1000 0000 0000 0000 0000 0000 0000 0000 1000 0001 0000 0011 0000 0011
16777216 0000 0001 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001 0000 0011 0000 0011
33554432 0000 0010 0000 0000 0000 0000 0000 0000 0000 0010 0000 0001 0000 0101 0000 0011
67108864 0000 0100 0000 0000 0000 0000 0000 0000 0000 0100 0000 0001 0000 0111 0000 0011
134217728 0000 1000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001 0000 0011 0000 0011
268435456 0001 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001 0000 0011 0000 0011
536870912 0010 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001 0000 0011 0000 0011
1073741824 0100 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001 0000 0011 0000 0011
2147483648 1000 0000 0000 0000 0000 0000 0000 0000 1000 0000 0000 0001 1000 0011 0000 0011
where i started was I seeded the "password" with the result of all 0 (0000 0000 0000 0001 0000 0011 0000 0011)
Then i looked at what changes were made with each data bit set (based on an XOR) e.g LSB bit 3 (right most bit 1) XOR with password bit 3 and 11
e.g. (May not be 100% as i was playing)
Bit Action
1 0000 0000 0000 0000 0000 0000 0000 0001 -
2 0000 0000 0000 0000 0000 0000 0000 0010 -
4 0000 0000 0000 0000 0000 0000 0000 0100 xor b3, xor b11
8 0000 0000 0000 0000 0000 0000 0000 1000 xor b4, xor b12
16 0000 0000 0000 0000 0000 0000 0001 0000 -
32 0000 0000 0000 0000 0000 0000 0010 0000 xor b6, xor b14
64 0000 0000 0000 0000 0000 0000 0100 0000 xor b7, xor b15
128 0000 0000 0000 0000 0000 0000 1000 0000 xor b8, xor b16
256 0000 0000 0000 0000 0000 0001 0000 0000 -
512 0000 0000 0000 0000 0000 0010 0000 0000 -
1024 0000 0000 0000 0000 0000 0100 0000 0000 -
2048 0000 0000 0000 0000 0000 1000 0000 0000 -
4096 0000 0000 0000 0000 0001 0000 0000 0000 -
8192 0000 0000 0000 0000 0010 0000 0000 0000 -
16384 0000 0000 0000 0000 0100 0000 0000 0000 -
32768 0000 0000 0000 0000 1000 0000 0000 0000 -
65536 0000 0000 0000 0001 0000 0000 0000 0000 -
131072 0000 0000 0000 0010 0000 0000 0000 0000 xor b18
262144 0000 0000 0000 0100 0000 0000 0000 0000 xor b19
524288 0000 0000 0000 1000 0000 0000 0000 0000 xor b20
1048576 0000 0000 0001 0000 0000 0000 0000 0000 -
2097152 0000 0000 0010 0000 0000 0000 0000 0000 xor b22
4194304 0000 0000 0100 0000 0000 0000 0000 0000 xor b23
8388608 0000 0000 1000 0000 0000 0000 0000 0000 xor b24
16777216 0000 0001 0000 0000 0000 0000 0000 0000 -
33554432 0000 0010 0000 0000 0000 0000 0000 0000 xor b26, b11
67108864 0000 0100 0000 0000 0000 0000 0000 0000 xor b27, b10, b11
134217728 0000 1000 0000 0000 0000 0000 0000 0000 -
268435456 0001 0000 0000 0000 0000 0000 0000 0000 -
536870912 0010 0000 0000 0000 0000 0000 0000 0000 -
1073741824 0100 0000 0000 0000 0000 0000 0000 0000 -
2147483648 1000 0000 0000 0000 0000 0000 0000 0000 xor b32, xor 16
Happy to create the password for any "id values" needed.
Last edited by mwalker (2019-06-11 08:02:24)
Offline
could you double test the
33554432 0000 0010 0000 0000 0000 0000 0000 0000 0000 0010 0000 0001 0000 0101 0000 0011
line?
Offline
33554432 Password : 0000 0010 0000 0001 0000 0101 0000 0011
So as posted. Note I did find this was more then just a simple xor. and some bits change if more then one bit is set.
So I think we need some more sample data and happy for some ideas. I was thinking things like 010101.... and 101010 and/or all 1 for each nibble.
Offline
uid AND 0x00010303
Curious of this one
32 0000 0000 0000 0000 0000 0000 0010 0000 0000 0000 0000 0001 0010 0011 0010 0011
64 0000 0000 0000 0000 0000 0000 0100 0000 0000 0000 0000 0001 0100 0011 0100 0011
128 0000 0000 0000 0000 0000 0000 1000 0000 0000 0000 0000 0001 1000 0011 1000 0011
what pwd will be generated with uid of 224?
Offline
UID of 224 : 0000 0000 0000 0001 1110 0011 1110 0011
uid 0xFFFFFFFF : 1000 0110 1110 1111 0111 0101 1110 1111
Offline
Just a quick memorydump on blue/black and white cloners.
A bit rusty, but it should still be correct:
Intro
Chinese sell the same looking stuff in 4 quality grades. Grade A to D
Grade A is perfectly working, without any problems, the most expensive
Grade D is barely working or breaks down quickly, the cheapest
Hey they sell you what you want to pay and a litlle soldering skills can improve a grade D to a grade A....
Chinese (125kHz) cloners
Blue and black cloners
3 variants: 1) EM cloner; 2)HID cloner; 3)EM/HID cloner
Quality varies my manufacturer (Quality A (Good) until D (Bad))
They set a password on block 7 of the chip and set the password enable bit in block 0
Standard password is normally: 51243648
Be sure to purchase the EM/HID version
White cloner (pre 2015)
Multifrequency
Buttons light up BLUE
Reads data correctly
Standard password is normally (for T55xx): AA55BBBB
Standard password 13,56mHz: individual per white cloner
Coil performance acceptable
White cloner (2016-)
Multifrequency
Buttons light up WHITE
Data scrambled (variable per individual cloner, possibly due to prevent legal issues)
Standard password is normally (for T55xx): AA55BBBB
Standard password 13,56mHz: individual per white cloner
Coil performance good
White cloner (2016- D Quality)
Multifrequency (Well it says so....but it doesn't....)
Only works for EM/HID card (125kHz)
High frequency not working
Standard password is normally (for T55xx): AA55BBBB
Note: Sets the HID card in TEST MODE
Unless you want to do some lazy cloning. Stick to the Proxmark 3 or other projects
Fixing your broken-by-chinese-cheap-cloners-T55xx cards:
Restore the page 1 data:
If t55xx write b 1 d E0150A48 1
If t55xx write b 2 d 2D782308 1
P.S. always doublecheck that cloner doesn't set your card to test mode...
Be aware if you want to use the card with your proxmark
Offline
What do you mean by
"always doublecheck that cloner doesn't set your card to test mode."
I thought test mode was used to make some changes and undo some protection, but had no long term affect.
update:
I went over the data sheet for the T5577 again and the way i read it is.
If the config in block 0 page 0 has its "master" key set to 6 then the page 0 test function is disabled.
If the config in block 3 page 1 has its "master" key set to 6 then the page 1 test function is disabled.
So, by setting either of those to 6 you can still make changes as long as you dont need the test option, you can also re-write the config and remove the masterkey to re-enable it.
The real challenge kicks in if you start setting the lock bits. As the way i read it, if you set the lock bit on any block, it cant be undone via the rfid commands, so if you set the master key to 6 then set the lock bit, thats it, locked.
i.e. for page 1
quote for data sheet.
"...If Option Key is 6 then the complete page 1 (i.e., option register and traceability data) cannot be overwritten by any Test Write Command.
This means, if the Lock bits of the three blocks of page 1 are set and the Option Key is 6, then all of page 1’s blocks
are locked against change...."
It hints that you need to disable the test write commands AND set the lock bit to "lock against change"
What I have not tested yet (for example) is what happens if you set the lock bits on (say) page 1 block 1 and 2, but NOT 3 (page 1 config).
Can you then change block 3 to remove the masterkey as its not locked, then use the test mode to clear the lock bits on the other blocks.
I would need to setup the software to allow the lock bit to be set (its hard coded to NOT lock atm).
Of course, happy to hear from those that have tried it.
Last edited by mwalker (2019-06-19 12:03:44)
Offline
I have myself just recently discovered that some chinese cloners have this "extra feature" of setting their own passwords to the cards they are writing to.
My chinese cloner is the white one (so called "10 Frequency NFC RFID Card Copier..." - on the box it says "zonsin the invincible king" or something). The buttons light white (with a little bluish tint, though). I had used it to clone a few key fobs before, without being aware of this thing... until trying to reuse some of the cloned tags with the proxmark3 and finding out they can't be written, because apparently they were password protected!
At first I tried using the default dictionary and even some random bruteforce sessions, but with no success (as expected). So, the next step was to try and sniff the commands from the cloner. Thanks to the great info I found on this forum, I eventually managed to understand the process: setting the correct threshold (64 was good enough in my case), then sniffing the write command of the cloner (without the key fob), saving data as .wav and manually decoding using audacity.
So far I only had time to try writing two IDs (123456 and 123457 (decimal)) with the cloner and trying to find the password. What I did find was that the cloner was trying to set the password "00014343 (hex)" in the block 7, using a known password (44B44CAE).
I then verified that indeed, the "00014343" was the correct password! And it was the same, for both the IDs I had written (123456 and 123457).
At first I thought that this was a fixed password, specific to that chinese cloner and even wanted to suggest its inclusion in the default password dictionary, but then I encountered this post... and that the password is somehow dependent on the written ID?!
I have banged my head against a wall a bit, today, trying to see some possible relationship between the ID or blocks content and the password, but so far nothing. It intrigues me though, so I'm going to spend a little more time trying to figure it out.
There's one thing I still don't understand: if the tag is protected with a variable password, how does the cloner know which password that was?? Because from what I have seen, it doesn't even try to read the ID from the tag first. It just tries to write the new one using the "old" 44B44CAE password! Is it possible that the data I "sniffed" from the cloner was not complete? (I only got 5 groups of commands (writting block 1, writting to block 2, writting block 7, ... all using the OLD password), then the sniffing stopped) If so, is there a way to fit more data into the capture buffer? (by changing the averaging parameter or something else?)
Last edited by paleopterix (2020-09-14 20:55:02)
Offline
...update
I will answer myself to some of my noobish questions (Sorry!)
1) using "lf configure" and increasing "decimation" does the trick of allowing more bits to be captured...
2) I just captured the cloner commands for various other IDs... For instance, when the Id=32 (decimal), using decimation=8, I managed to capture a little more commands than previously. I found out that the cloner first tries to write blocks 1,2 and 7 using the known password 44B44CAE. Block 7 is written with the new password 00012323 (hex)
Then does exactly the same, but using the other fixed password, 88661858.
So far I'm just ..confirming/repeating what @mwalker said, so not very useful info, sorry.
After that, there are two commands (separated groups of bits) that I can't yet interpret:
10000000000000000010010001100100011111
and
10000000000000101001000000001010000000
followed then by the attempt to write the blocks 1 and 2 using the new password (00012323)
I will try tomorrow to capture even more commands (increasing decimation as much as possible). Anyway, most likely at some point, the cloner tries to read the ID from the tag - and probably if it is not OK, it will try to recalculate the password and will try to write again blocks 1,2 and 7 using it.
Last edited by paleopterix (2020-09-14 22:50:54)
Offline
10 0 00000000000000010010001100100011 111 <- write 00012323 to block 7 page 0, thus a password
and
10 0 00000000000101001000000001010000 000 <- write 00148050 to block 0 page 0, thus config.
Config looks to be Manchester/ASK RF/64 - EM4100 tag is my guess since its a common cloner and its a valid config for the EM4100 clone.
Not sure if you have the same or similar cloner to my white one, but it sets the password based on the original Tag ID.
Mine seems to be based on the EM4100 last 4 bytes. Its a little more then just a bit scramble.
I have mapped out all the single bit positions for mine.
Its always good to start with all the single bit IDs. e.g. 1,2,4,8,16 and so on. if its a bit scramble it should show up.
edit:
btw, decimation can work, but only up to a point. There is also the skip option so you get full detail.
e.g.
Sample first 40,000 samples.
Set to skip 30,000
Sample next 40,000 samples
Set to skip 60,000
Sample next 40,000 samples.
and so on. repeat until no more samples/modulated data.
Note: the cloner will most likely send out the commands for each of the card types it supports. Eg. T55xx, EM4305 ...
This should overlap the last 10,000 (25%) so a good amount to ensure enough detail.
Offline
@paleopterix
I had a bit of a look today and it seems that your ID v Passwords are the same as my white cloner.
"...There's one thing I still don't understand: if the tag is protected with a variable password, how does the cloner know which password that was?? Because from what I have seen, it doesn't even try to read the ID from the tag first. It just tries to write the new one using the "old" 44B44CAE password! Is it possible that the data I "sniffed" from the cloner was not complete? (I only got 5 groups of commands (writting block 1, writting to block 2, writting block 7, ... all using the OLD password), then the sniffing stopped) If so, is there a way to fit more data into the capture buffer? (by changing the averaging parameter or something else?) ..."
My white cloner (when no card present) will write for 3 different cards. My guess is the 2 original passwords were from a previous firmware, so it needed to know the old fixed ones. After it writes to the card, it will attempt to initiate a read (default read), which should return the new ID. IF that new ID matches the one its trying to program, then it will say success. e.g. I set a password that it did not know. Then wrote a different EM4100 ID, and it failed (could not update), then I wrote the same EM4100 ID to the card, still with a password it did not know, "success". So I am happy it wont try to do an old ID password write unless it gets a valid ID back that does not match.
While I have not tried, my guess will be that if the ID failed, then it would THEN use it to re-write with the generated "previous" password.
Happy to review an ideas you have on the password generation algo. I have some roughed in code to test. It works with all single bit passwords and some multi bit passwords I have been testing with, but not all IDs get the write password.
i.e. there are some bits that are change only when 2 bits are shown
Offline
@mwalker
Indeed, I looked at your single-bit IDs ->passwords table and verified randomly a couple of them (4 or 5) with my cloner and they all match... definitely it's the same one (at startup it shows "firmware V5.04.16.0727").
I've been trying to find a "visual" approach to find a possible algo like "something AND something else XOR something else shifted by who knows what...."
i.e. 0x010303 OR ( (id AND mask1) << 8) OR ( (id AND mask2) << 16) ....
Tried a few spreadsheet software like excel, origin, openoffice calc... in the end the best was libreoffice calc (because it had some basic bitwise operators implemented), in which I transposed your single-bit ID vs generated keys table and then tried different formulas. Some of them went pretty close but still failed at some particular inputs... But I hit the limitations of this tool when I tried to include a custom 32 bitwise rotation in the formula (instead of simple shifting) and found out it was impossible, because the VB scripting only works with signed 32 bit integers and complained when the MSB was overflowing...... And now I'm back where I started: looking for a better tool for the job. I might give a try to Matlab...
Anyway, even if I had found a particular formula this way is very likely it would work just for those single bit inputs....
I'll resume the "hunt" when I can, but it seems I need a better approach anyway.
Another idea would be to examine the main PCB of this cloner and see if there's any accessible flash memory that can be read, to get access to the firmware and then try to disassemble it somehow, but it's a long shot.
Last edited by paleopterix (2020-09-16 21:34:57)
Offline
@paleopterix
If you are using the RRG repo, I have added a command to help sniff and decode the T55xx commands sent.
new command : lf t55 sniff
It sits on top of the lf sniff, so set up as normal (s - samples to skip, t - trigger level etc) then in the lf t55 sniff just as you would the lf sniff
sample output.
[usb] pm3 --> lf t55 sniff
[#] LF Sampling config
[#] [q] divisor.............95 ( 125.00 kHz )
[#] [b] bits per sample.....8
[#] [d] decimation..........3
[#] [a] averaging...........Yes
[#] [t] trigger threshold...50
[#] [s] samples to skip.....0
[#] LF Sampling Stack
[#] Max stack usage.........4048 / 8480 bytes
[=] You can cancel this operation by pressing the pm3 button
[#] Done, saved 42232 out of -84465 seen samples at 8 bits/sample
[=] Reading 42231 bytes from device memory
[+] Data fetched
[=] Samples @ 8 bits/smpl, decimation 1:3
[=] T55xx write Detection
[=] Minimum signal level : 20
[+] Downlink mode | password | Data | blk | page | 0 | 1 | raw
[+] -----------------+----------+----------+-----+------+-----+-----+-------------------------------------------------------------------------------
[+] Default | 44B44CAE | FF80007A | 1 | 0 | 5 | 8 | 1001000100101101000100110010101110011111111100000000000000001111010001
[+] Default | 44B44CAE | BBB2EFC2 | 2 | 0 | 5 | 8 | 1001000100101101000100110010101110010111011101100101110111111000010010
[+] Default | 44B44CAE | 064FD5CF | 7 | 0 | 5 | 8 | 1001000100101101000100110010101110000000110010011111101010111001111111
[+] Default | 88661858 | BBB2EFC2 | 2 | 0 | 5 | 8 | 1010001000011001100001100001011000010111011101100101110111111000010010
[+] Default | 88661858 | 064FD5CF | 7 | 0 | 6 | 10 | 1010001000011001100001100001011000000000110010011111101010111001111111
[+] Default | | 00148050 | 0 | 0 | 5 | 8 | 10000000000000101001000000001010000000
[+] Default | 064FD5CF | FF80007A | 1 | 0 | 5 | 8 | 1000000110010011111101010111001111011111111100000000000000001111010001
[+] Default | 064FD5CF | BBB2EFC2 | 2 | 0 | 5 | 8 | 1000000110010011111101010111001111010111011101100101110111111000010010
[+] Default | | BBB2EFC2 | 2 | 0 | 6 | 10 | 10010111011101100101110111111000010010
[+] ------------------------------------------------------------------------------------------------------------------------------------------------
Offline
Hi,
That would be very useful, indeed!
Unfortunately, I can't seem to have it in my proxmark3 software. I just installed the latest rrg release (rrg_other-64-20200916-06dfa3c32de26ee5fa1862d16e9962d35b2a4dd2), but still can't see it. Maybe it's only for the "RDV4"?
This is what I have:
"[ Proxmark3 RFID instrument ]
[ CLIENT ]
client: RRG/Iceman/master/v4.9237-1114-g06dfa3c3 2020-09-16 21:17:02
compiled with MinGW-w64 10.2.0 OS:Windows (64b) ARCH:x86_64
[ PROXMARK3 ]
[ ARM ]
bootrom: RRG/Iceman/master/v4.9237-629-g3ae8dedd 2020-08-02 21:19:25
os: RRG/Iceman/master/v4.9237-1114-g06dfa3c3 2020-09-16 21:16:55
compiled with GCC 9.3.1 20200408 (release)
[ FPGA ]
LF image built for 2s30vq100 on 2020-07-08 at 23: 8: 7
HF image built for 2s30vq100 on 2020-07-08 at 23: 8:19
HF FeliCa image built for 2s30vq100 on 2020-07-08 at 23: 8:30
[ Hardware ]
--= uC: AT91SAM7S512 Rev B
--= Embedded Processor: ARM7TDMI
--= Nonvolatile Program Memory Size: 512K bytes, Used: 259672 bytes (50%) Free: 264616 bytes (50%)
--= Second Nonvolatile Program Memory Size: None
--= Internal SRAM Size: 64K bytes
--= Architecture Identifier: AT91SAM7Sxx Series
--= Nonvolatile Program Memory Type: Embedded Flash Memory"
"[usb] pm3 --> lf t55
----------- --------------------- operations ---------------------
help This help
clonehelp Shows the available clone commands
config Set/Get T55XX configuration (modulation, inverted, offset, rate)
dangerraw Sends raw bitstream. Dangerous, do not use!! b <bitstream> t <timing>
detect [1] Try detecting the tag modulation from reading the configuration block.
deviceconfig Set/Get T55XX device configuration (startgap, writegap, write0, write1, readgap
dump [password] [o] Dump T55xx card Page 0 block 0-7. Optional [password], [override]
info [1] Show T55x7 configuration data (page 0/ blk 0)
p1detect [1] Try detecting if this is a t55xx tag by reading page 1
read b <block> p [password] [o] [1] -- Read T55xx block data. Optional [p password], [override], [page1]
resetread Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)
restore f <filename> [p <password>] Restore T55xx card Page 0 / Page 1 blocks
trace [1] Show T55x7 traceability data (page 1/ blk 0-1)
wakeup Send AOR wakeup command
write b <block> d <data> p [password] [1] -- Write T55xx block data. Optional [p password], [page1]
----------- --------------------- recovery ---------------------
bruteforce <start password> <end password> Simple bruteforce attack to find password
chk Check passwords from dictionary/flash
protect Password protect tag
recoverpw [password] Try to recover from bad password write from a cloner. Only use on PW protected chips!
special Show block changes with 64 different offsets
wipe [q] Wipe a T55xx tag and set defaults (will destroy any data on tag)
[usb] pm3 -->"
Last edited by paleopterix (2020-09-17 08:06:00)
Offline
It should be fine for non-rdv4 as its all client side.
It was only updated today - so double check for some new updates.
Note: its live on the github version if you download and compile yourself.
Precompiled will be a little behind.
Offline
Hi,
Today I tried again to find some "magic" formula for the password... and I found something that seems to satisfy at least all the one-bit IDs. I'm pretty sure that's NOT the final formula (it doesn't look pretty and doesn't make too much sense either), but who knows, it may be close. Here it is:
0x10303 OR ( (id AND 0x86ee00ef) XOR LSHIFT( id AND 0x000000ef, 8) ) + LROTATE( id AND 0x86000000, 16)
where 0x10303 is the password for ID="000...000", LSHIFT = left shift (obviously), LROTATE = left rotation on 32 bits, etc
PASS = 0x10303 + (id & mask1) + rolInt32(id & mask2,8) + rolInt32(id & mask3, 16) + rolInt32(id & mask4, 24)
or
PASS = 0x10303 + (id & mask1) ^ rolInt32(id & mask2,8) ^ rolInt32(id & mask3, 16) ^ rolInt32(id & mask4, 24)
(rolInt32 - left rotation on 32 bits)
ex.
PASS = 0x10303 + ( (id&86ee00ec) ^ rolInt32(id&000000ec,8) ^ rolInt32(id&86000000, 16) ^ rolInt32(id&00000000, 24));
(Update1: formula "version 2": better than the first one (actually it makes a bit of sense now), but still incomplete, to say the least; I already found some IDs (like '9876453') that do not lead to the expected password, although the difference is just in one or two shifted bits....; maybe the masks are not yet correct or another terms have to be added to the formula )
Update2: I think this might be it!!!! It works for all one-bit passwords and also it worked for a few dozen random IDs that I have tested!
PASS = 0x10303 + ( (ID & 0x86ee00ec) ^ rolInt32(ID & 0x000000ec, 8) ^ rolInt32(ID & 0x86000000, 16) )
(^ = bitwise XOR, rolInt32(a,b) = left rotation of "a" with "b" positions (32 bits), ID = the ID to be written on the tag, PASS = calculated block 7 password)
Also, here is a little HTML file that I have written to simulate and print the results, using javascript:
<html>
<head>
<style>
.tooltip {
color: #000000;
cursor: help;
position: relative;
}
.tooltip span {
margin-left: -999em;
position: absolute;
}
.tooltip:hover span {
font-family:"Courier New", Courier, monospace;
font-size:36px;
font-weight: bold;
position: absolute;
left: 5em;
top: -1em;
z-index: 99;
margin-left: 0;
}
.classic { padding: 0em 0em; background: #FFFFAA; border: 1px solid #FFAD33; text-align: center;}
table
{
border-spacing: 0px;
border-collapse: separate;
}
table td
{
border: 1px solid #004030;
}
input
{
background-color:#ffff99;
border: 1px solid #004030;
}
</style>
<body>
Input ID:<input id="newid" type="textbox" style="width:200px;" onchange='calcpwd();'> Calculated Passwd:<input id="calcpw" type="textbox" readonly style="width:200px;">/<input id="calcpwhex" type="textbox" readonly style="width:200px;">
<div id="dvInfo1" name="dvInfo1" style="width:100%; height:30px; border:1px solid; background-color:#bfffbf;overflow-x: auto;overflow-y: auto;"></div>
<div id="dvTable1" name="dvTable1" style="width:100%; min-height:1200px; border:1px solid; background-color:#dddddd;overflow-x: auto;overflow-y: auto;"></div>
<script type="text/javascript">
const MAX_BIT_WIDTH = 32;
const MIN_BIT_WIDTH = 0;
const bitwiseRotation = bitWidth => {
if (typeof bitWidth !== 'number') {
throw new Error('Bit width must be a number');
}
if (bitWidth > MAX_BIT_WIDTH) {
throw new Error(`Bit width too large; must be less than ${MAX_BIT_WIDTH}.`);
}
if (bitWidth < MIN_BIT_WIDTH) {
throw new Error(`Bit width too small; must be greater than ${MIN_BIT_WIDTH}.`);
}
const bitMask = (2 ** bitWidth) - 1;
const maskedRotation = (rotation) => rotation & (bitWidth - 1);
return {
ror: (value, r) => {
const rotation = maskedRotation(r);
return (
(value >>> rotation) |
((value << (bitWidth - rotation)) & bitMask)
);
},
rol: (value, r) => {
const rotation = maskedRotation(r);
return (
((value << rotation) & bitMask) |
(value >>> (bitWidth - rotation))
);
},
};
};
const { ror: rorInt8, rol: rolInt8 } = bitwiseRotation(MAX_BIT_WIDTH / 4);
const { ror: rorInt16, rol: rolInt16 } = bitwiseRotation(MAX_BIT_WIDTH / 2);
const { ror: rorInt32, rol: rolInt32 } = bitwiseRotation(MAX_BIT_WIDTH);
/////////////////////////////////////////////////////////////////////
</script>
<script type="text/javascript">
//////////////////////////////////////////////
function calcpwd(evt)
{
document.getElementById("calcpw").value = Calc(parseInt(document.getElementById("newid").value));
document.getElementById("calcpwhex").value = decToHex(Calc(parseInt(document.getElementById("newid").value)),0);
}
//////////////////////////////////////////////
function toBinary(integer, withPaddingLength) {
let str = integer.toString(2);
return str.padStart(withPaddingLength, "0");
}
/////////////////////////////////////////////
function decToHex(d, padding)
{
var hex = Number(d).toString(16);
padding = typeof (padding) === "undefined" || padding === null ? padding = 2 : padding;
while (hex.length < padding)
{
hex = "0" + hex;
}
return hex;
}
////////////////////////////////////////////
function Calc(number)
{
return Calc2(number);
}
///////////////////////
function Calc2(number)
{
var val, str, mask1, mask2, mask3, mask4;
mask1 = 0b10000110111011100000000011101100;
mask2 = 0b00000000000000000000000011101100;
mask3 = 0b10000110000000000000000000000000;
mask4 = 0b00000000000000000000000000000000;
val = 0x10303 + ( (number&mask1) ^ rolInt32(number&mask2,8) ^ rolInt32(number&mask3, 16) ^ rolInt32(number&mask4, 24));
val = val >>> 0;
//print a more readable formula
str = "0x10303 + ( (id&"+decToHex(mask1,8)+") ^ rolInt32(id&"+decToHex(mask2,8)+",8) ^ rolInt32(id&"+decToHex(mask3,8)+", 16) ^ rolInt32(id&"+decToHex(mask4,8)+", 24));";
document.getElementById("dvInfo1").innerHTML = str;
return val;
}
/////////////////////
function Test()
{
var cellsInRow = 1;
var div1 = document.getElementById('dvTable1');
// creates a <table> element
var row, cell, tbl = document.createElement("table");
var val, str, title;
var target_pw = [66307,66307,66307,67335,68363,66307,74531,82755,99203,66307,66307,66307,66307,66307,66307,66307,66307,66307,197379,328451,590595,66307,2163459,4260611,8454915,66307,33621251,67176195,66307,66307,66307,66307,2147582723, 8906727, 99203,82755,82755];
var id_list = [0,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,2147483648, 9876453, 47251, 123456,123457];
// creating rows
///header
row = document.createElement("tr");
//crt
cell = document.createElement("td");
cell.style.width = '50px';
cell.innerHTML = "Cnt";
row.appendChild(cell);
//ID
cell = document.createElement("td");
cell.style.width = '150px';
cell.innerHTML = "ID";
row.appendChild(cell);
//Target PSW
cell = document.createElement("td");
cell.style.width = '150px';
cell.innerHTML = "Target";
row.appendChild(cell);
//Calc. PSW
cell = document.createElement("td");
cell.style.width = '120px';
cell.innerHTML = "Calc";
row.appendChild(cell);
//Diff
cell = document.createElement("td");
cell.style.width = '150px';
cell.innerHTML = "Target - Calc";
row.appendChild(cell);
tbl.appendChild(row); // add the row to the end of the table body
//for (var b = 0; b < 33; b++)
var b = 0;
for (const id of id_list)
{
b++;
val = Calc(id);
row = document.createElement("tr");
/*if (b==0)
id = 0;
else
id = 1 << (b-1) >>> 0; */
//crt
cell = document.createElement("td");
cell.innerHTML = b-1;
row.appendChild(cell);
//ID
cell = document.createElement("td");
cell.innerHTML = id;
row.appendChild(cell);
//Target PW
cell = document.createElement("td");
cell.innerHTML = target_pw[b-1];
row.appendChild(cell);
//Calculated PW
cell = document.createElement("td");
cell.innerHTML = val;
row.appendChild(cell);
//Diff
cell = document.createElement("td");
title = " 01234567012345670123456701234567\n\nP0 "+toBinary(66307,32)+"\nID "+toBinary(id,32) + "\n \nTP " + toBinary(target_pw[b-1],32)+"\nCP "+toBinary(val,32);
str = (val-target_pw[b-1]).toString()+"<span class='classic'>"+title+"</span>";
cell.innerHTML = str;
//cell.setAttribute("title", title);
cell.style="cursor:pointer;";
cell.setAttribute("style","cursor:pointer;background-color:#7EDFA3");
cell.setAttribute("class","tooltip");
row.appendChild(cell);
tbl.appendChild(row); // add the row to the end of the table body
}
div1.appendChild(tbl); // appends <table> into <div1>
}
Test();
</script>
</body>
</html>
Last edited by paleopterix (2020-09-18 22:51:24)
Offline
By the way, the new "lf t55 sniff" command is awesome!!! Thank you!
Offline
Hehe yeah, it speeds things up.
I started with my own app to take the .pm3 file and extract then i ported that to the pm3 (rrg).
Its a bit of a work in progress, as to cover everything is a big job, so I am adding things as needed.
(e.g. I got sent some pm3 files that did not decode. workout out why not, and have re-writing the code (not pushed yet)
Back to the issue at hand.
I had a play with what I think your idea was. But rather then add i used xor. then I got side tracked with some other things.
As a rule of thumb, I kinda think if its too complex its not right. I then brute forced the mask. Never really got much better.
are you on the pm3 discord ?
http://www.proxmark.org/forum/viewtopic.php?id=8000
If you are, lets tee up a session to see if we can find something.
edit, just noticed the update... Will have a look now
edit 2: Looking good 44/44 for me - Passed my initial test set
Are you happy for it to be added to the rrg repo and have your user ID as credit ?
Memo7
00000001 | 00010303 = 00010303 - Match
00000002 | 00010303 = 00010303 - Match
00000004 | 00010707 = 00010707 - Match
00000008 | 00010B0B = 00010B0B - Match
00000010 | 00010303 = 00010303 - Match
00000020 | 00012323 = 00012323 - Match
00000040 | 00014343 = 00014343 - Match
00000080 | 00018383 = 00018383 - Match
00000100 | 00010303 = 00010303 - Match
00000200 | 00010303 = 00010303 - Match
00000400 | 00010303 = 00010303 - Match
00000800 | 00010303 = 00010303 - Match
00001000 | 00010303 = 00010303 - Match
00002000 | 00010303 = 00010303 - Match
00004000 | 00010303 = 00010303 - Match
00008000 | 00010303 = 00010303 - Match
00010000 | 00010303 = 00010303 - Match
00020000 | 00030303 = 00030303 - Match
00040000 | 00050303 = 00050303 - Match
00080000 | 00090303 = 00090303 - Match
00100000 | 00010303 = 00010303 - Match
00200000 | 00210303 = 00210303 - Match
00400000 | 00410303 = 00410303 - Match
00800000 | 00810303 = 00810303 - Match
01000000 | 00010303 = 00010303 - Match
02000000 | 02010503 = 02010503 - Match
04000000 | 04010703 = 04010703 - Match
08000000 | 00010303 = 00010303 - Match
10000000 | 00010303 = 00010303 - Match
20000000 | 00010303 = 00010303 - Match
40000000 | 00010303 = 00010303 - Match
80000000 | 80018303 = 80018303 - Match
FFFF0000 | 86EF8903 = 86EF8903 - Match
000000FF | 0001EFEF = 0001EFEF - Match
00000003 | 00010303 = 00010303 - Match
00000005 | 00010707 = 00010707 - Match
00000007 | 00010707 = 00010707 - Match
00000009 | 00010B0B = 00010B0B - Match
0000000A | 00010B0B = 00010B0B - Match
0000000B | 00010B0B = 00010B0B - Match
0000000C | 00010F0F = 00010F0F - Match
0000000D | 00010F0F = 00010F0F - Match
0000000E | 00010F0F = 00010F0F - Match
0000000F | 00010F0F = 00010F0F - Match
Offline
Awesome!
Offline
Brilliant!
Offline
Are you happy for it to be added to the rrg repo and have your user ID as credit ?
Of course, it would be an honor!
Offline
yup, already in the default pwd dictionary file.
Offline