Hacking Boston Transit Cards

Hacking Boston Transit Cards

Reverse engineering MBTA CharlieCard MIFARE Classic cards

2020Security ResearchRFID
Heads Up!

This writeup is a work in progress. I will be updating it with more details in the coming months.

Overview

The Massachusetts Bay Transportation Authority (MBTA) operates transit services in the Greater Boston area. The MBTA's CharlieCard uses MIFARE Classic 1K chips, a widely-deployed contactless smart card technology. Through security research, I discovered vulnerabilities in how the MBTA stores and protects fare data, allowing for modification of fare value and duplication of CharlieCards.

Disclaimer

This research was conducted for educational purposes in early 2021. The vulnerabilites discussed here were publicly released at DEFCON in 2023 after a responsible disclosure to the MBTA by a group of students. The MBTA has since begun transitioning to more secure card technologies as part of their AFC 2.0 program.


Background

MIFARE Classic cards have been the backbone of transit systems worldwide since the 1990s. They use a proprietary cipher called Crypto-1 for authentication and encryption. In 2008, researchers from Radboud University published a paper revealing fundamental weaknesses in Crypto-1, effectively breaking the security model that thousands of transit systems relied upon.

MIFARE Classic Memory Structure

A MIFARE Classic 1K card contains 1024 bytes of EEPROM memory, organized into 16 sectors. Each sector consists of 4 blocks, with each block holding 16 bytes of data. This gives us 64 blocks total (numbered 0–63).

The memory layout follows a specific structure:

  • Block 0 (Sector 0, Block 0): The manufacturer block, containing the card's unique 4-byte UID, manufacturer data, and check bytes. This block is read-only and set at the factory.
  • Blocks 1–2 (Sector 0): Available for data storage.
  • Block 3 (Sector 0): The sector trailer, containing Key A (6 bytes), access bits (4 bytes), and Key B (6 bytes).

This pattern repeats for all 16 sectors — the last block of each sector (blocks 3, 7, 11, 15, etc.) is always the sector trailer that controls access permissions. The access bits define what operations (read, write, increment, decrement) are allowed with Key A versus Key B, enabling sophisticated access control policies.

The access bits are particularly clever: they're stored with redundant inverted copies, allowing the card to detect corruption. If the access bits become corrupted, the entire sector becomes permanently inaccessible — a security feature that can also brick cards if manipulated incorrectly.


The Attack

Key Recovery

The first step in analyzing the CharlieCard was recovering the sector keys. MIFARE Classic's Crypto-1 cipher has well-documented cryptographic weaknesses, and several attack vectors exist for key recovery.

The most reliable approach is a two-stage attack. First, I needed to recover at least one sector key. I used a Darkside attack (implemented by mfcuk), which exploits flaws in the card's pseudo-random number generator and the way it responds to failed authentication attempts. By analyzing the error responses and timing, this attack can recover a single key without any prior knowledge — though it can take several minutes to hours depending on the card.

Alternatively, if you have access to a legitimate reader, you can sniff the authentication exchange between the reader and card using the Proxmark in eavesdrop mode. The captured nonces and encrypted responses can then be analyzed offline to recover the key.

Once I had a single valid key, I used mfoc (MIFARE Classic Offline Cracker) to perform the nested authentication attack. This attack exploits the weak PRNG to recover all remaining sector keys in under a minute. The attack works by authenticating to the known sector, then initiating authentication to unknown sectors — the predictable nonce generation allows the unknown keys to be mathematically derived.

What I discovered was alarming: the MBTA uses an identical set of keys across their entire CharlieCard fleet. There is no key diversification — once you recover the keys from a single card, you have the keys to read and write every CharlieCard in circulation. This is a fundamental architectural flaw that makes the system trivially vulnerable at scale.

Analyzing Card Data

With the keys recovered, I dumped the card's memory and began the tedious process of reverse engineering the data format. Unlike modern systems with documented APIs, transit card formats are proprietary and undocumented. The only way forward was manual analysis.

I started by comparing hex dumps from multiple cards and from the same card at different fare values. By adding $5 to my card and comparing before/after dumps, I could identify which bytes changed. The fare balance wasn't stored in an obvious location — it took careful examination to identify the relevant sector.

One interesting security mechanism I encountered was a rotating transaction log. Rather than writing transaction data to a fixed location, the card cycles through multiple blocks to record trip history. Each transaction entry includes a sequence number, and the system reads all entries to find the most recent valid one. This makes simple replay attacks more difficult, as you can't just restore an old block without the sequence numbers revealing the tampering.

The fare data itself employed some obfuscation: values were stored with simple XOR masks and split across non-contiguous bytes. While not true encryption, this required additional effort to decode. I mapped out the data structure by making small fare changes and tracking exactly which bits flipped.


Findings

  1. No Key Diversification: The MBTA uses identical keys across all CharlieCards. Recovering keys from one card compromises the entire system.
  2. No Backend Validation: The system relies entirely on card-side data validation. Fare readers trust whatever value the card reports without cross-checking against a central database.
  3. Weak Obfuscation: Fare data uses simple XOR masks rather than proper encryption, providing only minimal protection against reverse engineering.
  4. Predictable Structure: Once the data format is understood, arbitrary fare values can be written to any card.

Tools Used

  • Proxmark3 - RFID research and development platform for sniffing, emulating, and cloning cards
  • libnfc - Open source NFC library for low-level card communication
  • mfoc - MIFARE Classic offline cracker implementing the nested authentication attack
  • Hex editor - For manual analysis of card dumps and pattern identification

Lessons Learned

This project reinforced a critical security principle: never trust the client. The MBTA's system placed all trust in the card itself, with no server-side validation of fare values. A properly designed system would treat the card as untrusted storage and validate all transactions against a backend database.

The lack of key diversification was equally problematic. Modern transit systems derive unique keys for each card using a master key and the card's UID. Even if one card is compromised, the keys are useless for any other card in the system.