0% found this document useful (0 votes)
87 views54 pages

Unboxyourphone Ekoparty

The document discusses reversing efforts to understand Samsung's TrustZone and T-base microkernel. It explains that the T-base firmware was extracted and contains the microkernel, mcLib library, core trustlets. The microkernel initialization handles SMC calls, maps mcLib and the S0CB trustlet. The S0CB handles the MCP for trustlet loading and IPC. Trustlets use tlApi calls that map to S0CB IPC commands. Efforts focused on understanding the T-base syscall interface, S0CB processes, and trustlet/driver interactions.

Uploaded by

bejay26755
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
87 views54 pages

Unboxyourphone Ekoparty

The document discusses reversing efforts to understand Samsung's TrustZone and T-base microkernel. It explains that the T-base firmware was extracted and contains the microkernel, mcLib library, core trustlets. The microkernel initialization handles SMC calls, maps mcLib and the S0CB trustlet. The S0CB handles the MCP for trustlet loading and IPC. Trustlets use tlApi calls that map to S0CB IPC commands. Efforts focused on understanding the T-base syscall interface, S0CB processes, and trustlet/driver interactions.

Uploaded by

bejay26755
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 54

DANIEL KOMAROMY, EKOPARTY 2017

EXPLORING AND BREAKING


SAMSUNG’S TRUSTZONE SANDBOXES
INTRO
INTRODUCTION
WHY
▸ TrustZone on other platforms
▸ extensively researched
▸ statically found vulnerabilities, straightforward exploitation due to
terrible isolation properties
▸ TrustZone on Samsung
▸ minimal research, until recent work on Trustlets only (P0)
▸ OS complete black box
▸ my main interest: understanding the system
INTRODUCTION
WHAT WE KNOW ABOUT TRUSTZONE AND SAMSUNG KNOX
▸ Trusted Applications provide
services: DRM, KeyStore,
Certificate Management, SPay,
Trusted UI, Trusted PIN, etc.
▸ Trusted Drivers control access
to devices: SPI (Synaptic
Fingerprint Sensor), eSE
(NFC), MST (SPay), etc.
▸ Trusted Drivers add platform
security to Android: Kernel
Measurement, Device
Encryption, etc.
INTRODUCTION
WHAT WE KNOW ABOUT THE TRUSTONIC TEE
▸ microkernel-based OS
▸ SW but NOT EL3 (monitor mode)
▸ MobiCore Control Protocol for nSW to talk
to SW (documented)
▸ Trustonic provides Android {kernel driver,
Daemon, client library} that proxy MCP
commands into Android-level mcXYZ APIs
▸ Trustlet loading format (MCLF), names of
APIs (tlApiXYZ) provided by a common
“libc” fairly well known / previously
researched
▸ Trustlet Connector Interface (TLC/TCI),
aka the protocols for talking to Trustlets:
common TCI header, otherwise entirely
proprietary!
INTRODUCTION
WHAT MAKES TBASE A MICRO KERNEL?
▸ handful of SMC fastcalls only, two that matter:
▸ INIT: Android tells Trustonic location of command queues
▸ NOTIFY: tell Trustonic there is a new command in the queues
▸ everything else is via shared memory, handled by:
▸ MCP (loading/configuring trustlets): ??? but the expectation
is that it is not the kernel itself
▸ Trusted Applications
INTRODUCTION
WHAT WE DON’T KNOW 1.
▸ How is the t-base microkernel implemented?
▸ Where can t-base firmware actually be found on Android?
▸ How does it start up and implement common features (MMU,
process management, etc)
▸ What system calls does it implement?
▸ How/where are SMCs handled? Are the any extra SMC calls
beyond what’s documented?
▸ How/where is the MCP implemented?
INTRODUCTION
WHAT WE DON’T KNOW 2.
▸ Trustlets
▸ How exactly are they loaded? E.g. how is the libc (mcLib)
loaded?
▸ What Trustlet uuid corresponds to what actual (KNOX) feature?
▸ What are the differences between Trustlets and Drivers?
▸ How are tlApi/drApi calls actually implemented, how do they
map to interfaces towards the microkernel?
▸ Security hardening and isolation features in SW?
INTRODUCTION
WHAT WE DON’T KNOW 3.
▸ Android side
▸ What happens beyond libMcClient.so?
▸ What system components actually use TrustZone?
▸ What debugging features are present?
▸ What (if any) attack surface is there for an unprivileged
user?
REVERSING
T-BASE
REVERSE ENGINEERING T-BASE
FIRMWARE EXTRACTION
▸ t-base header embedded inside sboot, identified by “t-base”
▸ gives addresses and sizes of several firmware components:
▸ microkernel
▸ mcLib library
▸ core trustlets (e.g. crypto driver)
▸ the special “dom0” trustlet (MCCB/RTM/S0CB …
whatever :)
REVERSE ENGINEERING T-BASE
FIRMWARE EXTRACTION
REVERSE ENGINEERING T-BASE
FIRMWARE ARCHITECTURE
▸ t-base is connected to nSW by ATF (ARM Trusted Firmware)
▸ https://blog.quarkslab.com/reverse-engineering-
samsung-s6-sboot-part-ii.html awesome explanation of
this monitor mode, read that :)
▸ let’s start from the microkernel initialization and identify:
SMC handling (MC fastcall commands), MCP handling, SVC
handling
▸ hopefully we’ll understand what role the S0CB has
REVERSE ENGINEERING T-BASE
T-BASE MICROKERNEL START UP
▸ loading to ida: start address 0x7F00000
▸ can be figured out based on embedded pointer values, but
also boot logs that can be googled. Prior work also
mentioned this by now (Gal Beniamini)
▸ typical helpers: MCR instructions (setting VBAR, enabling MMU,
etc)
▸ but in any case, it was still pretty painful. lot of things unclear at
first that I was able to come back to when I understood more
about higher layers
REVERSE ENGINEERING T-BASE
T-BASE MICROKERNEL START UP
▸ early steps: pretty typical stuff
▸ configure VBAR, enable MMU, enable cache, reset
various context’s stacks (interrupt, smc, etc)
▸ then starts the t-base specific part
▸ tell ATF where the VBAR is for handling SMC calls
▸ map the mcLib and the S0CB
▸ initialize process structures and start S0CB
REVERSE ENGINEERING T-BASE
T-BASE MICROKERNEL START UP: SMC
▸ ATF needs to know the VBAR, because its SMC handler
uses the offset from there to trap into t-base’s smc/fastcall
handler. From here we can find the SMC handlers, eg
fastcalls:
REVERSE ENGINEERING T-BASE
T-BASE MICROKERNEL START UP: MAP LIB, S0CB
▸ to find where processes are mapped into memory, I had to find the functions
used for managing page table entries
▸ identifying page table operations helped by:
▸ MMU enablement code fixes TTBR0 to a static address, references easy to
see
▸ uses normal AARCH64 two level page table design, so code that e.g.
creates a pte has a pretty easily recognizable look
▸ intuition: it’s readily apparent from the SMC handlers (fastcall and normal)
that there isn’t any implementation of MCP in here, so there HAD to be a
mapping and creation of a new process in the init sequence (this turns out
to be the S0CB).
REVERSE ENGINEERING T-BASE
T-BASE MICROKERNEL START UP: REVERSING HINTS
▸ S0CB header format known, data flow from accesses to it in code can be
followed
▸ matching syscalls made in similar operations in different places, e.g. syscall
made by drApiMapClientBuffer to syscall made by mcMap MCP call, or
functions used by syscall made to start process by mcOpenSession to
functions used by microkernel startup sequence to start S0CB
▸ helpful: 0 heap in microkernel, all descriptors are at fixed locations,
references trivial to see
▸ unlike in the microkernel, Samsung trustlets and drivers have a TON of
debug strings; this helped a lot making sense of meaning of libc calls and
from there figuring out what syscall implements what
REVERSE ENGINEERING T-BASE
T-BASE MICROKERNEL START UP: MAP LIB, S0CB
REVERSE ENGINEERING T-BASE
T-BASE SYSCALLS
REVERSE ENGINEERING T-BASE
REVERSE ENGINEERING SOCB
▸ S0CB is a trustlet also, with (almost) same MCLF loading format
▸ Start-up sequence is pretty complex, as it has to initialize various descriptors for
maintaining state information of trustlet instances and it also has to load initial drivers
(specifically, the crypto driver)
▸ The most important is starting three threads:
▸ MCP handling
▸ IPC handling
▸ Trustlet notification handling
▸ To be able to handle things, S0CB needs to access the MCP and notification queues. It
uses the control syscall (0x1A) to get the address information from the microkernel
and then maps it in for itself.
REVERSE ENGINEERING T-BASE
REVERSE ENGINEERING SOCB: MCP
▸ MCP: we know the
command types and
definitions
▸ Follow OpenSession
command, see how
Trustlets and Drivers are
loaded (permissions,
where shared memory
buffers are put, etc.)
REVERSE ENGINEERING T-BASE
REVERSE ENGINEERING SOCB: IPC
▸ IPC: entirely proprietary, no initial info.
▸ The big help was identifying the tlApi/drApi callers of SVC 0x11,
which gave away which command type is what.
▸ From there, connect more syscall knowledge (e.g. mmap, mprotect
etc) to commands
▸ It was an iterative process, constantly back and forth among
microkernel, S0CB, and trustlets
▸ In total: of 40 IPC commands, I was able to identify the purpose of 30
REVERSE ENGINEERING T-BASE
REVERSE ENGINEERING SOCB: IPC
REVERSE ENGINEERING T-BASE
REVERSE ENGINEERING SOCB: TRUSTLET NOTIFY
TRUSTLETS
REVERSE ENGINEERING T-BASE
TRUSTLETS AND DRIVERS
▸ similarities and differences
▸ all depends on tlApi and drApi calls
▸ Trustlet behavior: single threaded; input from WSM tciBuf, tlApi_callDriver if driver needed
▸ Driver behavior: often multi threaded (handle IRQs from devices)
▸ input from drApiIpcCallToIPCH: command type + length + initial command pointer
▸ passed in arguments (marshalled from tlApi_callDriver by S0CB)
▸ then map in Trustlet memory to read actual command buffer(s) using more drApi calls
that map to S0CB IPC commands
▸ so, the comm. b/w trustlets&drivers is marshalled by the previously seen S0CB
▸ no “MAC” on IPCs at all; up to drivers to filter callers for commands based on caller uuid
REVERSE ENGINEERING T-BASE
LABELING TLLIB APIS
▸ Prior art + strings in Samsung TAs covered most tlApis, but few
drApis; additional reversing of secure drivers helped fill in the gaps
▸ “GOT” approach is really trivial: one field in trustlet/driver headers
gets filled in with tlLib address at load time; all library calls simply
call to this address with R0 holding the API id
▸ Luckily, all such calls go through small stub functions, so we can
label these nicely in the code.
▸ Wrote a script to automatically label the APIs in a trustlet/driver
binary, to aid reverse engineering
REVERSE ENGINEERING T-BASE
LABELING TLLIB APIS
REVERSE ENGINEERING T-BASE
TRUSTLETS AND DRIVERS
▸ 0006…: Widewine trustlet (drm)
▸ 0701…: TlCm (certificate management) trustelt
▸ 0706…:TEE keymaster trustlet
▸ 0813…: TEE gatekeeper trustlet
▸ f…5: HDCP trustlet (drm)
▸ f…a: TIMA PKM trustlet
▸ f…b: TIMA LKM Auth trustlet
▸ f…c: Key Management trustlet
▸ f…d: ?
▸ f…e: Synaptics Fingerprint trustlet
▸ f…f: TIMA attestation trustlet
REVERSE ENGINEERING T-BASE
TRUSTLETS AND DRIVERS
▸ f…12: CCM trustlet
▸ f…13: Keystore trustlet
▸ f…14: TUI trustlet
▸ f…16: SKMM trsutlet (Secure Key Management Module, used by SPay trustlets)
▸ f…17: MLDAP trustlet (knox mdm integration https://www.samsungknox.com/en/solutions/knox-workspace/on-
premise-mdm-integration)
▸ f…19: Dmverity trustlet
▸ f…1e: OTP trustlet
▸ f…1f: FIDO trustlet
▸ f…2e: Fingerprint trustlet
▸ f…38: ESECOMM trustlet
▸ f…3e: TEE Keymaster
▸ f…41: ICCC
REVERSE ENGINEERING T-BASE
TRUSTLETS AND DRIVERS
▸ f…1c: VISA Pay
▸ f…21: Mastercard Pay
▸ f…27: PLCC Pay
▸ f…28: KRCC Pay
▸ f…31: Discovery Pay
▸ f…3a: CHNCMM Pay
▸ f…33: JIC Pay
▸ f…32: CNCC Pay
▸ f…39: EURCOMM Pay
REVERSE ENGINEERING T-BASE
TRUSTLETS AND DRIVERS
▸ ffffff0….1: SRPMB driver
▸ ffffffd….4: Crypto driver
▸ ffffffd….a: TIMA driver
▸ ffffffd….e: SEC SPI driver #1 (fingerprint sensor)
▸ ffffffd….14: TUI driver
▸ ffffffd….17: SEC SPI driver #2 (eSE)
TLC IN ANDROID
REVERSE ENGINEERING T-BASE
T-BASE AND ANDROID
▸ Debugging info in filesystem?
▸ /system/bin/tima_dump_log
/system/tima_measurement_info (attestation)
/system/kern_sec_info{1|2|3|4] (pkm)
/proc/tima_secure_log
/proc/tima_secure_rkp_log
/proc/tima_debug_log
/proc/tima_debug_rkp_log (rkp)
/sys/kernel/debug/trustonic_tee/*
/proc/sec_log
REVERSE ENGINEERING T-BASE
T-BASE AND ANDROID
▸ Looking around
▸ strings -f * | grep onTransact
strings -f * | grep mcNotify
▸ lib names in /system/lib64/ & /system/vendor/lib64 with
“tlc”
▸ service list | grep {com.sec,finger,keystore} etc.
▸ finally, settled on tlc_server. Exposes access to certain
trustlets via Binder. (ESECOMM, CCM, DCM, TUI)
REVERSE ENGINEERING T-BASE
TLC SERVER
▸ one instance started for each TA (CCM, DCM, TUI,
ESECOMM, PUF)
▸ uses dlopen/dlsym to get comm_data initialization
function, e.g. esecomm_get_comm_data in
libtlc_tz_esecomm.so; this identifies trustlet to load
▸ registers binder service, handler a simple switch of
commands: OPEN, CLOSE, COMM, COMM_VIA_ASHMEM
REVERSE ENGINEERING T-BASE
TLC SERVER
▸ OPENSWCONN: create_comm_cxt()
▸ COMM, COMM_VIA_ASHMEM: parse arguments out of Binder
parcel and send via libMcClient.so
▸ COMM: uses SEAMS to validate caller based on SEAndroid policy
▸ COMM_VIA_ASHMEM: no authentication! COMPLETELY OPEN
VULNERABILITIES
VULNERABILITY RESEARCH
ATTACK SURFACES
▸ unpriviliged Android > TLC
▸ privileged Android > Trustlet (tci)
▸ privileged Android > IPCH (MCP implementation)
▸ privileged Android > tbase kernel (SMC)
▸ privileged Android > custom tbase fastcalls (SMC) and ATF SMCs
▸ Trustlet > Driver (IPC)
▸ Trustlet > tbase kernel (SVC)
▸ Trustlet > IPCH (IPC)
VULNERABILITY RESEARCH
FOUND VULNERABILITIES
▸ Authentication bypass in tlc_server
▸ Memory corruption in tlc_server
▸ Plenty of memory corruption vulnerabilities in trustlets (buffer
overflows, arbitrary writes, integer overflow-to-buffer overflows)
▸ Session hijack logic vulnerability in CCM Trustlet
▸ Memory corruption and race condition vulnerabilities in TIMA driver
▸ Feature abuse in TIMA driver leading to arbitrary Android kernel
read (KASLR bypass)
VULNERABILITY RESEARCH
STACK BOF IN ESECOMM
▸ ESECOMM: implements interface to eSE (NFC enabled for Samsung Pay)
▸ smart card communication: ISO7816
▸ http://www.cardwerk.com/smartcards/
smartcard_standard_ISO7816-4_4_abrev_and_notation.aspx
▸ Uses SEC SPI driver to talk to eSE
▸ SPI driver: there is also a Linux kernel driver (see /drivers/spi/spi-s3c64xx.c), this
explains meaning of memory mapped I/O
▸ Implements “SCP03 Global Platform Secure Channel Protocol”
▸ http://csrc.nist.gov/groups/ST/ssr2016/documents/presentation-mon-traore.pdf
▸ uses an APDU based protocol with TLV parameters to set up secure channel
cryptographic information (Diffie-Hellman keys)
VULNERABILITY RESEARCH
STACK BOF IN ESECOMM
signed int __fastcall process_ScpInstallCaCert(tci_msg_add_ca_payload_t *reqmsg, tci_rsp_payload_t *rspmsg)
{
tci_msg_add_ca_payload_t *reqmsg_; // r4@1
tci_rsp_payload_t *rspmsg_; // r5@1
char *reqmsg_payload_; // r7@1
signed int result; // r0@2
char pubkey[512]; // [sp+Ch] [bp-244h]@2
char caid[32]; // [sp+20Ch] [bp-44h]@2
char curveid; // [sp+22Ch] [bp-24h]@2
int pubkey_len; // [sp+230h] [bp-20h]@2
unsigned int caid_len; // [sp+234h] [bp-1Ch]@2
reqmsg_ = reqmsg;
rspmsg_ = rspmsg;
reqmsg_payload_ = reqmsg->payload;
if ( validate_input_len(reqmsg->payload, reqmsg->total_len, reqmsg->payload, (char *)&reqmsg->total_len) ) //
ONLY verifies the total input len, not related to TLV lengths
{
result = parse_ca_cert(reqmsg_payload_, reqmsg_->total_len, caid, (int *)&caid_len, &curveid, pubkey,
&pubkey_len);
(…)
VULNERABILITY RESEARCH
STACK BOF IN ESECOMM
signed int __fastcall parse_ca_cert(char *msg_payload, int total_req_payload_len, void *caid, int *caid_len, char *curveid,
void *pubkey_buf, int *pubkey_buf_len)
{
(…)
v7 = msg_payload;
total_req_payload_len_ = total_req_payload_len;
caid_ = caid;
v10 = caid_len;
v11 = -1;
memset_to_0(&out_buf, 0x44u);
if ( parse_tlvs_from_APDU(&out_buf, v7, 0, total_req_payload_len_) < 0 )
{
snprintf(logbuffer, 119, "%s:%d :: Error, %s\n", "parse_ca_cert", 73, "failed to parse TLV");
logbuffer[119] = 0;
tlApiLogPrintf_0("%s\n", logbuffer);
return 3;
}
tlv_caid = find_tlv_obj_in_parsed_tlvs(&out_buf, (char *)&caid_tag_value);
tlv_caid_ = tlv_caid;
if ( tlv_caid )
{
memcpy_w(caid_, &tlv_caid->tlv_value_OR_num_extra_tlvs, tlv_caid->tlv_length);
VULNERABILITY RESEARCH
CCM SESSION HIJACK
▸ CCM: Client Certificate Management
▸ supposed to secure private certs, basically
▸ https://seap.samsung.com/api-references/android-
premium/reference/com/sec/enterprise/knox/ccm/
TZ_CCM_PKCS11_Guide.pdf
▸ Keys never leave TZ, CCM is an encryption/decryption oracle.
▸ To secure this, at CA install time certs are secured with some
authentication method (password, TUI)
VULNERABILITY RESEARCH
CCM SESSION HIJACK
▸ So, how does login exactly work?
▸ First, session must be opened with C_OpenSession
▸ 64 bit random session id generated
▸ Then, session must login, using C_Login
▸ pass session id to identify session
▸ if successful, session->logged_in bit flipped
▸ After this, until C_CloseSession, all operations will be allowed where
session id matches
VULNERABILITY RESEARCH
CCM SESSION HIJACK
▸ That creates a race condition window:
▸ IF legitimate user logs a session in,
▸ ANYBODY can impersonate the session that knows the
session id
▸ 64 bit randomness from crypto engine though, so that
seems solid
▸ Except…
VULNERABILITY RESEARCH
CCM SESSION HIJACK
▸ The session ids are printed into the /proc/sec_log …
▸ Even if an app context would be restricted: the actual
secure log implementation is the same buffer for ALL
trustlets: by hijacking ESECOMM, we can read the sec_log
even if we can’t read /proc/sec_log itself b/c of SEAndroid
VULNERABILITY RESEARCH
TIMA DRIVER KASLR BYPASS
▸ Once we hijack ESECOMM, we can talk to the TIMA driver
▸ Implements many different things:
▸ TIMA measurement golden copy area read/write (trustlets use this to
verify/set warranty info)
▸ nSW kernel hashing (for TIMA PKM) (every UUID!)
▸ MST driver (for Samsung Pay) (only whitelisted UUIDs)
▸ SCrypto (a full openSSL stack based FIPS compliant crypto library… in
addition to the Crypto Driver, hmmm.) (every UUID!)
▸ modify UUID whitelists (restricted to CNCC trustlet)
VULNERABILITY RESEARCH
TIMA DRIVER KASLR BYPASS
▸ measurement info read/write:
▸ this would allow arbitrary physical address read/write
▸ Gal Beniamini described this
▸ however, in practice, range checks limit what can be
written to the intended areas
▸ Nonetheless - you could STILL replace the golden
measurement/warranty info (don’t try this at home…)
VULNERABILITY RESEARCH
TIMA DRIVER KASLR BYPASS
VULNERABILITY RESEARCH
TIMA DRIVER KASLR BYPASS
▸ What’s left in TIMA?
▸ SCrypto: I actually found several memory corruption vulnerabilities in
here. Disclosure not finished yet.
▸ PKM MD5 hashing command
▸ Hash command is open to all UUIDs! (Should have been restricted to TIMA
PKM trustlet)
▸ address range allows all of physical memory within which nSW lives
▸ to break Android KASLR: invoke from hijacked ESECOMM to hash
first page of kernel physical address space: this is an empty page
with just the value of the KASLR slide in it
▸ from the hash, it is a <32 bit bruteforce to recover the slide.
SUMMARY
TAKEAWAYS
▸ even an almost entirely black box TEE OS implementation can be reversed fairly
comprehensively
▸ t-base architecture solid for isolation, but lacks modern exploit mitigations
▸ driver api design less susceptible to exploitability of input parsing memory
corruption vulns, much worse for trustlets
▸ still, architecture should find a way to sandbox secure drivers, e.g. filter what
areas can be mapped by drivers, what drivers can make fastcalls etc.
▸ improve driver whitelists for allowed commands!
▸ altogether, t-base provides a huge attack surface to an elevated Android privilege
context and it does not help vendors to eliminate or deal with unprivileged
Android attack surface
TEXT
QUESTIONS?

You might also like