Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

22-Hexacon-Hara-Kirin Dissecting The Privileged Components of Huawei Mobile Devices

Download as pdf or txt
Download as pdf or txt
You are on page 1of 75

Hexacon 2022

About Us

Maxime Peterlin – @lyte__

Security researcher & Co-founder

Alexandre Adamski – @NeatMonster_

Security researcher & Co-founder

Impalabs – @the_impalabs

French offensive security company

Reverse engineering, vulnerability research, exploit development

Website – https://impalabs.com

Blog – https://blog.impalabs.com
Outline

Introduction
Introduction

Bootchain
Bootchain

Hypervisor
Hypervisor

Secure
SecureMonitor
Monitor

Secure
SecureKernel
Kernel

Trusted
TrustedOS
OS

Trusted
TrustedApplications
Applications

Conclusion
Conclusion
Introduction
Android Device Architecture
Kernel-Based Security

# Access control to resources from NORMAL WORLD

user space is enforced by the kernel


PROC PROC PROC

• Address space isolation SVC

• Preemptive multitasking KERNEL

• Peripherals access restriction

# Single point of failure

• Breaching kernel defenses results

in full system compromise


Android Device Architecture
Security Hypervisor

# CPU virtualization
NORMAL WORLD
• Traditionally used to execute multiple operating

systems in parallel on the same device


PROC PROC PROC

• Leveraged on Android devices to enhance


SVC

system security instead

KERNEL
# ARM virtualization extensions


HVC

Additional privilege level


HYPERVISOR
Memory access restrictions

• Exceptions interception

# Protects critical data structures at run time

• Credentials, security contexts, page tables, etc.


Android Device Architecture
TrustZone for Cortex-A

# System-wide hardware separation

NORMAL WORLD SECURE WORLD


• An untrusted Normal World and a trusted

Secure World
PROC PROC PROC APP APP APP

• Access to secure hardware resources from

non-secure software is prohibited


SVC SVC

• Inter-world communications through the KERNEL SECURE KERNEL

Secure Monitor
HVC

# TrustZone and Secure Boot are used to create a HYPERVISOR

Trusted Execution Environment (TEE)


SMC SMC

Authentication (e.g. for encrypted filesystem)

• Mobile payment, secrets management, etc. SECURE MONITOR

• Content management (DRM)


Android Device Architecture
Secure Boot

# Each stage cryptographically checks that the

next image is authorized to run


BOOTROM

• Creates a chain of trust Loads from UFS, Loads from USB,


verifies & executes verifies & executes

Starting from the root of trust, an immutable


component LOADER #1 USB LOADER

# Prevents unauthorized or modified software from

executing on the device

#
LOADER #N
OEMs implement additional features

• Anti-rollback mechanism

• Emergency boot over USB KERNEL HYPERVISOR TRUSTZONE

• Boot images encryption


Boot Chain
Boot Chain
Overview

# Security mechanisms

BOOTROM
• Secure boot: prevents replacing or modifying

boot chain images LPMCU


(Cortex-M)
Bootloader lock: prevents reflashing the

partitions or running a custom kernel


XLOADER

# Bootstrapping challenges

• All critical partitions are encrypted

• Can’t talk directly to targeted components


FASTBOOT

• Countermeasures in kernel and userland


ACPU

#
(Cortex-A)
Getting control over the boot chain

• High entry cost: we need to find a KERNEL

vulnerability first
Boot Chain
First Research Device

# P30 Lite (Kirin 710 chipset)


BOOTROM

• Xloader is signed but not encrypted, thus

can be retrieved from a firmware update

• Found a vulnerability in its


XLOADER
implementation of xmodem, the USB
recovery protocol

The next stage binary’s base address is

not verified
FASTBOOT

Can be leveraged to modify Xloader

itself (all memory is RWX)

Shorting a test point on the device


KERNEL
activates the download mode feature
Boot Chain
Second Research Device

# P40 Lite (Kirin 810 chipset) BOOTROM

• Xloader is signed and encrypted

• But it is also affected by the


XLOADER
xmodem vulnerability that needs to
be exploited blindly

• Decryption key no longer stored in


FASTBOOT
fuses and is only accessible to the

crypto engine

Firmware images are retrieved


KERNEL
by using the device as an oracle
Boot Chain
Third Research Device

BOOTROM

# P40 Pro (Kirin 990 chipset)

• Xloader is signed, encrypted,

but not vulnerable to the XLOADER

xmodem bug
• Fastboot is split into a privileged

and an unprivileged component FB BL2

• Another vulnerability is needed

to get control over the boot chain


KERNEL
Boot Chain
How to Tame Your Unicorn

# Talk presented at BlackHat USA 2021 by Taszk Security Labs


• Revealed multiple Xloader and BootROM bugs

• Including the Xloader vulnerability that we had discovered

# CVE-2021-22434: Head Chunk Resend State Machine Confusion

• Internal state is not reset when sending an incorrect payload address

• BootROM code execution can be achieved from this arbitrary write primitive

• Must be exploited blindly on the Kirin 990 chipset

Dump Xloader using the Flash Patch and Breakpoint unit of the LPMCU

# Huawei “fixed” the BootROM bugs by burning a fuse to disable the USB recovery mode
Boot Chain
Continuation of Execution

Steps Steps

# Send patched Xloader to the # Send patched Fastboot to

