Mifare goes Umeå

Remember Umeå’s SMS bus tickets? Well, we didn’t really go all out on that one, considering it is reasonably an online system. Which means we can’t modify the central database and only imitate a legitimate ticket. However, of course, that’s good enough as long as the ticket inspectors don’t actually check the tickets against the central database. But with risk of becoming stale, we’re moving on to the real tickets. Pre-purchased cards containing any given amount of trips (that people can reasonably afford).

Länstrafiken i Västerbotten (though the buses are driven by Nobina) use RFID cards operating at 13.56MHz following the Mifare Classic standard. This is a fairly easy system to use, giving you contact-less tickets operating at a slightly more rapid verification speed than the old magnetic cards that were in use before.

Mifare Classic is also used in several other scenarios, be it other sorts of ticket systems or even security-related such as access control to buildings or computer systems. Thus, knowing how Mifare works is a good start if you want to crack it. Fortunately (so one doesn’t have to get in over one’s head) lots of people have been doing lost of fine work over the last decade. The tools needed to complete a full secret-key recovery of just about any Mifare classic card are all available as open source hardware and software. Thanks to a friend of mine, I now have access to a reader that allows for toying around with the security issues on Mifare cards.

A lot of the RFID technology has been, by me too, perhaps incorrectly bashed upon to be unsafe. Me and others have concluded that “just by walking into a room” you can know who are present through reading their RFID data. This is not true in the sense of immediate access to this knowledge. However, aggregating enough data may definitely resolve information needed to this at a restricted level. Regardless, the fact remains that RFID is contact-less, meaning it WILL transmit data available for interception – without being removed from your pocket – to the general public. It’s not as easy as 1-2-3. Maybe 5 though.

For my part I’m first going to read up on the actual standard, the available security research and whatever else may be necessary to know. In parallell I have started applying the available tools for dumping keys on RFID cards in my personal possession. For example, the crapto1 project (from Mifare Classic’s encryption scheme CRYPTO1) lists these sources as security research reports, it’s as good a start as any:

Also, the documentation provided by the libnfc project is very good and carries the ISO 14443, Mifare dump specifications etcetera. The project which binds crapto1, libnfc etc. together is mfcuk, which I use to maneuver a simple 30€ reader (ACS122 compatible, device ID 072f:2200). Because of WordPress’ disliking of certain file-endings, I’ll tar-gzip just this once and present to you 58127350-initial_payload.tar.gz – straight from nfc-mfclassic. Remember to take into account big/little endian decoding issues. I’m not dead-certain which order is which in the software versus Mifare specifications etc.

In either case, this is what hexdump tells me (cutting off the ASCII part):

00000000  67 62 ce fb 30 88 04 00  43 29 9c 43 00 19 08 09
00000010  34 01 14 07 14 07 14 07  14 07 14 07 14 07 14 07
00000020  14 07 14 07 14 07 00 00  00 00 00 00 00 00 00 00
00000030  a0 a1 a2 a3 a4 a5 78 77  88 c1 83 69 85 fa a9 3e
00000040  80 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
00000050  00 01 40 16 09 b0 03 76  f3 f6 06 59 08 8e 00 10
*
00000070  71 4a 90 80 b0 9b 78 77  88 00 e0 a8 67 68 31 6f
00000080  13 88 13 88 70 73 dd 70  74 19 00 10 8d 13 88 00
00000090  13 88 13 88 70 74 58 70  74 94 00 90 40 13 88 00
000000a0  1e 20 00 02 02 00 00 00  00 00 00 00 00 00 00 00
000000b0  5b 53 fb 10 d0 0c 78 77  88 00 92 c1 2e fb 21 24
000000c0  1e 1e 00 02 02 00 00 00  00 00 00 00 00 00 00 00
000000d0  10 40 dc 18 aa 1c 18 aa  1c 1c f7 5c 18 9f 70 00
000000e0  10 40 1c 18 aa 1c 18 aa  1c 1c f7 5c 1d 16 30 00
000000f0  32 a9 09 15 8a 1c 78 77  88 00 70 b8 b0 f2 f5 5a
00000100  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
*
00000130  34 4d 0a 51 12 87 78 77  88 00 fe 8f 9e 57 6d e4
00000140  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00

- empty sectors -

000002f0  a0 a1 a2 a3 a4 a5 ff 07  80 69 b0 b1 b2 b3 b4 b5
00000300  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00

- default keys -

0001000
  • 0x30, I’m not really sure what’s in Sector 0. A friend says it might be a Mifare Application Directory, MAD, sector. This seems reasonable. I’ll still have to read up on how those are specified.
  • 0x70, Sector 1 is most likely relevant data. Note similarities between 0x80-0x8F and 0x90-0x9F
  • 0xB0, Sector 2 is most likely also relevant data. Note similarities between 0xD0-0xDF and 0xE0-0xEF
  • 0x130, from here there are only empty sectors (at least on this specific card)
  • 0x2F0, from here default keys (0xA0A1A2A3A4A5/0xB0B1B2B3B4B5) are used and the sectors contain no data

I haven’t pondered yet at what the various hexes might decode to yet, but the similarities mentioned in sectors 1 and 2 will probably be of interest. Now we need diffs, timestamps, refills etc. This specific card is pretty unknown to me even at this point. But it’s a start and proof of concept.

And we’re out of coffee to brew at Umeå hackerspace. That sucks.

Update 2010-01-07 13.25: Having dumped another card, I verified that they used the very same keys on all sectors. The only difference on the key dump was the following (the first line, 0x0, being the card’s UID). Below is the payload diff:

1c1
< 00000000  d5 d8 20 f3 de 88 04 00  43 25 b4 53 00 11 0a 05
---
> 00000000  67 62 ce fb 30 88 04 00  43 29 9c 43 00 19 08 09
5,6c5,6
< 00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
< 00000050  00 01 40 16 09 b0 03 75  4c 6b 01 51 88 57 80 10
---
> 00000040  80 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
> 00000050  00 01 40 16 09 b0 03 76  f3 f6 06 59 08 8e 00 10
9,11c9,11
< 00000080  13 88 13 88 6b fc 01 6b  fc 3d 00 10 28 13 88 00
< 00000090  13 88 13 88 6b df 2d 6b  df 69 00 10 19 13 88 00
< 000000a0  12 00 00 02 02 00 00 00  00 00 00 00 00 00 00 00
---
> 00000080  13 88 13 88 70 73 dd 70  74 19 00 10 8d 13 88 00
> 00000090  13 88 13 88 70 74 58 70  74 94 00 90 40 13 88 00
> 000000a0  1e 20 00 02 02 00 00 00  00 00 00 00 00 00 00 00
13,15c13,15
< 000000c0  12 02 00 02 02 00 00 00  00 00 00 00 00 00 00 00
< 000000d0  10 40 9a f7 cb 5a ff 00  5a e4 2a 5a e6 0a 00 00
< 000000e0  10 40 5a f7 cb 5a df eb  9a e4 2a 5a e6 0a 00 00
---
> 000000c0  1e 1e 00 02 02 00 00 00  00 00 00 00 00 00 00 00
> 000000d0  10 40 dc 18 aa 1c 18 aa  1c 1c f7 5c 18 9f 70 00
> 000000e0  10 40 1c 18 aa 1c 18 aa  1c 1c f7 5c 1d 16 30 00

There is no plaintext in any sector. I’ll collect more data for later posts. Once the system is reverse-engineered, there’ll be a post describing the process of interpreting and what all differences are.

5 thoughts on “Mifare goes Umeå”

Leave a Reply

Your email address will not be published. Required fields are marked *