Reading some RFID cards

Note that this information is incomplete at best, and possibly incorrect. It is purely what I’ve gleaned from observation and subsequent web-searching. Your actions are your own responsibility.

Reading RFID cards with the Proxmark is probably the most common use-case; it’s certainly the thing I do most often, followed by attempting to write the info onto a cloned card to verify that I’ve read all of the relevant info from the card.

How you read a card depends entirely on what sort of card it is, and that usually isn’t obvious just by looking at the card.

There are broadly 2 different categories of card (low and high frequency), and many different types within each category. Helpfully, the Proxmark is reasonably good at identifying what type of card it is. Simply running lf search and hf search in turn will generally tell you what type of card it is, and therefore what to do next.

Low frequency cards

There are several types of low frequency card, but all the ones which I’ve encountered are purely a unique ID and don’t contain any data storage or any security around that unique ID (e.g. a pre-shared secret needed to access the ID). This means that if you’re carrying one of these cards, then anyone can brush up against you in the street and read everything they need to know to clone your card.

The low frequency cards which I’ve come across are the HID Prox ID and the Honeywell EM410x. There is a chip called the T5577 which is able to emulate both of these types of cards, which is quite useful.


On running the lf search command, you’ll see something like this:

[+] HID Prox TAG ID: 123456789a (123456) - Format Len: 35bit - OEM: 000 - FC: 2716 - Card: 123456

The important bit here is the ID 123456789a - this is likely what the reader is looking for, and the only information you need to clone the card. To write this ID on to something like a T5577, use the command:

lf hid clone 123456789a

Honeywell EM410x

If lf search identifies the card as an EM410x, then it’s one of a series of Honeywell cards.

There is a subset of commands for dealing with the EM410x chips, under the lf em command. For example, to get detailed information from an EM410x card, similar to what lf search shows, use the command lf em 410x_read which will give an output like:

EM410x  pattern found

EM TAG ID      : 123456789A

