iceman1001 / proxmark3

[Deprecated] Iceman Fork, the most totally wicked fork around if you are into proxmark3
http://www.icedev.se/pm3.aspx
GNU General Public License v2.0
465 stars 116 forks source link

Mifare classic - NACK bug detection #141

Closed iceman1001 closed 6 years ago

iceman1001 commented 6 years ago

This would be a nice addition to have. Question is how to make one? @doegox @pwpiwi ?

The parity bug (nack bug) is triggered when the command bytes are wrong but the parity bits are correct for a genuine command?

8 bits parity, So loop 256 times to change possible parity bits, and if anyone triggers a NACK response from tag, we have a winner.

iceman1001 commented 6 years ago

Some response I got:

Of course spotting cards that reply with a NACK is easy (some clones), but distinguishing between cards that never reply with NACK and cards that do is harder.

See https://eprint.iacr.org/2009/137.pdf On average you need to send 128 queries to get one NACK back, but to get some assurance that a card never replies with a NACK, how many trials do you need to do?

If I'm right, to get a certainty of 99% that a card never emits NACKs, you need at least 1177 tests. (as (255/256)^1177 < 1% so there will be less than 1% chance that a card that replies NACKs won't reply any NACK 1177 times in a row).

To do the tests, you need to pick every time a fresh random nonce on the reader side otherwise as the timing is pretty stable on PM3 you will always hit the same internal state.

Process:

Fix your nonce, fix your timing, check the nonce of the card is also the one expected, so you know the keystream is always the same. Now vary the parity byte and try the 256 possibilities (or toggle one bit per command byte, which is the same as toggling parity bits)

Maybe there are shorter commands than 8 bytes that would trigger a NACK ? Then the NACK would be triggered sooner...

I tried to send only 4 bytes instead of 8 bytes during the Auth phase (so just nR and not nRaR) but the card never NACKs.

It seems we've to stick to these 8 bytes...

pwpiwi commented 6 years ago

To do the tests, you need to pick every time a fresh random nonce on the reader side otherwise as the timing is pretty stable on PM3 you will always hit the same internal state.

This is one of the possibilities, but you never will be sure 100%. The other option: you would keep the nonce and the internal state and vary the parity bits only. When you have tried all 256 combinations of parity bits and didn't receive a NACK then you have one of the cards never responding with NACK. This is when hf mf mifare gives up here: https://github.com/iceman1001/proxmark3/blob/5614066a4eb36b08e82f1074ac30408e8ca8983a/armsrc/iso14443a.c#L2518

So you have this check already.

iceman1001 commented 6 years ago

I belive the person who wrote it, meant that to ensure the card never responds with NACK and cards that do with statistical certainty within 1% error margin.

As you pointed out the current implementation does 256 tests with one nonce and its done.

iceman1001 commented 6 years ago

At least a draft is out. It works against some of my weak cards.
https://github.com/iceman1001/proxmark3/commit/bea28ae654110cc8c9584298783605893b2b15fa

Should do with a better selection of nonces. Maybe use the crypto-1 prng for this purpose?

iceman1001 commented 6 years ago

So this command is more or less done. Thanks @doegox for ideas and testing! hf mf nack

pm3 --> hf mf nack
...........          
NACK bug detected    

and with verbose,

pm3 --> hf mf nack v
Started testing card for NACK bug. Press key to abort          
Press pm3-button on the proxmark3 device to abort both proxmark3 and client.
...........          
Num of auth requests  : 261          
Num of received NACK  : 1          
NACK bug detected          
pm3 --> hf mf nack
.          
Always leak NACK detected          
pm3 --> hf mf nack v
Started testing card for NACK bug. Press key to abort          
Press pm3-button on the proxmark3 device to abort both proxmark3 and client.
.          
Num of auth requests  : 10          
Num of received NACK  : 10          
Always leak NACK detected