BootROM Xloader

# Force its execution by # Patches allow execution to

overwriting a return address continue normally

BOOTROM XLOADER FASTBOOT

Patches Patches

# Remove the address # Change boot mode from

and length checks USB to UFS

# Disable decryption and # Ignore the Android Verified

signature verification Boot failure

# Similarly to “CHECKM30” presented at MOSEC 2021 by Pangu Team


Security Hypervisor
Security Hypervisor
Introduction

# Called Huawei Hypervisor Execution Environment (HHEE)


CODE CODE CODE CODE CODE CODE CODE CODE

• Similar to uH/RKP on Samsung’s Exynos or QHEE on


RO RO RO RO

Qualcomm’s Snapdragon
CODE CODE CODE CODE
DATA DATA DATA DATA

PAGE PAGE PAGE UID ADDR

# Main Security Features


SELINUX SELINUX SELINUX
TABLE TABLE TABLE GID LIMIT

Kernel

• Prevents arbitrary changes to the kernel read-only data,


DATA DATA DATA DATA DATA DATA DATA DATA

its page tables, SELinux structures, etc.


DATA DATA DATA DATA DATA DATA DATA DATA

• Keeps a read-only copy of tasks’ information to detect


DATA DATA DATA DATA DATA DATA DATA DATA

privilege escalation on the next syscall or file access


RO RO

Ensures only the pages belonging to the kernel and


CODE CODE CODE CODE CODE CODE
DATA DATA

Module
modules code segment can be executed at EL1
DATA DATA DATA DATA DATA DATA DATA DATA

• Makes critical physical memory regions (e.g. sensorhub,

secure npu, modem, etc.) inaccessible to EL0 and EL1 PAGE Executable PAGE Read-Only

• Enables execute-only user space memory that is


PAGE Write-Mediated PAGE Read-Write

unreadable from the kernel


Security Hypervisor
Second Stage of Address Translation

# Virtual address translation is

extended with a second stage


VIRTUAL INTERMEDIATE PHYSICAL


MEMORY PHYSICAL MEMORY MEMORY

The VA is first translated into an

Intermediate Physical Address APP (EL0)

TRANSLATION
MEMORY

TRANSLATION
MEMORY


TABLES TABLES

The IPA is then translated into a PA OS (EL1) PERIPHERALS PERIPHERALS


TTBRn_EL1 VTTBR0_EL2

# It uses a second set of page tables


MEMORY

under the control of the hypervisor TRANSLATION


HYP (EL2)


TABLES

These page tables can apply TTBR0_EL2


PERIPHERALS

additional access control

# The hypervisor also has its own page

tables for its virtual address space


Security Hypervisor
Second Stage Limitations

63 62 59 58 55 54 53 52 51 50 48 47 12 11 10 9 8 7 6 5 2 1 0

RES PBHA IGNORED XN Cont DBM RES0 OA FnXS AF SH S2AP MemAttr Type

XN[1] XN[0] Access S2AP EL1 and EL0 Access

XN[1] XN[0] Access


0 0 Executable at EL0 and EL1 00 None

0 1 Executable only at EL0 0 RES0 Executable at EL0 and EL1 01 Read-only

1 0 Not executable at EL0 or EL1 1 RES0 Not executable at EL0 or EL1 10 Write-only

1 1 Executable only at EL1 11 Read/write

With FEAT_XNX Without FEAT_XNX

# Stage 2 permissions cannot distinguish between EL0 and EL1 for:

• Read and write accesses

• Executability, if FEAT_XNX is not implemented


# It is the main reason stage 1 page tables also need to be controlled by the hypervisor
Security Hypervisor
Kernel Page Tables

# Initial processing

• Traps changes made to the TTBR1_EL1 and SCTRL_EL1 system registers


• Performs a page table walk and ensures every descriptor is sane and coherent

e.g. descriptors with the contiguous bit set actually point to contiguous memory

• Enforces EL0/EL1 distinction for read-write accesses and executability

By default, kernel pages are set non executable at EL1 and non accessible at EL0

# Changes monitoring

• Kernel page tables are set as read-only in the second stage

Except when permissions can be enforced at previous table level (PXNTable/APTable)

• A write to a stage 1 descriptor or a translation fault during a page table walk raises an exception

Handled by the hypervisor to ensure modifications are permitted and update stage 2 accordingly
Security Hypervisor
Software Attributes

63 62 59 58 55 54 53 52 51 50 48 47 12 11 10 9 8 7 6 5 2 1 0

RES PBHA IGNORED XN Cont DBM RES0 OA FnXS AF SH S2AP MemAttr Type

#
Attrs Description
Hypervisor Software Attributes
0b0000 Unmarked

• Bitfield stored in bits [58:55] of a stage 2 descriptor


0b0100 Level 0 Page Table

0b0101 Level 1 Page Table

• Contains usage information about the underlying memory region


0b0110 Level 2 Page Table

0b0111 Level 3 Page Table

0b1000 OS Read-Only
• Used to prevent disallowed changes to protected memory
0b1001 OS Module Read-Only

0b1010 Hyp-mediated OS Read-Only e.g. making a OS read-only page writable again


0b1011 Hyp-mediated OS Module Read-Only

# Rules enforced while modifying them


0b1100 Shared Obj Protection Execute-Only

• Only unmarked descriptors can be marked

