0% found this document useful (0 votes)
538 views61 pages

D2 - Launching Feedback-Driven Fuzzing On TrustZone TEE - Andrey Akimov

- The document discusses Trustonic Kinibi, which is the TEE operating system used in Samsung Galaxy devices from the S3 to S9. - It describes the architecture and usage of ARM TrustZone technology in these devices, including the separation of the device into normal and secure worlds. - Key components of the Trustonic Kinibi TEE implementation are outlined, such as the secure boot process, trusted applications, inter-world communication mechanisms, and fuzzing efforts to find vulnerabilities.

Uploaded by

Knife Fish
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)
538 views61 pages

D2 - Launching Feedback-Driven Fuzzing On TrustZone TEE - Andrey Akimov

- The document discusses Trustonic Kinibi, which is the TEE operating system used in Samsung Galaxy devices from the S3 to S9. - It describes the architecture and usage of ARM TrustZone technology in these devices, including the separation of the device into normal and secure worlds. - Key components of the Trustonic Kinibi TEE implementation are outlined, such as the secure boot process, trusted applications, inter-world communication mechanisms, and fuzzing efforts to find vulnerabilities.

Uploaded by

Knife Fish
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/ 61

HITB GSEC 2019 Singapore

Launching feedback-driven fuzzing


on TrustZone TEE
Andrey Akimov,
security researcher
Agenda

• Samsung S8 usage of ARM TrustZone – Trustonic Kinibi


• Searching for attack target
• Exploring TrustZone implementation
• Trusted applications
• Fuzzing
• Crash analysis
• Results
• Exploitation of SVE-2019-14126

3
ARM TrustZone
Usage

• Corporate services • Hardware secure storage


• Content management • Authentication, biometrics
• Personal data protection • Hardware cryptographic engine

• Connectivity protection • Digital Rights Management (DRM)


• Protecting and monitoring of the Normal World by
• Mobile financial services the Secure World
• Real-Time Kernel Protection (RKP)
• Periodic Kernel Measurement (PKM)
• Trusted user interface

4
Trustonic Kinibi
TEE operating system

• Ex. G&D mobicore, <t-base


• Samsung Exynos SoCs: Galaxy S3 to Galaxy S9 – Trustonic Kinibi
• Samsung Galaxy S10 – Samsung Teegris
• github: trustonic-tee-user-space
• github: trustonic-tee-driver
• Old Qualcomm leak with Trustonic Kinibi SDK qcom_leaked_sources.zip
• secure world headers
• secure world static libraries
• documentation
• etc.

5
Trustonic Kinibi
Normal World and Secure World

Architecture Developer’s view

6
Normal World
Exploring Android file system
Trustonic Kinibi
Client applications

• Keymaster
• access to key information
• Fingerprintd Fingerprintd
• biometrics Keymaster

• Samsung Pay
• …

8
Trustonic Kinibi
Trusted application connector

• Native libraries
• libtlcotp.so
• libtlc_direct_comm.so
• …
• Binder /system/bin/tlc_server
libtlcotp.so
• /system/bin/tlc_server – access to
trustlets via Binder interface TuiService.apk
RootPA.apk
• TuiService.apk – access to TUI
• Service provider provisioning agent
• Root provisioning agent
• RootPA.apk – gd.mobicore.pa

9
Trustonic Kinibi
Client API

• /system/vendor/lib64/libMcClient.so – trustlet
communication
• mcOpenSession
• mcMallocWsm
• mcNotify
• …
• /system/vendor/lib64/libMcRegistry.so –
registry management libMcRegistry.so
• mcRegistryStoreAuthToken libMcClient.so
• mcRegistryStoreSp
• …

10
Trustonic Kinibi
Daemon

• /system/vendor/bin/mcDriverDaemon
• Communicates through @mcdaemon socket
• SELinux
• u:object_r:mobicoredaemon_exec:s0

@mcdaemon

mcDriverDaemon

11
Trustonic Kinibi
Kernel components

• Official open source Android kernel


• Community builds
• TGP Kernel
• Xceed
• BatStock-Kernel V1.8.0
• …
• make menuconfig
• TrustZone related kernel components
• Trustonic TEE Driver
• triggers SMC to switch CPU to Secure World

12
Trustonic Kinibi
Kernel components

• Main kernel entry points


• /dev/mobicore – administration tasks
• /dev/mobicore-user – client application –
trusted application communication
• /dev/t-base-tui – trusted user interface
• SELinux enforced
• u:object_r:mobicore_device:s0
• u:object_r:mobicore_user_device:s0
• u:object_r:tui_device:s0

mobicore-user

mobicore t-base-tui

