Full Report
The Titan M chip was put onto Pixels in 2018. This chips main purpose is to reduce the attack surface for attackers. This chip is on a separate SoC that runs its own special firmware and communicates to the main chip via the SPI bus. The point of the chip is to hold secret information, such as a hardware backed keystore. The firmware runs a lightweight open source operating system called Embedded Controller. The OS acts as a Real Time Operating System (RTOS) with only the concepts of tasks. It only have a fixed stack size and no heap. Additionally, it has Nx but no other binary protections, such as ASLR or stack canaries. The authors decided to fuzz the different services offered by the Titan M chip for memory corruption vulnerabilities. They tried two approaches: black-box fuzzing and emulation based fuzzing. The black-box fuzzing was simple to do since the tasks use ProtoBuf, allowing for the built in libprotobuf-mutator to be used. ProtoBuf definitions have to be around somewhere in order for this to be usable. They found a few bugs with this but because they couldn't just hook GDB up to the OS, it was much harder to find deep bugs. Emulation based fuzzing was more fruitable on this project, since the firmware was publicly available. After reverse engineering the firmware some more, they found the proper place to put the inputs in order to mutate the proper things for fuzzing. To emulate and fuzz, they used AFL++ and their Unicorn emulation mode. One issue with emulation based fuzzing is that hardware-dependent functions must be hooked to have no functionality in order to still run. After fuzzing for a while, they found a crash in the call to ImportKey. The parameters were simply taking a large index and writing the value 1 to this. This vulnerability looks small but can be triggered multiple times. Additionally, since the memory is completely static and this is a relative write, lots can be done with this. Before they wrote the exploit, they had to find a reasonable way to debug this... without GDB or some debugger. The chip has UART debug output on it. If they could run code that would print to this log, it would be possible to learn some information about the system. Attacking these chips is hard not because of the complex vulnerabilities but because of the non-standard exploitation environment providing other challenges. What do we even overwrite with a single 1 that would be useful? After writing Ghidra scripts looking for good targets they found the structure KEYMASTER_SPI_DATA, which contains information about the messages going back to Android. By overwriting a pointer to this structure from 0x192c8 to 0x101c8, later incoming requests will be written to this location! Since this is a valid address, this gives us a much better primitive for writing. They noticed that writing a valid code address to 556 bytes after the payload for a KeyMaster operation allowed them hijack control flow. This was tested by force printing logs to the UART console. From there, they wrote a ROP chain with a complicated stack pivoting gadget. The only way we could return our leaked bytes back to Android was to copy them in the response of an SPI command. To do this, they needed to be in the context of the handling, which was essentially in a jump table. To make this work, they used the previous calls to setup a stack frame with a SINGLE gadget to move the stack. By doing this, they could write to a location where the data wouldn't be changed between execution of tasks. Eventually, another call could be made, using the previous data as the final ROP chain. The final ROP chain called memcpy with the user-provided arguments, allowing them to read in the Keymaster SPI response buffer. Then they could jump back to the Keymaster stack, like the normal command handler would have done, to return the data. This allowed them to dump all of the secrets on the chip. Overall, great post on vulnerability discovery and exploitation!
Analysis Summary
# Vulnerability: Out-of-Bounds Write in Titan M Firmware Leading to Key Leakage
## CVE Details
- CVE ID: CVE-2022-20233
- CVSS Score: N/A (Severity based on impact, researcher noted high potential, Google assigned $75k bounty, indicating high severity)
- CWE: CWE-787 (Out-of-bounds Write)
## Affected Systems
- Products: Google Pixel smartphones utilizing the Titan M Security Chip (introduced starting with Pixel 3).
- Versions: Specific vulnerable firmware versions on the Titan M chip prior to the June 2022 update.
- Configurations: Titan M running the Embedded Controller (EC) firmware, communicating via the SPI bus.
## Vulnerability Description
The vulnerability exists in the Titan M firmware, which runs on an Embedded Controller (EC) RTOS with static memory allocation. Researchers found a crash in the `ImportKey` function during fuzzing. This flaw was an **Out-of-Bounds Write** triggered by providing exceptionally large index values as parameters, which resulted in writing the constant value `1` to an arbitrary, statically determined memory location. Due to the static memory layout of the RTOS, this predictable write primitive was leveraged to achieve corruption of critical data structures, specifically overwriting a pointer related to the KeyMaster SPI data structure (`KEYMASTER_SPI_DATA`). By manipulating this pointer, the attacker could redirect subsequent incoming requests to a controlled memory location, ultimately enabling control flow hijacking.
## Exploitation
- Status: **Proof-of-Concept (PoC) available** (Researchers demonstrated ROP chain execution and successful exfiltration of secrets).
- Complexity: **High** (Exploitation required extensive reverse engineering of the static environment, finding suitable gadgets, developing complex stack pivoting techniques, and manually setting up the environment via the UART console before achieving arbitrary read/write to leak stored secrets).
- Attack Vector: Adjacent/Local (Requires access to communicate with the Titan M via the SPI bus, typically through the main Application Processor context).
## Impact
- Confidentiality: **High** (Successful exploitation led to the dumping of all secrets stored on the chip, including hardware-backed Keystore data).
- Integrity: **High** (Control flow hijacking allows arbitrary code execution within the Titan M context).
- Availability: **Low** (The primary impact is data compromise, not system downtime, although a successful crash/exploit could lead to a temporary denial of service).
## Remediation
### Patches
- Patches were released in the **June Pixel Update Bulletin (2022)**. Specific firmware versions containing the fix are not detailed but correspond to updates rolled out on or around June 10, 2022.
### Workarounds
- No specific external workarounds were detailed, as the vulnerability is deep within the trusted execution environment firmware and required an update from Google.
## Detection
- **Indicators of Compromise (IoCs):** Unexpected or anomalous state transitions or command handling within the Titan M firmware, particularly involving SPI communication payloads processed by the `ImportKey` function handler, or non-standard activity logged to the UART debug interface if accessible.
- **Detection Methods and Tools:** Standard hardware-level monitoring tools might detect abnormal SPI traffic patterns related to the input corruption, but effective detection relies primarily on applying vendor security updates quickly.
## References
- Vendor Advisory/Fix: June Pixel Update Bulletin (2022).
- Relevant links - defanged:
- hxxps://nvd.nist.gov/vuln/detail/CVE-2022-20233
- hxxps://blog.quarkslab.com/attacking-titan-m-with-only-one-byte.html (Original research publication)