• To unmark a descriptor, the current marking must be provided


Security Hypervisor
Methodology

# Extensive reverse engineering # Identifying the attack surface

• Static analysis • HVC and SMC handlers

68 KB raw binary • Faulting memory accesses

AArch64 code • Trapped system registers accesses

295 functions e.g. SCTLR_EL1, TCR_EL1, etc.


No symbols • Memory shared with the kernel

~10 log strings

• Analysis can be augmented with information # Comparing the security hypervisors of different

OEMs might highlight implementation flaws


coming from external sources

HVC names from the kernel source code

Armv8-A Architecture Reference Manual


Security Hypervisor
Vulnerability

data_ptr

head_size data_size

HEADER DATA

H E L L O _ W O R L D \n

curr_off

# CVE-2021-39979

• Logging system use a control structure located in shared memory that is

accessible to the kernel

• Pointer, offset and sizes fields are all unchecked

• We can write log strings at any virtual address that is mapped into the hypervisor
Security Hypervisor
Exploitation

data_ptr = target

# Constrained write primitive head_size data_size = 1

• The log string being written is not user-controlled

• Since the buffer is circular and written character by HEADER DATA

character

Only the last byte will remain in memory if we set \n

the data size of the buffer to 1

It’s always the new line character: \n (0xA)


curr_off = head_size

# Linear heap allocator

• Heap region has a fixed base address and size

The current offset is stored in a global variable

• The allocation function assumes the offset value is void malloc(uint64_t size) {

if (HEAP_SIZE - heap_off < pad + size)


sane (smaller than the heap size)
return 0;

If it isn’t, an integer underflow happens and the heap_off += pad + size;

allocator returns out-of-bounds memory return HEAP_ADDR + heap_off + pad;


}
Right after the heap is a kernel-accessible region
Security Hypervisor
Exploitation

Global Variables

# Getting code execution


heap_off 0x00000000

remaining 0x005BA400

0x12F14C00
heap_ptr Heap Region

0x134CF000
Security Hypervisor
Exploitation

Global Variables

# Getting code execution


heap_off 0x005BA400

• Step 1: Fill up the heap to its maximum by remaining 0x00000000

triggering stage 2 page tables allocations


0x12F14C00
Heap Region

S2 Page Table

S2 Page Table

S2 Page Table

S2 Page Table

S2 Page Table

S2 Page Table

S2 Page Table

S2 Page Table

S2 Page Table
heap_ptr
0x134CF000
Security Hypervisor
Exploitation

Global Variables

# Getting code execution


heap_off 0x005BA40A

• Step 1: Fill up the heap to its maximum by remaining 0xFFFFFFF6

triggering stage 2 page tables allocations


0x12F14C00


Heap Region
Step 2: Use the constrained write primitive to

move the offset right past the end of heap


S2 Page Table

S2 Page Table

S2 Page Table

S2 Page Table

S2 Page Table

S2 Page Table

S2 Page Table

S2 Page Table

S2 Page Table

heap_ptr 0x134CF000
Security Hypervisor
Exploitation

Global Variables

# Getting code execution


heap_off 0x005BC400

• Step 1: Fill up the heap to its maximum by remaining 0xFFFFE000

triggering stage 2 page tables allocations


0x12F14C00


Heap Region
Step 2: Use the constrained write primitive to

move the offset right past the end of heap


S2 Page Table


S2 Page Table

Step 3: Trigger a last stage 2 page table

allocation that is made out-of-bounds


S2 Page Table

because of the integer underflow S2 Page Table

S2 Page Table

S2 Page Table

S2 Page Table

S2 Page Table

S2 Page Table

0x134CF000

heap_ptr S2 Page Table


Security Hypervisor
Exploitation

# Getting code execution


S2 Page Table

• Step 1: Fill up the heap to its maximum by 0x10000000 0x10000000 RO

triggering stage 2 page tables allocations


0x10001000 0x10001000 RO

• Step 2: Use the constrained write primitive to 0x10002000 0x10002000 RO

move the offset right past the end of heap … … …

• Step 3: Trigger a last stage 2 page table 0x101FD000 0x101FD000 RO

allocation that is made out-of-bounds 0x101FE000 0x101FE000 RO

because of the integer underflow


0x101FF000 0x101FF000 RO

HVC Handler

mov x1, #8

mov x0, x8

str x1, [x8]


Security Hypervisor
Exploitation

# Getting code execution


S2 Page Table

• Step 1: Fill up the heap to its maximum by 0x10000000 0x12F00000 RW

triggering stage 2 page tables allocations


0x10001000 0x12F01000 RW

• Step 2: Use the constrained write primitive to 0x10002000 0x12F02000 RW

move the offset right past the end of heap … … …

• Step 3: Trigger a last stage 2 page table 0x101FD000 0x130FD000 RW

allocation that is made out-of-bounds 0x101FE000 0x130FE000 RW

because of the integer underflow


0x101FF000 0x130FF000 RW

• Step 4: Change the page table from the

kernel to remap the hypervisor as read-write


HVC Handler

mov x1, #8

mov x0, x8

str x1, [x8]


Security Hypervisor
Exploitation

# Getting code execution


S2 Page Table

• Step 1: Fill up the heap to its maximum by 0x10000000 0x12F00000 RW

triggering stage 2 page tables allocations


0x10001000 0x12F01000 RW