13
Secure World
Exploring binary images
Trustonic Kinibi
Secure World

• sboot.bin
• Fernand Lone Sang – Reverse Engineering Samsung S6 SBOOT
• Alexander Tarasikov – Reverse-engineering Samsung Exynos 9820 bootloader and TZ

+---Firmware----------------------------+
+-+ G950FXXU3CRGH_G950FOXM3CRGH_SER.zip |
| +---------------------------------------+
|
| +---Firmware content------------------------------------------------------------+
+--->+ AP_G950FXXU3CRGH_CL14023573_QB19093103_REV00_user_low_ship_meta.tar.md5 |
+-+ BL_G950FXXU3CRGH_CL14023573_QB19093103_REV00_user_low_ship.tar.md5 |
| | CP_G950FXXU3CRGH_CP10267592_CL14023573_QB19093103_REV00_user_low_ship.tar.md5 |
| | CSC_OXM_G950FOXM3CRGH_CL14023573_QB19093103_REV00_user_low_ship.tar.md5 |
| | HOME_CSC_OXM_G950FOXM3CRGH_CL14023573_QB19093103_REV00_user_low_ship.tar.md5 |
| +-------------------------------------------------------------------------------+
|
| +--BL_G950FXXU3CRGH...--+
+--->+ cm.bin.lz4 |
| param.bin.lz4 |
+-+ sboot.bin.lz4 |
| | up_param.bin.lz4 |
| +-----------------------+
|
+-------------------------------------------------------------------------------------->
15
Trustonic Kinibi
S-Boot

• Based on ARM Trusted Firmware (now Trusted Firmware-A)


• Secondary bootloader – AP_BL2
• EL3 Monitor – AP_BL31
• Secure EL-1 Payload – AP_BL32
• U-boot – AP_BL33

+--sboot.bin-----------+
+--> Secondary Bootloader |
| EL3 Monitor |
+-+ Secure EL-1 Payload |
| | Non-secure Payload |
| +----------------------+
|
+---------------------------->

16
Trustonic Kinibi
Secure EL-1 Payload

• Contains most parts of TEE

+--Secure EL-1 Payload--+


+--> MTK |
| RTM |
| mclib |
| TAs |
| TDs |
+-----------------------+

17
Trustonic Kinibi
Secure EL-1 Payload

• Kinibi kernel – MTK


• Runtime manager – RTM
• Some trusted drivers – drcrypto, …
• Some trusted applications – STH2, …
• Internal API library - mclib
mclib

drcrypto
RTM

MTK

18
Trustonic Kinibi
Trustlets

• Trusted applications - TA, CM system TA, SP TAs


• Reside in Android file system
• Identified by GUID
GUID_3
GUID_1
GUID_2

19
Trustonic Kinibi
Inter-world communication

20
Trustonic Kinibi
Inter-world communication flow

21
Trustonic Kinibi
Trustlets

• MobiCore Load Format – MCLF


• github: mcLoadFormat.h
• IDA Pro loader
• Ghidra loader
• Signed binaries
• 32-bit executables
• Uninitialized fields
• tciBuffer_ptr
• tciBuffer_len
• mcLibEntry
• …
• Internal API via mclib

22
Zoom in

• All external calls are through mclib entry field in MCLF header
• Easy to emulate such an isolated code
• Easy to wrap in fuzzing environment

23
Fuzz smartly
AFL
Fuzz smartly

• Straightforward approach
• Fuzz trustlets from Normal World
• Non-controlled environment
• No coverage control
• No crash information
• Smart approach
• Controlled environment
• Control fuzzing coverage
• All crash information
• Explore crashes with all tools

25
Fuzz smartly
AFL

• AFL fuzzes applications


• source code – afl-gcc
• binary code – afl-unicorn
• executables – qemu usermode
• AFL mutates standard input (--) or file input (@@)

• Use AFL qemu usermode


• Convert MCLF trustlet to ELF executable
• Make a wrapper to forward standard input to the trustlet TCI
• Fuzz it with qemu mode!

26
Binary porting
Transform a trustlet to a linux application

• Make an initial stub to forward input


• Make an ELF with initial stub and trustlet
• Relocate trustlet image properly
• Transfer execution to the trustlet entry point
• Mock mclib
• Automate it for all trustlets

27
Binary porting
Call TA’s entry point

• Make an initial stub code


• Define symbols
• tciBuffer_ptr
• tciBuffer_len
• tlMain

// tlrun.c

tciBuffer = malloc(TCILEN); // get memory for TCI buffer


tciBufferLen = read(STDIN_FILENO, tciBuffer, TCILEN); // fill it from standard input

