Attacking Titan M with Only One Byte (CVE-2022-20233)¶
Titan M Keymaster handler'ında emulated fuzzing ile bulunan single-byte out-of-bounds write, full code execution'a ve StrongBox-protected key'lerin extraction'ına escalate edilir.
Mechanism¶
Note
Titan M, Google'ın Pixel telefonlarda gönderdiği (Pixel 3'ten beri) dedicated security chip'idir. Open-source Chrome EC framework'ünden türetilmiş hafif, task-based bir embedded OS çalıştırır; static bir memory layout'a sahiptir (klasik anlamda heap yoktur) ve eşzamanlı write+execute permission'larını yasaklayan bir MPU'su vardır. Application Processor (AP) onunla bir SPI mailbox üzerinden konuşur ve serialized command request'leri (Keymaster, Weaver, attestation vb.) gönderir.
CVE-2022-20233, Keymaster ImportKey request handler'ındaki bir out-of-bounds
single byte write'ıdır. Handler KeyParameter tag'lerinin listesini parse ederken
DIGEST tag'ini (0x20005) arar.
Bulduğunda, attach edilmiş integer value'yu alır ve — bazı check'lerden sonra
ama uygun bir upper-bound check olmadan — onu bir
stack buffer'a offset olarak kullanır, oraya strb instruction'ı ile 1 sabitini yazar.
Aşılan trust boundary AP-to-chip'tir: bir Keymaster request'ini
kontrol eden bir attacker (yani Android tarafındaki kod) SPI
mailbox üzerinden uzanıp security chip'in memory'sini corrupt eder. Offset
attacker-influenced olduğundan, tek write byte'ı amaçlanan
buffer'ın dışına düşebilir.
Bir byte'ın neden yeterli olduğu: ASLR'siz, static-layout bir cihazda bilinen bir target address güvenilir şekilde erişilebilirdir. "Least significant byte yalnızca 0x0, 0x2 veya 0x4 olabilir" kısıtı bile seçili bir pointer field'ı clobber etmek için yeterli özgürlük bırakır. Araştırmacılar primitive'i bir global structure'daki request-buffer pointer'ını yeniden yazmak için kullandılar, 1-byte write'ı controlled bir büyük overwrite'a, sonra da ROP ve code execution'a dönüştürdüler.
Walkthrough¶
Bug, emulation-based fuzzing ile keşfedildi: Unicorn mode'unda AFL++,
Keymaster task'larını tek tek emulate ediyor ve libprotobuf-mutator ile
protobuf-shaped mesajlar üretiyordu. Crash, bir ImportKey request'i handle edilirken
bir Unicorn UC_ERR_WRITE_UNMAPPED olarak yüzeye çıktı — firmware
unmapped memory'ye bir byte yazmaya çalıştı.
Kavramsal olarak, vulnerable parse loop şunu yapar:
// pseudo-code reconstructed from the writeup
for (each KeyParameter p in params) {
if (p.tag == 0x20005 /* DIGEST */) {
// checks omitted: no proper upper bound on p.integer
stack_buffer[p.integer] = 1; // strb -> 1-byte OOB write
}
}
Quarkslab tarafından tarif edilen exploitation chain'i:
- SPI request-buffer pointer'ını redirect et.
0x1e21doffset'ine0x01yazmak Keymaster SPI data structure'ını değiştirir, böylece gelen request buffer adresi değişir (0x192c8'den0x101c8'e taşındığı raporlanmış). Artık sonraki request byte'ları amaçlanan buffer yerine komşu memory'yi overwrite eder. - Bir payload sahnele. 556-byte'lık bir payload, bir stack frame unwind edildiğinde kontrolü ele geçiren geçerli bir code address taşır (bir idle task'ın saved return pointer'ı overwrite edilir).
- ROP ile stack pivot.
sub sp, #0x20; mov r4, r0; ldr r3,[r0]; add.w r5,r4,#0x70; ldr r3,[r3,#8]; blx r3formundaki bir gadget, stack'i tamamen controlled memory'ye "tırmanmak" için kullanılır. - Bir command handler'ı hijack et.
DestroyAttestationIdscommand handler'ının adresi değiştirilir ve bir trampoline gadget execution'ı final ROP chain'ine pivot eder. - Bir read primitive inşa et. Chain, attacker-chosen
argument'larla
memcpyçağırır, target memory'yi Keymaster SPI response buffer'ına kopyalar, böylece AP tarafından read back edilebilir.
Code execution ile araştırmacılar StrongBox-protected
cryptographic key'leri (örn. BeginOperation'ı sürüp sonra memory'yi dump'layarak),
boot ROM içeriklerini ve bootloader'dan geçirilen Root of Trust'ı exfiltrate ettiler.
Impact'i bir test app'inden bir AES key extract edip
veriyi offline decrypt ederek gösterdiler.
Kullanılan tooling
nosclient— Quarkslab'ın Titan M'e SPI interface üzerinden arbitrary komutlar göndermek için açık kaynak client'ı.- Chip log'larını okumak ve exploitation'ı confirm etmek için bir SuzyQable debug cable (ya da lehimlenmiş wire'lar) üzerinden UART console erişimi.
Warning
Yalnızca authorized research / CTF / defensive kullanım. Chain, belirli bir firmware sürümünün static, ASLR-free layout'una bağlıdır; yukarıdaki offset ve gadget cited writeup'tan gelir ve version-specific'tir.
Detection¶
- Firmware version detection. En güvenilir pratik indicator patch level'dir: June 2022
öncesi Pixel Security Update'inde kalan Titan M firmware'i vulnerable'dır. Cihazın
security patch level'ını (
ro.build.version.security_patch) kontrol etmek, fielded bir fleet'te riski triage etmenin birincil yoludur. - Anomalous NOS/Keymaster traffic. Exploit, privileged bir Android context'inden SPI
mailbox üzerinden malformed
ImportKeyrequest'leri (out-of-rangeDIGESTtag value'ları ile) gönderilmesini gerektirir;nosclienttarzı raw NOS command trafiği veya beklenmedik Keymaster tag pattern'leri host tarafında gözlemlenebilir bir işaret olabilir. - Chip fault / reset telemetry. Corrupting write'lar Titan M'de unmapped-memory fault'ları,
task crash'leri veya reset'ler tetikleyebilir; UART console log'ları (SuzyQable üzerinden) ya
da kernel'in gördüğü tekrarlayan NOS/
citadelreset'leri, lab ortamında exploitation'ın bir belirtisidir. - Inherent limitation. Bir kez chip compromise edildiğinde host tarafından güvenilir detection/attestation zordur; bu yüzden birincil savunma detection değil, patching'dir (version detection + update).
Mitigation¶
Google CVE-2022-20233'ü (Critical olarak rated) June 2022 Pixel
Security Update'inde patchledi. Spesifik key-exfiltration riski için, app'ler
StrongBox key'lerinde setUserAuthenticationRequired(true) çağırabilir, böylece
key kullanılmadan önce biometric/PIN authentication gerekir.