• Step 2: Use the constrained write primitive to 0x10002000 0x12F02000 RW

move the offset right past the end of heap … … …

• Step 3: Trigger a last stage 2 page table 0x101FD000 0x130FD000 RW

allocation that is made out-of-bounds 0x101FE000 0x130FE000 RW

because of the integer underflow


0x101FF000 0x130FF000 RW

• Step 4: Change the page table from the

kernel to remap the hypervisor as read-write


HVC Handler

• Step 5: Patch the hypervisor memory and get


mrs x0, CurrentEL

str x0, [x8]

code execution at EL2 from EL1 ret

e.g. targeting one of the HVC handlers


TrustZone
TrustZone
Overview

NORMAL WORLD SECURE WORLD

Java Native
TA TA TA TA TA
Applications Processes

/dev/binder

ITeecService
libc libgm libtee libvendor

tee_auth_daemon

IPC

/dev/hwbinder

ILibteecGlobal

GTask
libteec@3.0-service

Perm
Platdrv RPMB SSA TUI
Serv
libteec_vendor

@tc_ns_socket

Shared IPC
libteec_vendor
Non-Secure

Memory

FS MISC RPMB SOCKET hmsysmgr hmfilemgr

SVC
/dev/tc_ns_client

TEEK

Client API
Kernel Driver Secure Kernel

SMC SECURE MONITOR SMC

TEE-OS
SMC Handlers
Dispatcher
Forward to custom TEE OS Handler
TrustZone
Normal World Overview

NORMAL WORLD SECURE WORLD

# Java applications & native processes Java Native


TA TA TA TA TA
Applications Processes

• Main users of secure world features /dev/binder

ITeecService


libc libgm libtee libvendor

But not privileged enough to send requests to the Secure


tee_auth_daemon
World
IPC

/dev/hwbinder

Use the kernel as a proxy ILibteecGlobal

GTask

# Steps to send messages to the Secure World from userland libteec@3.0-service

• Requests are received by the userland daemon teecd Platdrv


Perm

Serv
RPMB SSA TUI

libteec_vendor

First go through tee_auth_daemon for Java applications @tc_ns_socket

Shared IPC


teecd

And then forwarded to the kernel through the character device


Non-Secure

Memory

tc_ns_client FS MISC RPMB SOCKET hmsysmgr hmfilemgr

Implements the agents (filesystem, networking, etc.) SVC


/dev/tc_ns_client

Provides a shared library to communicate with it


TEEK
Kernel Driver Secure Kernel


Client API

The kernel then sends the requests to the Secure World

through an SMC
SMC SECURE MONITOR SMC

# Each interface has its own SELinux context to restrict access


TEE-OS
SMC Handlers
Dispatcher
Forward to custom TEE OS Handler
TrustZone
Secure World Overview

NORMAL WORLD SECURE WORLD

Java Native
TA TA TA TA TA
Applications Processes

/dev/binder

ITeecService
libc libgm libtee libvendor

# Secure Monitor
tee_auth_daemon

IPC

/dev/hwbinder


ILibteecGlobal

Handles SMCs and forwards requests to GTask


libteec@3.0-service

the trusted OS
Perm
Platdrv RPMB SSA TUI
Serv

#
libteec_vendor

Trusted OS @tc_ns_socket

Shared IPC
teecd
Non-Secure

• Based on a micro-kernel architecture


Memory

FS MISC RPMB SOCKET hmsysmgr hmfilemgr

• Trusted applications running on top of


SVC
/dev/tc_ns_client

privileged tasks and drivers TEEK


Kernel Driver Secure Kernel
Client API

SMC SECURE MONITOR SMC

TEE-OS
SMC Handlers
Dispatcher
Forward to custom TEE OS Handler
Secure Monitor
Secure Monitor
Introduction

NORMAL WORLD SECURE WORLD

# Executes at EL3, the highest privilege level


Java Native
TA TA TA TA TA
Applications Processes

• Performs privileged operations and manages


/dev/binder

ITeecService
libc libgm libtee libvendor

critical hardware peripherals tee_auth_daemon

IPC

e.g. efuses, power controls, RPMB, etc. /dev/hwbinder

ILibteecGlobal


GTask
Bridge between the Normal and Secure libteec@3.0-service

Worlds Perm
Platdrv RPMB SSA TUI
Serv
libteec_vendor

Forwards requests between the kernel and @tc_ns_socket

the trusted OS
Shared IPC
teecd
Non-Secure

Memory

#
hmsysmgr hmfilemgr
Huawei’s implementation based on the ARM
FS MISC RPMB SOCKET

Trusted Firmware (ATF) /dev/tc_ns_client


SVC

• Open source, probably heavily reviewed TEEK

Client API
Kernel Driver Secure Kernel

# Huawei implemented additional runtime services


SMC SECURE MONITOR SMC

• These handlers are more likely to be vulnerable


TEE-OS
SMC Handlers
Dispatcher
Forward to custom TEE OS Handler
Secure Monitor
Vulnerability

# CVE-2021-39994

• Secure Monitor acts as a pass-through for the kernel to interact with

the Secure Element (SE)


struct {

• A response from the SE uses the user_data structure where the user uint32_t unkn;

# Body Level One


controls: uint32_t code;

uint32_t addr;
The address of user_data, that contains the response metadata


uint32_t size;

Body Level Two


The address and size of the reponse data: user_data.addr and } user_data;
user_data.size
• Bounds check

