Attacking Titan M with Only One Byte

We discussed this vulnerability as part of our weekly podcast on 21 September 2022

The Titan-M is a security chip found on Google’s Pixel devices from Pixel 3 onwards. This post goes through some of the background and reversing they did on the chip, as well as exploring some fuzzing routes through blackbox as well as emulation via unicorn. Through emulated fuzzing, they found a vuln in the Keymaster task’s ImportKey handler, which had a wild one-byte write of 1. It seems the KeyParameters field was used to index into a stack buffer to set a byte to 1, but there was no bounds checking. At first this seems a weak primitive, but the Titan-M’s memory is static, and lacks mitigation for memory corruption beyond W^X.

They were able to smash one byte of the address where incoming keymaster requests get stored, giving a more useful out-of-bounds write. They then were able to corrupt a return pointer to ROP, and setup a second stage ROP chain to exfil data over SPI. The secondary ROP chain would be triggered by smashing the command handler with the first ROP chain. Unfortunately they couldn’t find any stack-pivot gadgets that were suitable for launching the secondary chain, but they found a cool trick. A stack pivot could be achieved as they discovered the DestroyAttestationIds handler had a 32-bit slot in the stack-frame that wasn’t overwritten by a previous function, giving a trampoline to stack-pivot. They were then able to break root of trust, exfil keys, etc.