Possible de-scramble patterns
Unique TAG ID  : ABCDEF1234
HoneyWell IdentKey {
DEZ 8          : 04444444
DEZ 10         : 0004444444
DEZ 5.5        : 00333.22222
DEZ 3.5A       : 999.22222
DEZ 3.5B       : 000.22222
DEZ 3.5C       : 333.22222
DEZ 14/IK2     : 55555555555555
DEZ 15/IK3     : 666666666666666
DEZ 20/ZK      : 77777777777777777777
Other          : 22222_333_04444444
Pattern Paxton : 1111111111 [0x123456789A]
Pattern 1      : 22222222 [0xDEF123]
Pattern Sebury : 22222 333 4444444  [0x789A 0x56 0x56789A]

To clone this onto a T5577, run this command:

lf em 410x_write ABCDEF1234 1

Note that there are 2 IDs in the output of lf em 410x_read: “EN TAG ID” and “Unique TAG ID”. You want to use the ID from “Unique TAG ID” in the lf em 410x_write command.

High frequency cards

In my experience, these are considerably more complex than the low frequency cards, and involve a number of different layers defined in various standards. All of the high frequency cards which I’ve come across are various types of Mifare cards, which build upon ISO 14443. There are also cards which build upon ISO15693 but I’ve not seen any of those.

ISO 14443 is a 4-layer standard, covering everything from the radio interface (including collision detection and avoidance) through the way that packets are constructed and even some basic application-level “commands”. Specific cards (e.g. Mifare Classic) then build upon this with their own application-level commands.

Mifare Classic

Mifare Classic cards have a series of data storage blocks, arranged into sectors, which are protected by one or two keys. Different keys are allowed per sector. Authorization for read, write, and key update can be granted per key per sector, so you can (for example) allow sector “3” to be read by its key “A”, and for its key “B” to be able to write the data and to update keys “A” and “B”. Sector 0 is reserved (it’s where things like the card’s UID are stored) and not updateable by normal means.

Sector and block numbering is contiguous; this means that sector 0 is blocks 0, 1, and 2, with block 3 for the sector’s config, while sector 1 is blocks 4, 5, and 6, with block 7 for the sector’s config, etc. Block 45 is in sector 11.

I’ve seen Mifare Classic in 3 sizes: 1k, 2k, and 4k. This is the total size of all of the data sectors, however (for the 1k) this is subdivided into a 15 usable sectors of 48 usable bytes each (plus sector 0). The 2k is basically double the sectors from the 1k cards, therefore has 31 usable sectors with 48 bytes each. The 4k has 31 usable 48-byte sectors, and an additional 8 sectors with 240 bytes each; the block sizes are the same, but there are more blocks in each of the top 8 sectors. Block 233 is in sector 38.

This diagram from Suprema explains it well: Mifare Classic memory layout

This is how the Mifare Classic cards look when presented to a Proxmark running hf search:

 UID : 01 02 03 04
ATQA : 00 02
 SAK : 18 [2]TYPE : NXP MIFARE Classic 4k | Plus 4k SL1
proprietary non iso14443-4 card found, RATS not supported
No chinese magic backdoor command detected
Prng detection: HARDENED (hardnested)

In this case, the unique ID (UID) is 01 02 03 04. Sadly, many security systems entirely base their authentication on this value, leaving the cards no more secure than the low frequency cards mentioned above.

Official Mifare Classic cards from NXP (or possibly licensed from NXP) don’t have the capability to change their UID, or write to block 0 at all regardless of what key is used. However, there are some unauthorised cards from a place in China which respond to an extra set of “magic” commands, which do allow the UID to be changed. These are not common cards, but are generally found in “pen-testing” packs (e.g. the set I got from Lab401). The card in the example above is an “official” card, hence it saying No chinese magic backdoor command detected. Since it is possible to detect the presence of magic commands, some readers are known to also test for these and deny access to a card which responds to them; to combat this, there are also cards which will respond to the magic commands once to let you change the UID, but then no longer respond to them. There are also unofficial cards which let you change the UID by allowing you to write directly to block 0; if you write the wrong thing to these, it is easy to brick the cards.

To write a UID to a Chinese magic card, run this command:

hf mf csetuid 01020304

You should see output like this:

[usb] pm3 --> hf mf csetuid 01020304
--wipe card:NO  uid:01 02 03 04
[+] old block 0:  01 01 01 01 00 98 02 00 E3 41 00 20 00 00 00 14
[+] new block 0:  01 02 03 04 04 98 02 00 E3 41 00 20 00 00 00 14
[+] old UID:00 00 00 00
[+] new UID:01 02 03 04

and an hf search shows the new UID in use:

[usb] pm3 --> hf search
[=] Checking for known tags...

 UID : 01 02 03 04
ATQA : 00 02
 SAK : 08 [2]
TYPE : NXP MIFARE CLASSIC 1k | Plus 2k SL1 | 1k Ev1
[=] proprietary non iso14443-4 card found, RATS not supported
[+] Answers to magic commands (GEN 1a): YES
[+] Prng detection: WEAK

[+] Valid ISO14443-A tag  found

To copy an arbitrary data block from one card to another:

# Read block 4 from the "source" card using the key 'ffffffffffff'
hf mf rdbl 4 a ffffffffffff
--> data: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f           

# Write the result to block 4 on the "destination" card
hf mf wrbl 4 a ffffffffffff 000102030405060708090a0b0c0d0e0f

To clone the rest of the data blocks on the card, you ideally need to know the key for each block. There are some well-known defaults, which ship with the Proxmark codebase; to try them, run this:

hf mf chk *1 A t

(This is for a 1k card; if you have a 4k card, change the “1” for a “4”. Also, this will check the “A” keys)

You should see output like this:

|sec|key A           |res|key B           |res|
|000|  ffffffffffff  | 1 |  ffffffffffff  | 1 |
|001|  ffffffffffff  | 1 |  ffffffffffff  | 1 |
|002|  ffffffffffff  | 1 |  ffffffffffff  | 1 |
|003|  ffffffffffff  | 1 |  ffffffffffff  | 1 |
|004|  ffffffffffff  | 1 |  ffffffffffff  | 1 |
|005|  ffffffffffff  | 1 |  ffffffffffff  | 1 |
|006|  ffffffffffff  | 1 |  ffffffffffff  | 1 |
|007|  ffffffffffff  | 1 |  ffffffffffff  | 1 |
|008|  ffffffffffff  | 1 |  ffffffffffff  | 1 |
|009|  ffffffffffff  | 1 |  ffffffffffff  | 1 |
|010|  ffffffffffff  | 1 |  ffffffffffff  | 1 |
|011|  ffffffffffff  | 1 |  ffffffffffff  | 1 |
|012|  ffffffffffff  | 1 |  ffffffffffff  | 1 |
|013|  ------------  | 0 |  ------------  | 0 |
|014|  ------------  | 0 |  ------------  | 0 |
|015|  ------------  | 0 |  ------------  | 0 |
[+] Found keys have been transferred to the emulator memory

This means that it has found that key ffffffffffff is in use for sectors 0-12, but sectors 13, 14, and 15 use an unknown key.

If that doesn’t work, then you’ll need to try to brute-force the key. Since the key-space is so large, this will take an unpalatably large amount of time, however there’s a weakness in the implementation of Mifare Classic which allows you to discover all of the keys if you know at least one of the keys already. Assuming that you know that the key for block 3 is 010203040506, then you can run this to get another key (e.g. for block 5):

hf mf hardnested 3 A 010203040506 5 A

In the example which I have, this takes around 17 seconds to get the key for the target block. This eventually gives you a line which looks like Brute force phase completed. Key found: 101112131415

… and then this to read the data blocks:

hf mf rdbl 5 A 101112131415

Once you know the key for a sector, you’ll want to start making a custom “dictionary” with the known keys in it. Put the keys, one per line, into a file my_keys.dic in the client/ directory:

(echo ffffffffffff ; echo 000000000000 ; echo 010203040506 ; echo 101112131415) > my_keys.dic

… and then check the whole card against these keys:

hf mf chk *1 ? my_keys.dic

To clone a card, once you know the keys, you need to dump them to a file for later use:

hf mf chk *1 ? my_keys.dic d

… then dump the contents of the card into a file:

hf mf dump

Now switch out the source card for the destination card, and “restore” the dump onto it:

hf mf restore 01020304

If you have a 2k or 4k card, you need to add a “2” or a “4” to all of the above commands; check their docs for info on where to add that.

As well as reading / writing data and keys, the Mifare Classic commands allow for some built-in manipulation of the stored data. For example, it is possible to increment a counter every time a particular data block is accessed, useful in applications like travel ticketing.

Mifare DESFire

These are a far more complex card than the Mifare Classic, and bear little relation to them at all other than they are also built on top of ISO 14443. Instead of data blocks, these store a number of “applications” each with its own “application ID” (AID). Instead of using a pre-shared key to interact with the card, it is possible to restrict access to an application using one of a number of authentication schemes (DES, 3DES, AES). Currently, there are no known exploits for extracting the key or accessing an application without knowing the key.

A common application to “install” onto a DESFire card is the “NDEF Tag Application”, AID D2760000850101, which allows for NDEF “files” to be stored on the card. These can store (e.g.) vcard files, for exchanging contact details with a phone when the card is presented. DESFire cards are available up to 8k (or maybe more) which allows for a useful amount of contact info (e.g. including a logo).

In pictorial form, the layers involved:

Vcard in an NDEF "file"
NDEF Tag Application
ISO 14443-4
ISO 14443-3
<Some physical layer, e.g. ISO 14443-1,2

I haven’t dug into DESFire cards too much currently, if/when I do I’ll write more and link it from here.