Body Level Three


uint32_t user_size;

The user-provided addresses for user_data and user_data.addr


must be in a specific world-shared memory buffer /* check(user_data, user_size) is missing */

• Body Level Four


void on_reply(uint32_t addr, uint32_t size) {
However, in one of the requests, the check is missing for
user_data.code = 0xAABBCC55;
user_data

• Body Leveluser_data.size))
user_data.size = min(size, user_size);

Five
Information about the SE’s response is thus written at a user-
if (check(user_data.addr,
controlled address
memcpy(user_data.addr, addr, user_data.size);

The response code 0xAABBCC55 at offset 4 }

The response size in the range 0x0-0xC at offset 0xC


The response data address user_data.addr, which is checked
Secure Monitor
Exploitation

Data overwritten using the SE

response metadata

#
Global Variables
Step 1: Use the response metadata to disable the check on the
cma_addr 0x40000000

shared memory region


cma_size 0x10000000

• Allows copying the response data at an arbitrary

user_data.addr
• Data isn’t controlled either, but gives us more options
Secure Monitor
Exploitation

Data overwritten using the SE

response metadata

#
Global Variables
Step 1: Use the response metadata to disable the check on the
cma_addr 0x40000000
0xC

shared memory region


cma_size 0x10000000
0xAABBCC55

• Allows copying the response data at an arbitrary

user_data.addr
• Data isn’t controlled either, but gives us more options
Secure Monitor
Exploitation

#
Global Variables
Step 1: Use the response metadata to disable the check on the
cma_addr 0xC

shared memory region


cma_size 0xAABBCC55

• Allows copying the response data at an arbitrary

user_data.addr

Handler #1
Data isn’t controlled either, but gives us more options

# Step 2: Hijack a SMC handler pointer


0x14204A1C
[...]

• 1-byte overwrite by specifying a response size of 1


SMC Handlers

• Change an existing function pointer to an interesting gadget handler ptr #1 0x14204A1C

BLR X2 —> arbitrary function call


handler ptr #2 0x14204A14

Arbitrary Call Gadget


... ...

LDR X2, [X2,#0xB8]


0x14204A7C
CBNZ X2, loc_14204AA0

...

BLR X2
Secure Monitor
Exploitation

#
Global Variables
Step 1: Use the response metadata to disable the check on the
cma_addr 0xC

shared memory region


cma_size 0xAABBCC55

• Allows copying the response data at an arbitrary

user_data.addr

Handler #1
Data isn’t controlled either, but gives us more options

# Step 2: Hijack a SMC handler pointer


0x14204A1C
[...]

Data overwritten using the SE


response data

1-byte overwrite by specifying a response size of 1


SMC Handlers

• Change an existing function pointer to an interesting gadget handler ptr #1 0x14204A7C

BLR X2 —> arbitrary function call


handler ptr #2 0x14204A14

Arbitrary Call Gadget


... ...

LDR X2, [X2,#0xB8]


0x14204A7C
CBNZ X2, loc_14204AA0

...

BLR X2
Secure Monitor
Exploitation

#
Global Variables
Step 1: Use the response metadata to disable the check on the
cma_addr 0xC

shared memory region


cma_size 0xAABBCC55

• Allows copying the response data at an arbitrary

user_data.addr

Handler #1
Data isn’t controlled either, but gives us more options

# Step 2: Hijack a SMC handler pointer


0x14204A1C
[...]

Data overwritten using the SE


response data

1-byte overwrite by specifying a response size of 1


SMC Handlers

• Change an existing function pointer to an interesting gadget handler ptr #1 0x14204A7C

BLR X2 —> arbitrary function call


handler ptr #2 0x14204A14

Arbitrary Call Gadget


... ...

# Step 3: Call a write gadget to create stable read and write 0x14204A7C
LDR

CBNZ
X2,

X2,
[X2,#0xB8]

loc_14204AA0

primitives
...

BLR X2

Arbitrary Write Gadget

STR W1, [X0]

CSINC W0, W21, WZR, NE

0x1420CF88 LDP X19, X20, [SP,#0x10]

LDP X21, X22, [SP,#0x20]

LDP X23, X24, [SP,#0x30]

LDP X29, X30, [SP],#0x50

RET
Secure Monitor
Exploitation

#
Global Variables
Step 1: Use the response metadata to disable the check on the
cma_addr 0xC

shared memory region


cma_size 0xAABBCC55

• Allows copying the response data at an arbitrary

user_data.addr

Handler #1
Data isn’t controlled either, but gives us more options

# Step 2: Hijack a SMC handler pointer


0x14204A1C
[...]

• 1-byte overwrite by specifying a response size of 1


SMC Handlers

• Change an existing function pointer to an interesting gadget Arbitrary Write 0x14205E74

BLR X2 —> arbitrary function call


handler ptr #2 0x14204A14

Arbitrary Call Gadget


... ...

# Step 3: Call a write gadget to create stable read and write 0x14204A7C
LDR

CBNZ
X2,

X2,
[X2,#0xB8]

loc_14204AA0

primitives
...

BLR X2

Arbitrary Write Gadget

STR W1, [X0]

CSINC W0, W21, WZR, NE

0x1420CF88 LDP X19, X20, [SP,#0x10]

LDP X21, X22, [SP,#0x20]

LDP X23, X24, [SP,#0x30]

LDP X29, X30, [SP],#0x50

RET
Secure Monitor
Exploitation

#
Global Variables
Step 1: Use the response metadata to disable the check on the
cma_addr 0xC

shared memory region


cma_size 0xAABBCC55

• Allows copying the response data at an arbitrary

user_data.addr
• Data isn’t controlled either, but gives us more options

# Step 2: Hijack a SMC handler pointer

• 1-byte overwrite by specifying a response size of 1


SMC Handlers

• Change an existing function pointer to an interesting gadget Arbitrary Write 0x14205E74

Arbitrary Read

BLR X2 —> arbitrary function call


0x142013F4

... ...

# Step 3: Call a write gadget to create stable read and write

primitives
Secure Monitor
Exploitation

#
Global Variables
Step 1: Use the response metadata to disable the check on the
cma_addr 0xC

shared memory region


cma_size 0xAABBCC55

• Allows copying the response data at an arbitrary


MONITOR MEMORY

user_data.addr
• Data isn’t controlled either, but gives us more options

# Step 2: Hijack a SMC handler pointer


Scan memory to find the monitor


page tables

1-byte overwrite by specifying a response size of 1


SMC Handlers

• Change an existing function pointer to an interesting gadget Arbitrary Write 0x14205E74

Arbitrary Read

BLR X2 —> arbitrary function call


0x142013F4

... ...

# Step 3: Call a write gadget to create stable read and write

primitives

# Step 4: Double map the Secure Monitor because of WXN

• Locate the secure monitor page tables

• Add new entries where the memory is read-write

• Patch the code to gain code execution


Secure Monitor
Exploitation

#
Global Variables
Step 1: Use the response metadata to disable the check on the
cma_addr 0xC

shared memory region


cma_size 0xAABBCC55

• Allows copying the response data at an arbitrary


MONITOR MEMORY

user_data.addr
• Data isn’t controlled either, but gives us more options

# Step 2: Hijack a SMC handler pointer

• 1-byte overwrite by specifying a response size of 1

Monitor Page Tables


SMC Handlers
0x14000000 0x14002000 RX

• Change an existing function pointer to an interesting gadget Arbitrary Write 0x14205E74 0x14001000 0x14002000 RX

Arbitrary Read 0x14002000 0x14002000

BLR X2 —> arbitrary function call


0x142013F4 RX

... ... ... ... ...

# Step 3: Call a write gadget to create stable read and write

primitives

# Step 4: Double map the Secure Monitor because of WXN

• Locate the secure monitor page tables

• Add new entries where the memory is read-write

• Patch the code to gain code execution


Secure Monitor
Exploitation

#
Global Variables
Step 1: Use the response metadata to disable the check on the
cma_addr 0xC

shared memory region


cma_size 0xAABBCC55

• Allows copying the response data at an arbitrary


MONITOR MEMORY

user_data.addr
• Data isn’t controlled either, but gives us more options

# Step 2: Hijack a SMC handler pointer

• 1-byte overwrite by specifying a response size of 1

Monitor Page Tables


SMC Handlers
0x14000000 0x14000000 RX

• Change an existing function pointer to an interesting gadget Arbitrary Write 0x14205E74 0x14001000 0x14001000 RX

Arbitrary Read 0x14002000 0x14002000

BLR X2 —> arbitrary function call


0x142013F4 RX

... ... ... ... ...

# Step 3: Call a write gadget to create stable read and write 0x15000000 0x14000000 RW

primitives 0x15001000 0x14001000 RW

#
0x15002000 0x14002000

Step 4: Double map the Secure Monitor because of WXN


RW

... ... ...

• Locate the secure monitor page tables

• Add new entries where the memory is read-write

• Patch the code to gain code execution


Trusted OS
Trusted OS
Introduction

SECURE WORLD

# Huawei Trusted OS based on a micro-kernel TA TA TA TA TA

architecture

• Secure Kernel (S-EL1)


libc libgm libtee libvendor

Responsibilities kept to the bare minimum IPC

Critical operations are performed through an


GTask
API restricted to Managers in userland

• Processes (S-EL0)
Platdrv
Perm
RPMB SSA TUI
Serv

Managers: privileged processes providing

the core functionality of the trusted OS IPC

Tasks & Drivers: implement additional OS


hmsysmgr hmfilemgr
services used by the trusted applications
S-EL0

Trusted Applications: Huawei and 3rd party


S-EL1

applications providing services to the REE


Secure Kernel
Trusted OS
Boot Process

TEEOS SECURE GLOBAL S-EL0


PLATDRV
LOADER KERNEL TASK

SYSTEM
DRV_TIMER
MANAGER

FILE
TEESMCMGR
MANAGER

TEEOS
TEEOS CPIO Archive
TASKS

FILEMGR RAMFS Archive


Secure Kernel
Introduction

SECURE WORLD

# Only performs low-level operations, such TA TA TA TA TA

as:


libc libgm libtee libvendor

Physical memory allocation


IPC

• Inter-process communication
GTask

• Process scheduling
Perm


Platdrv RPMB SSA TUI
Serv

Access control management


IPC

# Everything else is implemented in userland hmsysmgr hmfilemgr

# SVCs for critical operations restricted to

the Managers Secure Kernel


Secure Kernel
Capabilities

# Capability-based OS # Capability type examples

• Privileges are divided into distinct units called • CNode


capabilities
• Thread

• Provides fine-grained access to kernel


• PMEM
resources
• Channel / Notification / Message

# Huawei Implementation
• IRQCTRL / IRQHDLR
• Most likely inspired by seL4
• VSRoot
• Capabilities system described in a patent filed

in 2019
• Timer

• TEESMC
• All system resources are associated with a

capability • etc.

• Capabilities are owned by a CNode (capability

node)

• Capabilities can be granted to and revoked

from other CNodes


Secure Kernel
Capabilities Example

PROCESS A HMSYSMGR
Grant

CNODE CNODE

... ...

Grant
Main thread
THREAD THREAD

CHANNEL VSROOT Address space


PROCESS B
Grant

CNODE CNODE

... ...

Grant

PMEM PMEM Stack, heap, etc.

VSROOT CHANNEL
hmsysmgr

communications

CHANNEL
Grant Grant
Managers
Overview

SECURE WORLD

TA TA TA TA TA

libc libgm libtee libvendor

# Managers
IPC

• The only S-EL0 processes allowed to ask the


GTask

secure kernel to perform critical operations

e.g. mapping physical secure memory


Perm
Platdrv RPMB SSA TUI
Serv

• Can be considered as extensions of the IPC

micro-kernel in userland hmsysmgr hmfilemgr

Secure Kernel
Managers
File & System Managers

# File manager (hmfilemgr) # System manager (hmsysmgr)

• Manages and exposes two virtual file • Implements most of the

systems fundamental features of the OS

RAMFS Process creation

• Embedded archive Virtual memory management

• Contains tasks binaries Access control

TAFS etc.

• Temporary storage for trustlets # Communicate with other processes


and libraries through IPCs

# Permissions of the calling process are

checked in the command handlers


Tasks & Drivers
Global Task

SECURE WORLD

# Equivalent to the init process on Unix-based


TA TA TA TA TA

systems

#
libc libgm libtee libvendor

Handle normal world commands


IPC

Mailbox/shared memory registration

• Loading of trusted applications


GTask

Decryption with a private key “derived” from Platdrv


Perm
RPMB SSA TUI
Serv

the provisioned key


IPC

Signature verification with a hardcoded

public key hmsysmgr hmfilemgr

• Session management

• Forwarding of commands to trusted applications Secure Kernel


Tasks & Drivers
Examples of Tasks & Drivers

SECURE WORLD

# DRV_TIMER # RPMB
TA TA TA TA TA

• Manages secure timers • RPMB filesystem


libc libgm libtee
Uses a normal world agent
libvendor

# GATEKEEPER
• Gatekeeper implementation # SSA IPC

# KEYMASTER • Trusted Storage API


GTask
Uses a normal world agent
• Keymaster implementation

# PERMISSION_SERVICE # TALOADER & TARUNNER Perm


Platdrv RPMB SSA TUI


Serv
glue between GlobalPlatform
• Permissions system for RPMB,
and OS-level APIs
SSA and TUI
IPC

# PLATDRV # TUI

hmsysmgr hmfilemgr
Trusted User Interface
• Platform drivers
implementation
• Interrupts, crypto engine, secure

element, fingerprint sensor, etc.

Secure Kernel
Tasks & Drivers
Security

# Vulnerability research # Vulnerabilities identified

• IPC command handlers • TUI Task


Heap buffer overflows
Permissions system

There is a library for implementing • Platdrv Task

security access controls


Arbitrary memory read/write

Tasks have credentials and security


Non-secure physical memory read
contexts, that can be mapped to
Heap buffer overflows
permissions

Heap pointer leak


Most permissions are static, but can


also be added dynamically
Only specific tasks can reach the

Permissions are checked within the vulnerable IPC command handlers

IPC command handlers


Trusted Applications
Trusted Applications
Introduction

SECURE WORLD

# Secure world userland applications TA TA TA TA TA

# Developed by Huawei and 3rd parties to libc libgm libtee libvendor

provide services to the Normal World IPC

# Use the standard GlobalPlatform APIs, as GTask

well as some proprietary extensions


Perm
Platdrv RPMB SSA TUI
Serv

# Generally loaded from the Normal World IPC

• Stored in the Android system/vendor hmsysmgr hmfilemgr

partitions or embedded in APKs

• Signed and encrypted


Secure Kernel
Trusted Applications
Life Cycle

# Trusted Applications Properties

• Single instance, multi session, instance keep alive, etc.

# Create and Destroy # Open and Close Sessions # Command Invocation

• Manage the global state • Manage the per-CA state • Handles a request coming from a CA

and sends back a response


• Declare the allowed CAs list

Create

Open Open Open

Session Session Session

Handler #1 ... Handler #n Handler #1 ... Handler #n Handler #1 ... Handler #n

Close Close Close

Session Session Session

Destroy
Trusted Applications
Authentication

# Trusted applications embed a list of authorized APKs/binaries

• APK: package name + signing public key

• Binaries: file path + user id + hash of code pages

# Chain of trust

• The kernel is assumed to be uncompromised

• The kernel authenticates teecd


• teecd forwards information about the binaries
Trusted Applications
Design Choices & Mitigations

# Design choices # Software Mitigations



NX
Secure functions (e.g. memcpy_s)
• RelRO
• Parameter buffers are copied to

prevent inter-world TOCTOU • Stack cookies



ASLR
Robust and generic Parcel-based

system to handle data in a safe Used to be bypassable with an

manner arbitrary read


The TA base address was written at a
Output buffer sizes can only be
fixed address by the loader
reduced
Only works for the ELF sections,

• Etc. stack and heap are still randomized


Trusted Applications
Methodology

# Reverse engineering: ~40 trustlets, # Vulnerabilities

mainly AArch32 ELF but some AArch64


• Unchecked parameter types

#

The attack surface mostly boils down
Stack & heap buffer overflows
to the command handlers

• Information leaks

# Fuzzing: developed a custom fuzzer

based on Unicorn/AFL++ • OOB accesses

• Obstacles: stubbing the GP APIs, • Race conditions (multi session

ELF relocations, getting a backtrace binaries only)

• Limitations: stateless, only low • Etc.

hanging fruits can be found


# Mostly in third party TAs
Trusted Applications
Vulnerabilities in HW_KEYMASTER

# HWPSIRT-2021-63568

• cmd_unwrap can be used to write typedef union {

struct {

arbitrary data to any files in the void* buffer;

size_t size;

sec_storage_data/PKI/ folder of the } memref;

secure file system


struct {

uint32_t a;

uint32_t b;

# HWPSIRT-2021-80349
} value;

} TEE_Param;

• generate_keyblob copies semi user- TEE_Result TA_InvokeCommandEntryPoint(

controlled data into the output


void* sessionContext,

uint32_t commandID,

parameter params[3] uint32_t paramTypes,

TEE_Param params[4]

• Should be a memref, but there is a );

code path where it can be a value


Trusted Applications
Exploitation of HW_KEYMASTER

SFS

# Arbitrary read

• Write a “fake” keyblob to the SFS using a

previously imported all-zeroes AES key


Trusted Applications
Exploitation of HW_KEYMASTER

SFS

# Arbitrary read

• Write a “fake” keyblob to the SFS using a


0000...0000

previously imported all-zeroes AES key


Trusted Applications
Exploitation of HW_KEYMASTER

SFS

# Arbitrary read

• Write a “fake” keyblob to the SFS using a Fake Keyblob

previously imported all-zeroes AES key magic 0x534554

• Call cmd_get on the “fake” keyblob to read version 0x1

data from a user-controlled offset key_off 0x1C

key_len 0x42

... ...

if (keyblob->magic == 0x534554

&& keyblob->version <= 0x12C

&& keyblob->keyblob_size == keyblob_size) {

memcpy_s(

params[1].memref.buffer,

params[1].memref.size,

keyblob + keyblob->key_off,

keyblob->key_len);

}
Trusted Applications
Exploitation of HW_KEYMASTER

SFS

# Arbitrary read

• Write a “fake” keyblob to the SFS using a Fake Keyblob

previously imported all-zeroes AES key magic 0x534554

• Call cmd_get on the “fake” keyblob to read version 0x1

data from a user-controlled offset key_off 0x1C

key_len 0x42

... ...

Keyblob opened

and copied in the

heap

if (keyblob->magic == 0x534554

&& keyblob->version <= 0x12C

&& keyblob->keyblob_size == keyblob_size) {


Obj #1 Keyblob Obj #2 Obj #3 Obj #4 Obj #5
memcpy_s(

params[1].memref.buffer,

Heap
params[1].memref.size,

keyblob + keyblob->key_off,

keyblob->key_len);

}
Trusted Applications
Exploitation of HW_KEYMASTER

SFS

# Arbitrary read

• Write a “fake” keyblob to the SFS using a Fake Keyblob

previously imported all-zeroes AES key magic 0x534554

• Call cmd_get on the “fake” keyblob to read version 0x1

data from a user-controlled offset key_off 0x1C

First read adjacent heap data to get a leak


key_len 0x42

of the object’s address ... ...

Then you can read at arbitrary addresses,

and break ASLR in particular

Obj #1 Keyblob Obj #2 Obj #3 Obj #4 Obj #5

Heap
key_off

key_len
Trusted Applications
Exploitation of HW_KEYMASTER

# Arbitrary read

• Write a “fake” keyblob to the SFS using a

previously imported all-zeroes AES key

• Call cmd_get on the “fake” keyblob to read


data from a user-controlled offset
File operations
First read adjacent heap data to get a leak

of the object’s address Open 0x12345678 Write gadget

Then you can read at arbitrary addresses,


Read 0xdeadbeef Arbitrary function
and break ASLR in particular

# Arbitrary write
... ...

Use it to overwrite a function pointer (e.g.

file operations structure) to create a better

arbitrary write primitive

Can also use it to call arbitrary functions


Conclusion
Conclusion

# All vulnerabilities were reported to Huawei Bug Bounty Program and fixed in updates released prior to this presentation

# Well thought-out security architecture

• Defense-in-depth measures

• Privilege limitations and access control

• Robust implementations (secure coding practices)

• Mistakes can still happen, but are mitigated

# Binary encryption is a double edged-sword

• Harder for an attacker to get access and find bugs

• But teams with the resources to break the encryption layer might be less likely to share their findings

# Upcoming blogposts with the missing details

• https://blog.impalabs.com
Thank you!

You might also like