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 just got around to try reading a Skylander toy.
It doesn't want to be identified but uses a default key. Doesn't want to let me read it.
Some ideas?
pm3 --> hf 14a read
ATQA : 01 0f
UID : 06 5d 4f c4
SAK : 01 [2]
proprietary non iso14443a-4 card found, RATS not supported
Found valid key:[000000000000]
--sector: 1, block: 7, key type:B, key count:13
Found valid key:[000000000000]
--sector: 2, block: 11, key type:B, key count:13
Found valid key:[000000000000]
--sector: 3, block: 15, key type:B, key count:13
Found valid key:[000000000000]
--sector: 4, block: 19, key type:B, key count:13
Found valid key:[000000000000]
--sector: 5, block: 23, key type:B, key count:13
Found valid key:[000000000000]
--sector: 6, block: 27, key type:B, key count:13
Found valid key:[000000000000]
--sector: 7, block: 31, key type:B, key count:13
Found valid key:[000000000000]
--sector: 8, block: 35, key type:B, key count:13
Found valid key:[000000000000]
--sector: 9, block: 39, key type:B, key count:13
Found valid key:[000000000000]
--sector:10, block: 43, key type:B, key count:13
Found valid key:[000000000000]
--sector:11, block: 47, key type:B, key count:13
Found valid key:[000000000000]
--sector:12, block: 51, key type:B, key count:13
Found valid key:[000000000000]
--sector:13, block: 55, key type:B, key count:13
Found valid key:[000000000000]
--sector:14, block: 59, key type:B, key count:13
Found valid key:[000000000000]
--sector:15, block: 63, key type:B, key count:13
Found valid key:[000000000000]
pm3 --> hf mf rdsc 0 b 000000000000
--sector no:0 key type:B key:00 00 00 00 00 00
#db# Cmd Error: 04
#db# Read sector 0 block 0 error
#db# READ SECTOR FINISHED
isOk:00
Last edited by iceman (2015-05-25 10:22:43)
Offline
And I should have searched the forum first..
Offline
Just pushed a little lua script that reads tnp3xxx tags in my fork.
If you gonna use it in the master/v1.1.0 then take notice to the md5.lua and changes in scripting.c
The script may need some testing, to see if it works correct.
Last edited by iceman (2014-11-03 22:02:04)
Offline
And there is a beginning for a identification list used with the script. If someone wants to add/correct it you are welcome.
Offline
The tnp3.lua script now correctly dumps and decrypts the data.
It also can verify the checksums.
If I add some more stuff, you can enhance this game-item as you wish.
Offline
Great work man ! So the decrypted data are "correct" (readable) ?
Offline
Yes, the dump is now decrypted correct and can calculate all 4 checksums, hence all data can be modified and encrypted again..
You might even simulate any toyitem with a dump or magic uid card
Offline
or I just add the possibility to load the emulator memory from within the script...
Then I only need to issue a "hf mf sim" .. maybe that from within the script aswell...
Offline
There is 2 scripts now,
tnp3dump - dump contents of a tnp3
tnp3sim - load a dump, sends it to the device memory of the pm3, where the "hf mf sim" should be able to simulate a tnp3
it needs to be tested against a correct reader, which I can't do.
Offline
Really cool! The neighbour kids have them, I'll see if I can borrow one and test. Why is it called tnp- , instead of "skylander-dump" and "skylander-sim" ?
Offline
well, we perhaps don't want too much attention??
Offline
and tnp3 is the chip used...
Offline
Holiman, I really hope you can borrow one and test. What I lack is proper testing right now. The dump works, but sim is experimental.
Offline
iceman, I have been working on this one a few days now, I have dumped a few characters and simulated them through normal proxmark simulator (did not test it on the portal yet). But I could try to test your code. Do not know when I have time, but will keep you posted.
Offline
that would be great,
Offline
So, after some troubles getting your fork to build on win64 I tested stuff out.
- So, I was just raw dumping MF (with NEST attack) and that is the same as your script but your script makes life so much easier
- The simulator is not working... well, it does the same as I already tried, just load the eml into memory, set uid, and see. I think there is something wrong with my antenna because when reading the proxmark (simulated) from another reader it can not get further then one block. I am using DIY antenna
FYI, I do not think <company> will be happy that you put both important and "secret" keys in your script, there was this other guy who got sued hard over the AES key.
On another node, I am trying to get a dump of the portal chip, but I am lacking materials and experience.... but should be doable. Would love to figure out key derivation algorithm!
Offline
I suspected that a simulation needs to identify itself with correct ataq & sak, which is not the case with the "hf mf sim" command.
The portal is a reader/writer , it can't be dumped with a pm3. However I strongly doubt there is something interesting inside it. If you are interested in the communications, you should look into the softwaredriver.
When it comes to the key derivation algo, someone on the forum found a piece of the puzzle but the picture is not clear. There are more luascripts around.
Offline
Pushed a option to simulate tnp3xxx tag in the "hf mf sim" command. usage: "hf mf sim 5 aabbccdd".
See if you can try that one, Noclafasm ?
Offline
I suspected that a simulation needs to identify itself with correct ataq & sak, which is not the case with the "hf mf sim" command.
The portal is a reader/writer , it can't be dumped with a pm3. However I strongly doubt there is something interesting inside it. If you are interested in the communications, you should look into the softwaredriver.
When it comes to the key derivation algo, someone on the forum found a piece of the puzzle but the picture is not clear. There are more luascripts around.
I know, I have a couple of portals already opened. The use the PIC18F14K50 chip with an ISCP port available and there is a way to dump the memory (http://www.openicsp.org/). Or you could try to reset the protection bits with UV light (another research). I had contact with a guy who knew another guy who reversed the key derivation algorithm without dumping the chip so at the moment I am trying to figure out what bits/bytes from sector zero are used for the key derivation.
Do you have those scripts/links? If so I am very interested.
Yes, will try when I have time.
P.S. It is currently impossible to get the "hf 14a list" through lua right? When using the GET_SAMPLES_ADC something through lua it crashes. The snooper.exe is broken (for quite some time), I made a new snooper.exe which works somewhat but it would be nice to be able to have an "endless" snoop.
Offline
A chip dump will surely be very good and useful ! Anyway the pic "exploit" was succesfully performed (also by some members of this forum) to read HID keys.
Last edited by asper (2014-11-26 19:37:23)
Offline
So experiment one:
- Rewritable sector 1 card
- Small program to change bytes in sector one and auto fixing the LRC (UID checksum) and first block checksum (CRC16-CCITT(0xFFFF) over 0:30)
Changed one byte from 0 to 32 and fixing LRC, CRC: Always fails but does show correct type (skeleton, tree, etc)
Changed one byte from 0 to 32 and fixing LRC, leaving CRC: Always fails
Changed one byte at 33: Works like a charm
So from this you could say, well the whole 32 bytes are used for key derivation.
I started looking at the keys and see if we could find some simple bitwise operation or arithmetic operation together with the CRC, all fails
I had two the same characters (which of course have quite some different bytes in sector 0) and the key derivation shows a pattern. Namely, of the 48 bits, 28 are the same between the Nth key of the two characters. The pattern my characters share is, where S is SAME, D is DIFFERENT
S DD S DDDDD S D SS DDDDDD S D SS DD SSSSS D SSS D SSSSSSSSSSS D S
MASTER = 0 10 0 10110 0 0 01 011001 0 0 00 00 00100 0 001 1 11100110010 1 1
#00 C1 = 0 00 0 01000 1 0 00 100011 1 1 01 11 10101 1 010 0 01001010111 1 0
#00 C2 = 0 11 0 10111 1 1 00 010100 1 0 01 00 10101 0 010 1 01001010111 0 0
#01 C1 = 0 01 0 00100 0 1 01 001101 0 1 11 11 00001 0 101 0 11110100111 0 1
#01 C2 = 0 10 0 11011 0 0 01 111010 0 0 11 00 00001 1 101 1 11110100111 1 1
#02 C1 = 1 01 1 00010 0 0 11 111010 0 0 10 10 01011 0 010 1 10101011111 0 0
#02 C2 = 1 10 1 11101 0 1 11 001101 0 1 10 01 01011 1 010 0 10101011111 1 0
#03 C1 = 1 11 1 11011 1 0 00 101111 0 1 10 11 00010 1 100 0 11011111110 1 1
#03 C2 = 1 00 1 00100 1 1 00 011000 0 0 10 00 00010 0 100 1 11011111110 0 1
#04 C1 = 0 11 0 11101 1 1 10 011000 0 0 11 10 01000 1 011 1 10000000110 1 0
#04 C2 = 0 00 0 00010 1 0 10 101111 0 1 11 01 01000 0 011 0 10000000110 0 0
#05 C1 = 0 10 0 10001 0 0 11 110110 1 0 01 10 11100 0 100 1 00111110110 0 1
#05 C2 = 0 01 0 01110 0 1 11 000001 1 1 01 01 11100 1 100 0 00111110110 1 1
Each two similar characters appears to have a pattern
D S DD SSSS D S DDDD S DD SS D S DD SSSS D S D SS DDD SS DDD SSS DD S D S
#00 T1 = 0 0 00 0101 1 0 0100 0 10 11 0 0 00 0110 0 0 0 00 111 00 100 010 11 1 0 0
#00 T2 = 1 0 11 0101 0 0 1011 0 01 11 1 0 11 0110 1 0 1 00 000 00 011 010 00 1 1 0
#01 T1 = 0 0 10 0011 1 1 1111 0 01 01 1 0 10 0100 1 0 0 11 001 10 011 100 11 1 1 1
#02 T2 = 1 0 01 0011 0 1 0000 0 10 01 0 0 01 0100 0 0 1 11 110 10 100 100 00 1 0 1
Offline
Given how the decrypting key looks like, it is most likely that it uses the same constants somehow in the keyA/B generation.
Asper and I found 2 values based on the keyA/Bs.. We didn't come further with than that.
You said Sector 1 (S1)
If you gonna change S1 values, you need first to decrypt them, then change them, then encrypt them again.
If you meant Sector 0 (S0) then you change the decrypting key for the rest of the data. just so you understand,which you need to "decrypt old key, change S0, encrypt new key"..
Offline
I indeed meant sector 0 (manufacture data). Shit, I indeed forget about the whole fixing of the AES encryption. O well, this is somewhat good news. I will add the encryption/decryption and other checksum fixing so I can experiment more. Will keep you guys posted.
Offline
I just realised one of my many changes actually broke some functionality.. So, latest push should have solved it.
Offline
I haven't dived too much into this, but I wanted to test some ideas I have had regarding interpreting data patterns. I tested the dump data above with "parity streams" (don't know if it's an existing concept, probably is, don't know).
The idea: In order to find parity bits, you can for a given input generate the parity at that point. That is the parity stream. If you line up all parity streams, the columns that contain the same digit across the column is (potentially) a parity bit.
Here's a way to generate it on my javascript playground http://martin.swende.se/tools/inject_it.js/
function parity(stream){
outp ="";
par = 0;
for(var i =0 ; i < stream.length; i++){
ch = stream[i];
num = parseInt(ch);
if(isNaN(num)) { outp += ch; continue}
if (num > 0){ par = !par}
outp += par ? "1" : "0"
}
return outp;
}
function bitno(stream){
outp ="Bit numbers\r\n";
bitnum=0;
par = 0;
for(var i =0 ; i < stream.length; i++){
ch = stream[i];
num = parseInt(ch);
if(isNaN(num)) { outp += ch; continue}
outp += bitnum++ % 10;
}
return outp;
}
function parity_guess(par_streams){
var outp="";
for(var i =0 ; i < par_streams[0].length; i++)
{
var isok = true;
var ch = par_streams[0][i];
if(isNaN(parseInt(ch))) { outp += ch; continue}
for(var j = 0; j < par_streams.length; j++)
if(par_streams[j][i] != ch) isok = false;
if (isok) outp += "^";
else outp +=" ";
}
return outp;
}
function pstreams(arr){
var outp = [];
for(var i =0 ; i < arr.length ; i++)
{
var stream = arr[i];
outp.push(parity(stream));
}
outp.push(parity_guess(outp))
return outp;
}
x = [
"0 00 0 01000 1 0 00 100011 1 1 01 11 10101 1 010 0 01001010111 1 0",
"0 11 0 10111 1 1 00 010100 1 0 01 00 10101 0 010 1 01001010111 0 0",
"0 01 0 00100 0 1 01 001101 0 1 11 11 00001 0 101 0 11110100111 0 1",
"0 10 0 11011 0 0 01 111010 0 0 11 00 00001 1 101 1 11110100111 1 1",
"1 01 1 00010 0 0 11 111010 0 0 10 10 01011 0 010 1 10101011111 0 0",
"1 10 1 11101 0 1 11 001101 0 1 10 01 01011 1 010 0 10101011111 1 0",
"1 11 1 11011 1 0 00 101111 0 1 10 11 00010 1 100 0 11011111110 1 1",
"1 00 1 00100 1 1 00 011000 0 0 10 00 00010 0 100 1 11011111110 0 1",
"0 11 0 11101 1 1 10 011000 0 0 11 10 01000 1 011 1 10000000110 1 0",
"0 00 0 00010 1 0 10 101111 0 1 11 01 01000 0 011 0 10000000110 0 0",
"0 10 0 10001 0 0 11 110110 1 0 01 10 11100 0 100 1 00111110110 0 1",
"0 01 0 01110 0 1 11 000001 1 1 01 01 11100 1 100 0 00111110110 1 1"]
show(bitno(x[0]));
show("S DD S DDDDD S D SS DDDDDD S D SS DD SSSSS D SSS D SSSSSSSSSSS D S");
var parity_streams = pstreams(x)
show("Parity streams:\r\n"+parity_streams.join("\r\n"));
If you want to play with it, just paste it into the left pane (replace the text there).
And here's the result:
Parity streams:
0 00 0 01111 0 0 00 111101 0 1 10 10 11001 0 011 1 10001100101 0 0
0 10 0 11010 1 0 00 011000 1 1 10 00 11001 1 100 1 10001100101 1 1
0 01 1 11000 0 1 10 001001 1 0 10 10 00001 1 001 1 01011000101 1 0
0 11 1 01101 1 1 10 101100 0 0 10 00 00001 0 110 1 01011000101 0 1
1 10 1 11100 0 0 10 101100 0 0 11 00 01101 1 100 1 00110010101 1 1
1 00 1 01001 1 0 10 001001 1 0 11 10 01101 0 011 1 00110010101 0 0
1 01 0 10010 1 1 11 001010 0 1 00 10 00011 0 111 1 01101010100 1 0
1 11 0 00111 0 1 11 101111 1 1 00 00 00011 1 000 1 01101010100 0 1
0 10 0 10110 1 0 11 101111 1 1 01 00 01111 0 010 1 00000000100 1 1
0 00 0 00011 0 0 11 001010 0 1 01 10 01111 1 101 1 00000000100 0 0
0 11 1 00001 1 1 01 011011 0 0 01 00 10111 1 000 1 11010100100 0 1
0 01 1 10100 0 1 01 111110 1 0 01 10 10111 0 111 1 11010100100 1 0
^ ^ ^ ^ ^^^
So, possibly, bits 15, 24, 29, 34 and 42 are parity bits (probably not 43 and 44, false positives are more likely directly after a parity bit)
Does it make sense?
Offline
makes sense! Nice concept! But I think it is not as hard as we think it is. The key is probably dependent on a very small portion in the first section because skylanders was able to read the character type but then stopped (sounds like data decryption problem more so then mifare key problem).
I ordered all hardware parts I need from ebay so in a few months I will post back if I was able to dump the firmware, haha!
Offline
after adding some bins from me, it narrows down to bits 34 and 43...
Offline
Well, the character type is written in S0-B1 (byte 00-01) , It can read the type wether or not being able to read the card-data on B8 and forward.
If it can't read the data, since you changed the key for decrypting it follows naturally. Which data needed to generate the keyA/B is different, I suspect that its in the driver.sys for the portal if someone likes to poke around in those files.
Offline
Hi, though I don't own a PM3, I would like to help check things out.
But first of all, I need to get raw data access. My current setup is kali-linux w/ SCL3711 reader. Using mfoc wasn't successful due to ATQA: 0F 01 issue.
I read even fixing ATQ restriction in mfoc won't ehlp. Any hints?
Offline
it is a standard mifare 1k s50 card inside, so you should be able to read the data quite simple.
mfoc/mfuc and no PM3 makes your post a bit of track. You should be able to read the card without concern of ATQA but then I don't know that about the inner workings of the mfoc software. If you download the sourcecode you should be able to add the 0x0F 0x01 to the identification function without any problems.
Offline
hmm, I modified mfoc to ignore ATQA and I was able to decode one of the Gi_an_ts characters (quite fast), but now it takes quite long for a T_rap TE_am char. Maybe due to some brute force protection (I read something similar). Pity.
Thnx anyway.
Offline
I haven't tested to read a t_ra_p_te_am char. But I did notice that some char's was not responding to the a nested attack at all.
Offline
ok, non vulnerability to nested attack vector seems to be obvious for these chars. I'll made some additional checks w/ different setups.
This point in post of Greg made me nervous:
2) It seems that a "feature" of Mifare/etc. is that after an incorrect auth attempt all further auth attempts (even with the correct key) will fail until the entire "card transaction" is reset (e.g. new call to PN532 with InListPassiveTarget)
http://www.proxmark.org/forum/viewtopic.php?id=1818
Offline
ok, failed to recover A key of t_ra_p_te_am char. prng seems to be fixed (though I will take a second look at mfcuk implementation regarding Gregs comment.
Is it possible to sniff A keys w/ PM3 while using legacy reader and char?
Offline
Yes, you can snoop communication data and try to recover at least 1 key.
Offline
I'd like to use the usb portals as readers for regular non-figure NFC tags. Even just a tag UID would be great. Anyone know whether this might be feasible?
I poked around with the figure editor that uses the portal. The portal responds with a status change with a regular MiFare classic tag, but I can't get data from it using that code. I don't need the MiFare chips to fool the game into thinking they are figures, just enough to get the portal to read anything from them. So what it is about the proper figure tags that the portal is looking at and could be possible to reproduce this? If it's the UID, ATQA, SAK then I'm out of luck. If it's a key then or something else than maybe it would work? I wouldn't mind tearing the portals apart if I could to access the chip (PIC18F14K50 as reported here) directly either.
Apologies for going a bit off topic for this thread, but after looking pretty much everywhere, this seems to be one of the few places where someone might know the answer.
Offline
I suppose you to build your own software to talk to the usb-driver. And then your "own" tag need to mimic the data of toy-tag the sector 0 and ATAQ == 0F 01, SAK == 01. I am not sure, but I think the whole read/write access is coded in the driver software.
Offline
Well if I need sector 0 writable tags, for the project I'm working on, it would basically defeat the point of having a ton of cheap durable readers with a cool controllable LED.
Considering just getting a box of random used 1st gen figures and cannibalizing the tags -- they only seem to be about twice as expensive as buying NFC stickers anyway. And I should still be able to get the UID of a Skylander with a standard reader.
Offline
either that or you re-write the provided usb-driver... If you just want it to read the uid, it might work. I thought you want to use it like a normal reader (read/write data)..
Offline
That's an interesting idea. You are just speculating those restrictions are in the driver and not just the portal hardware, right, that's not confirmed by anyone?
Offline
The mifare accesskeys A/B generation algo or keyhandling wasn't found inside the portal dll like other interesting stuff. This level of communication was handed of to the usb-driver. So it's not a pure speculation. It's a feeling but most likely true, that all key A/B dealing is in the driver....
Offline
Interesting. USB drivers are way outside my skillset, but maybe worth looking into later. Maybe just flip the right bit and it passes along reads for any MiFare.
Offline
Could be. But then go ahead and decompile the usb-driver. If you find something interesting please do tell me about it.
Offline
After a very good chat with someone on the forum last night, we have a bigger understand in the keygen-algo.
To put it short, only UID is used. There is several steps, where it seems only one is left to be understood. A permutation problem.
This is great news! Thank you, 0! for sharing your findings. Asper is on it and he is really enthusiastic
Offline
I also tried to sniff and sim using my scripts / built-in and they need some changes.
I was confused by:
"hf 14a sim" / "hf 14a snoop" //working good
vs
"hf mf sim" / "hf mf sniff" // not working
Offline
An evening of testing..
I did some more testing this evening and the results was promising but not successful.
HF MF SIM / HF MF SNIFF (snoop?) is not working at all. I can't set the ataq / sak and the detection is bad. There is an old issue on github on the subject.
HF 14A SIM - works lika a charm. The wii recoqnise the PM3 as a tag and starts loading... and then the trace is full and it all quits.
HF 14A SNIFF - works like a charm. Sniffs the traffic between portal and tag without a problem for 1-2 sec then the trace is full and it all quits.
To conclude, the PM3 will be able to simulate a tag either the "14a" commands gets an option to not trace so it can pretend to be tag forever. (or until the button is pressed)
OR the "HF MF SIM/SNIFF" commands gets a makeover and becomes stable. The code on ARM for these "HF MF SIM/SNIFF" is much better at memory allocation because they are sending back data from device to client all the time. The trace will not be filled.
Good but still no disco
Offline
actually, you don't have to "not trace", just don't quit at trace full.
Offline
And it'd be great if hf mf sim /snoop got some love
Offline
Hm, I'm getting "trace full. simulation stopped" .. Which in the iso14443a.c relates to this. And breaks...
if (!tracing) {
Dbprintf("Trace Full. Simulation stopped.");
break;
}
Offline
The code on ARM for these "HF MF SIM/SNIFF" is much better at memory allocation because they are sending back data from device to client all the time. The trace will not be filled.
Well, this is only a convenience function. After 2 seconds of inactivity, it sends data to the host and starts over. Should anything be received during this transfer, it will be lost.
Currently there is no way for a constant data transfer to the host - the USB transfer speed is no match even for the slowest (Standard) 106kBit/s card speed which is delivered by the FPGA to the ARM at 106kByte/s.
I think that hf mf sim and hf 14a sim were intended to trace reader commands rather than to really simulate a card. But I agree that the simulation needs not necessarily to stop when the trace buffer is full.
I am working on the BigBuf Memory allocation and my next change will allow much longer traces.
Offline