*(int*)sym_tciBuffer = tciBuffer; // fill in the fields in the trustlet's header


*(int*)sym_tciBufferLen = tciBufferLen;

tlMain_t tlmain = (tlMain_t)&sym_tlMain; // get tlMain address from symbols


tlmain(tciBuffer, tciBufferLen); // call tlMain

28
Binary porting
Relocating TA properly

• Compile our stub


• gcc –c tlrun.c –o tlrun.o
• Define symbols
• objcopy --add-symbol tlMain=$(TLMAIN)
• Adding sections
• objcopy --add-section .tlbin_text=.text.bin \
--set-section-flags .tlbin_text=code,contents,alloc,load \
tlrun.o tlrun.o.1
• Locating sections
• gcc tlrun.o.1 --section-start=.tlbin_text=0x1000 –o tlrun

29
Binary porting
Implement mclib API

• TlApi.h
• TlApiCom.h _TLAPI_EXTERN_C tlApiResult_t tlApiUnwrapObjectExt(
void *src,
• TlApiCommon.h
size_t srcLen,
• TlApiCrypto.h void *dest,
• TlApiError.h size_t *destLen,
uint32_t flags );
• TlApiHeap.h
• TlApiLogging.h
• TlApiMcSystem.h
_TLAPI_EXTERN_C void tlApiLogPrintf(
• TlApiSecurity.h const char *fmt,
• TlApiTime.h ...);
• TlApiTplay.h
• TlApiTui.h

30
Binary porting
Implement mclib dispatch

• Dispatch function
• tlApiLibEntry // entry.S

// tlrun.c .syntax unified


.arch armv7a
typedef void (*tlApiEntry_t)(int num); .globl tlApiEntry
tlApiEntry:
void (*tlApiLibEntry)(int num) __attribute__((weak)); push {r0-r4,lr}
void tlApiEntry(int num) __attribute__((noplt));
bl get_api
__attribute__((constructor)) void init() mov r12, r0
{ pop {r0}
tlApiLibEntry = tlApiEntry; pop {r0-r3,lr}
} bx r12

// tllib.c

void* get_api(int num)


{
return ptrs[num];
}
31
Binary porting
Automation for multiple TAs

• Trustlet porting parameters • Trustlet entry point


• Entry point • objcopy --add-symbol tlMain=$(TLMAIN)
• Sections locations • Sections locations
• TCI buffer length • gcc tlrun.o.1 --section-
start=.tlbin_data=$(TLDATA) –o tlrun
• Old good Makefiles
• TCI buffer length
• gcc -DTCILEN=$(TLTCI_LEN) –c tlrun.c –o
tlrun.o

32
Binary porting
Automation for multiple TAs

rem ida_auto.bat
• IDA Pro
• batch mode for /r %%f in (*.idb) do (
idascript %%f %TOOLDIR%\tlinfo.py
• Idascript )
• Ghidra
# tlinfo.py
• Headless mode
def info_segments():
ss = dict()
for s in Segments():
name = idc.get_segm_name(s)
segs.update({name: [s, idc.get_segm_end(s)]})
return segs

if __name__ == "__main__":
try:
kinibi_api.main()
print "TLMAIN := 0x%x" % (locate_tlmain() + 1)
ss = info_segments()
env_names = {".text": "TLTEXT",
".data": "TLDATA",
".bss": "TLBSS"}
33
Binary porting
Launch

~ # ./tlrun < test

34
Fuzzing
Poexali!
Fuzzing
Hardships

• QEMU and AFL QEMU patches issues


• toolchain
• AFL instrumentation issues
• Study AFL thoroughly

36
Fuzzing
It works!

37
Gathering crashes

23 trustlets – 477 crashes

afl-cmin – 225 unique cases

38
Crash analysis
Crash analysis

• Get to ARM machine


• Dynamic analysis
• Gdb scripts
• Dynamic Binary Instrumentation
• DynamoRIO
• Valgrind
• Symbolic execution
• angr

40
Crash analysis

• gdb crash analyzer


• poor information
• DynamoRIO
• cannot load so specifically constructed file
• Valgrind
• callgrind
• memcheck
• not for automatic parsing
• angr
• error-prone, time-consuming

• gdb is the only friend

41
Crash analysis

• gdb scripts
# catch.py
• Make more logging from our mclib
def handler_stop(event):
• Build SQLite database if isinstance(event, gdb.SignalEvent):
# stub.gdb print "%s at %s" % (event.stop_signal,
hex(int(gdb.parse_and_eval("$pc").cast(gdb.lookup_type("int"
set logging on )))))
set logging redirect on
target remote :5555 def handler_exit(event):
source catch.py print "================================"
continue gdb.execute("quit")
# analyze.sh

