Skip to content

Proxmark3 vs Ultralight C

by on April 4, 2014

Proxmark 3

There have been no secrets this week while I’ve been trying to add Mifare Ultralight C support to the Proxmark. Ultralight C cards are HF (13.56MHz) tags that are part of the Mifare family.  This week has been an interesting learning process, and it has corrected some misconceptions I had about the card.  For those interested you can follow my progress at http://www.proxmark.org/forum/viewtopic.php?id=1946.  But I will summarise my findings below:

Ultralight C

Card Size & Readable Blocks

The Card has 0x2f Pages (or blocks) which means 47 decimal blocks.  However, only 43 of these are readable. The remaining 4 blocks contain the 3DES Key needed for authentication, and are write only, so the key cannot be simply recovered.

proxmark3> hf mfu ucrdcard
Attempting to Read Ultralight C...
#db# READ CARD FINISHED
isOk:01
Block 00:04 0e 6b e9
Block 01:ca 0b 28 80
Block 02:69 48 00 00
Block 03:00 00 00 00 [0]
Block 04:02 00 00 10 [0]
Block 05:00 06 01 10 [0]
Block 06:11 ff 00 00 [0]
Block 07:ff ff ff ff [0]
...abreviated...
Block 2b:00 00 00 00 [0]

Encryption

Contrary to belief (I admit making an initial mistake here), Ultralight C contents are not encrypted by default! (Unless cryptography has been added by the controlling application).  Basically a 3DES (Triple DES) key (16 bytes split into key 1 and key2, (key3=key1)) is used for Authentication Only! Depending on the configuration of Auth0 & Auth1 Page/Block (2a byte 0 & Page 2b Byte 0) depends on what pages/blocks are accessible.

  • Auth0 controls the page range from 0x03 – 0x30; (0x00 = disabled)
  • Auth1 controls the enforced restrictions 0x1 = Read Unauthenticated & Write Protected 0x00 = Read & Write Protected

Authentication (Updated 8th April 2014)

Below is a trace of attempted authentication with an Ultralight C card:

proxmark3> hf mfu auth
#db# Auth1 Resp: af1eae15f85b05e32d99b5                 
#db# AUTH 1 FINISHED                 
enc(RndB):1e ae 15 f8 5b 05 e3 2d           
     RndB:13 46 86 a9 4b f7 94 cd           
     RndA:9b 75 fe 7f 5b 9e ba 79           
     RA+B:9b 75 fe 7f 5b 9e ba 79 46 86 a9 4b f7 94 cd 13           
enc(RA+B):62 7a b7 02 0c fe c7 8b a2 4e 6b 43 5e 0f a0 b7           
#db# len b                 
#db# Auth2 Resp: 00fcb27f6e3d5db88b8e                 
#db# AUTH 2 FINISHED                 
isOk:88 Resonse:00 00 00 00 00 00 00 00           
proxmark3> hf 14a list
Recorded Activity          
          
Start = Start of Start Bit, End = End of last modulation. Src = Source of Transfer          
All times are in carrier periods (1/13.56Mhz)          
          
     Start |       End | Src | Data          
-----------|-----------|-----|--------          
         0 |       992 | Rdr | 52              
      2404 |      4772 | Tag | 44  00              
      7040 |      9504 | Rdr | 93  20              
     10852 |     16740 | Tag | 88  04  0e  6b  e9              
     18816 |     29280 | Rdr | 93  70  88  04  0e  6b  e9  2c  90              
     30692 |     34212 | Tag | 04  da  17              
     35456 |     37920 | Rdr | 95  20              
     39268 |     45092 | Tag | ca  0b  28  80  69              
     47232 |     57760 | Rdr | 95  70  ca  0b  28  80  69  69  f1              
     59108 |     62692 | Tag | 00  fe  51              
     66176 |     70944 | Rdr | 1a  00  41  76              
     82660 |     95460 | Tag | af  1e  ae  15  f8  5b  05  e3  2d  99  b5              
   1031296 |   1053344 | Rdr | af  62  7a  b7  02  0c  fe  c7  8b  a2  4e  6b  43  5e  0f  a0  b7  96  df              
   1065060 |   1077796 | Tag | 00  fc  b2  7f  6e  3d  5d  b8  8b  8e  cc 

Basically:

  1. The authentication starts with the command 1A 00 concatenated with an iso1433a CRC.
  2. The card/tag responds with AF followed by 8 bytes e_k(RndB) and a 2 byte CRC
  3. This e_k(RndB), is an encrypted Random number with key k.
  4. We decrypt these bytes to get the real number RndB’ =
    13 46 86 a9 4b f7 94 cd
  5. Next we generate our own random number (if we wish)  RndA =
    9b 75 fe 7f 5b 9e ba 79
  6. Rotate RndB’ left by 8 bits
  7. Concatenate RndB’ with Rnd A =
    9b 75 fe 7f 5b 9e ba 79 46 86 a9 4b f7 94 cd 13
  8. We encrypt RndA||RndB’ and send this to the tag with a command byte of AF + our enc(RndA||RndB’) = 
    62 7a b7 02 0c fe c7 8b a2 4e 6b 43 5e 0f a0 b7
  9. The tag should respond with 8 bytes, which should be e_k(RndA’) =
    fcb27f6e3d5db88b
  10. This point we can decrypt and rotate the result right 8 bits and it should match our initial RndA value.  But because we have a valid response we can choose to ignore it 🙂

Where to get blank tags?

I purchased my Ultralight C tags from Amazon:

http://www.amazon.co.uk/s/ref=nb_sb_noss?url=search-alias%3Daps&field-keywords=mifare%20ultralight%20c

Conclusion

Cracked it! 🙂  Currently my Proof-of-Concept is hard coded with the default 3DES Ultralight key!  Now I just need to modify the code slightly to take as input a user supplied key.

What keys did I use you may ask?  I have tried an empty key, and the default 3DES key specified in libfreefare, and 000102030405060708090a0b0c0d0e0f

Code

Code has recently been published on the Pentura  Github repo:

https://github.com/PenturaLabs/proxmark3/tree/Ultralight-Mod

Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: