Since a while back, I’ve been active within the proxmark3-community. Proxmark3 is a device with which you can communicate with both HF and LF RFID cards. The software is not very user friendly, but the package is pretty much unlimited - the communication is implemented open source from scratch, and can thus be used to do almost anything. In contrast, commercial readers implement the ISO-standards, so cannot be made to for example simulate tags or vary the UID etc.

Cracking mifare

During the summer, quite a lot happened on the pm3-front. Cracking a mifare classic is very old news, but I was having trouble doing it even so, which led me to investigate that further. When it worked, it was a time-consuming event, but some cards were just never cracked (looking at you, SL).

In order to crack a mifare classic hf mf mifare, the device relies on a few flaws: predictable nonces being one. The way it worked (sorta) was this

  1. The pm3 powered on the card
  2. Wait a specified time.
  3. Ask for a nonce, ‘guess’ a nonce-response. In this step, the pm3 has a small chance of obtaining one bit of information about the keystrem.
  4. Power down the card.
  5. Wait for it to power down.
  6. Go back to 1.

The key thing here is that in order to succeed, the reader needs to obtain the same a lot of times, thus the timing between power-on and auth-request was very critical. After having received the same nonce many times, that “small chance” will have occurred enough times that 8 bits of keystream information has been leaked, thus the crack is complete.

I noticed that some cards needed a lot of time to power down. Unless the card powered down, the reader had no chance to hit the same nonce again. So, I implemented two things:

  • Card-tuning, so the reader could detect what amount of time a card needed in order to power down. This varied between cards from 50 to 800 milliseconds.
  • Several states - instead of just zoning in on once nonce, it kept state for a handful of nonces simultaneously, thus optimizing the chances of catching the one that will be ‘seen’ most often.

With those improvements, I was finally able to crack any card, even though it could take a while (in the area of ~15 minutes)

That was r727. Then ‘piwi’ blew me out of the waters with r745.

Piwi used another approach; instead of powereing down the card (which produced a delay of up to 800 ms between each nonce-request), he/she found a very reliable timer on the FPGA. Using that timer, the device instead waits 655536 cycles, after which the PRNG on the tag will complete a full circle. Super reliable, super fast.

Averaging 25 seconds. Wow.

Nested attack

Piwi further improved the ‘nested attack’. The original attack hf mf mifare obtains one key to one sector. The Mifare classic has lots of sectors, and two keys for each. There is another flaw within the Mifare Classic: when a key to a sector has been obtained, a ‘nested attack’ can be used to obtain all other keys very quickly.

In r764, piwi made some great improvements here also: hf mf nested approx 8 times faster, hf mf chk approx 4 times faster :forum thread

Lua scripting

I implemented Lua scripting within the proxmark3 host-code. For me, that makes a big difference, as the development cycle is much, much faster. When implementing Lua functionality, I don’t even have to restart the program, just :

  1. Write script
  2. Start pm3
  3. Do prerequisite stuff
  4. run script within pm3
  5. edit code
  6. run script again
  7. go to 5

In contrast, c-development (and this is ansi c, btw) cycle is:

  1. Write code
  2. Compile
  3. Start pm3
  4. Do prerequisite stuff
  5. Test code/feature
  6. Quit pm3
  7. go to 1

The Lua-functionality is, of course, inspired from the Nmap NSE implementation. However, I have not implemented any security checks - if you run a malicious script, that script can do whatever, whereas an Nmap NSE script executes in a bit more sandboxed environment.

So, obviously, as you would never run a bash-script from an untrusted source, don’t run a lua-script from an untrusted source.

A few scripts have been made so far:

  • Check default keys with mfkeys

    • The existing functionality to check if previously found ‘leaked’ keys can be used against a card; hf mf chk was a bit outdated. It contained only 13 keys, and first checked all a-keys and then all b-keys. I scraped the net a bit, and rounded up 69 unique keys from various sources.
  • Show mifare-dump as a highlighted html-report with htmldump

  • Convert dump from hf mf dump into a format that can be used by hf mf eload followed by hf mf sim with dumptoemul

  • Play with ISO 144443A raw

I have a few more that I want to complete, especially regarding LF-tags and mifare-based authentication. If you have any ideas or feedback, comment here or in the forum.

Oh, and implementing ProxBrute functionality as a lua-script shouldn’t be to difficult, I imagine.

This is how to run scripts

proxmark3> script list
parameters.lua   A script file          
dumptoemul.lua   A script file          
cmdline.lua      A script file          
mfkeys.lua       A script file          
14araw.lua       A script file          
htmldump.lua     A script file          
proxmark3> script run mfkeys

I’ll try to write more a another time about how to write scripts.