for f in $(ls $1/out/crashes)


do
echo === $f === | tee -a gdb.txt
../afl-qemu-trace -L /usr/arm-linux-gnueabi/ -g 5555 $1/tlrun < $1/out/crashes/$f 1>/dev/null 2>/dev/null
2>/dev/null &
arm-none-eabi-gdb -x stub.gdb -batch 2>/dev/null
tail -n 2 gdb.txt
../afl-qemu-trace -L /usr/arm-linux-gnueabi/ $1/tlrun < $1/out/crashes/$f > /tmp/1.qemu
done
42
Crash analysis

• Non-trivial functions
• tlApiSecSPICmd
• tlApi_callDriver
• tlApiWrapObjectExt
• tlApiUnWrapObjectExt
• …

• Exclude such cases


• Implement and get more accurate fuzzing results

43
Crash analysis

~ # sqlite3 analyze-cmin.db ‘select * from main’ | grep –v tlApiSecSPICmd

44
Results

• https://security.samsungmobile.com/securityUpdate.smsb
• SVE-2019-13958
• SVE-2019-14126

45
SVE-2019-14126
Heap overflow in keymaster trusted application
SVE-2019-14126
Root cause

• Parsing DER-encoded ASN.1


• malloc – size 1 – little endian
• memcpy – size 2 – big endian

TCI buffer
SVE-2019-14126
Security mitigations

• Trusted applications
• Per TA virtual memory
• Unable to access kernel or physical memory
• Divided into sections with different memory attributes
• TCI buffers are non-executable
• No ASLR
• only in future plans (Adding ASLR to a microkernel-based operating system)

48
SVE-2019-14126
Exploitation overview

• Strategy
1. Find a function pointer in .bss;
2. Relocate a heap chunk before the pointer;
3. Trigger memory allocation and copying at this chunk to overwrite the pointer;
4. Call overwritten pointer.
• Heap exploitation in Kinibi
• Eloi Sanfelix - TEE Exploitation

49
SVE-2019-14126
Relocating heap

• Brute force
• In heap
• create a fake chunk, pointing to .bss
• In .bss
• create one more fake chunk, pointing to itself
• next allocations loop infinitely?
• Yes – suitable address
• No, the trustlet crashed – the relocation failed

50
SVE-2019-14126
Relocating heap

• Brute force + passing the execution demo

51
SVE-2019-14126
Exploitation

• What we have
• Calling an arbitrary executable code
• No chances to execute a shellcode
• Code-reuse is possible
• Canaries in the stack

52
SVE-2019-14126
Exploitation

• JOP (Jump Oriented Programming)

ROP gadget ROP gadget JOP gadget

53
SVE-2019-14126
Exploitation

• ROPgadget --binary tlrun --thumb --range 0x1000-0xbeb44


• grep -E "; b.+ r[0-9]+$"

54
SVE-2019-14126
Exploitation

• JOP (Jump Oriented Programming)


• Jump table in memory
• One super gadget as a dispatcher

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0068b/BABEFCIB.html 55
SVE-2019-14126
Exploitation

• ROPgadget --binary tlrun --thumb --range 0x1000-0xbeb44


• grep -E "; b.+ r[0-9]+$"
• grep –E “ldm..”

56
SVE-2019-14126
Breaking keymaster

• Demo

57
SVE-2019-14126
Breaking keymaster

• Demo
• Break Android FDE through keymaster
• Extracting Qualcomm's KeyMaster Keys - Breaking Android Full Disk Encryption
• Post-Exploitation
• Escalate to Trusted Drivers
• Escalate to TEE kernel
• Escalate to EL3 Monitor
• Do anything you want

58
Conclusion

• Porting a binary to get all available toolset


• Easy
• Portable
• Fuzzing with AFL qemu mode
• Fast
• Reliable
• Exploiting vulnerabilities in Kinibi trustlets
• No ASLR
• A starting point for pwning TrustZone
• One more way to pwn Android kernel

59
Useful links

• Reverse Engineering Samsung S6 SBOOT


• Unbox Your Phone
• Trust Issues: Exploiting TrustZone TEEs
• TEE Exploitation: Exploiting Trusted Apps on Samsung’s TEE at Zer0con 2019
• BREAKING SAMSUNG'S ARM TRUSTZONE at BlackHat USA 2019
• Reverse-engineering Samsung Exynos 9820 bootloader and TZ

60
Thanks for your attention!
Andrey Akimov,
security researcher
tg: @e13fter

29 Krasnogo Kursanta st., building 2, Saint Petersburg DSecRU

You might also like