0% found this document useful (0 votes)
1K views100 pages

Attacking Samsung

Uploaded by

Mohammad Afaneh
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)
1K views100 pages

Attacking Samsung

Uploaded by

Mohammad Afaneh
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/ 100

Attacking Samsung Galaxy A*

Boot Chain

Maxime Rossi Bellom


Damiano Melotti
Raphael Neveu
Gabrielle Viala
Who we are

■ Maxime Rossi Bellom @max_r_b ■ Gabrielle Viala @pwissenlit


■ Security researcher ■ Security researcher
and R&D leader @ Quarkslab and R&D leader @ Quarkslab
■ Working on mobile and embedded ■ Playing with low-level stuff
software security

■ Damiano Melotti @DamianoMelotti ■ Raphaël Neveu


■ Ex security researcher @ Quarkslab ■ Security researcher @ Quarkslab
■ Interested in low-level mobile ■ Working on low-level mobile
security and fuzzing security
2
Our Device

■ Samsung Galaxy A225F


● Cheap (~300€)
● Mediatek SoC MT6769V
● Main OS: Android
● Mix of Mediatek and Samsung code
● Trustzone OS: TEEGRIS
● Secure Boot Bypass using MTKClient1
→ making debugging easier

[1]: https://github.com/bkerler/mtkclient
4
Mediatek Secure Boot Process

5
Mediatek Secure Boot Process

6
Android partitions

■ boot.img
● Kernel and ramdisk
■ vbmeta.img
● For verified boot
■ super.img
● Dynamic partition combining system, vendor, and more
■ … many more…

7
Little Kernel (LK)

■ Open-source OS2
■ Common as bootloader in the Android world
■ Allows to boot Android or other modes
(Recovery)
■ Implements Android Verified Boot v2
● Verification of Android images
● Involving boot and vbmeta partitions
● Anti-rollback

[2]: https://github.com/littlekernel/lk
8
Little Kernel by Samsung

■ Samsung modified LK to include:


● The Odin recovery protocol
● Knox Security Bit
● Etc…
● And a JPEG parser/renderer
■ This version is closed source

9
Why Targeting the JPEG Loader/Parser

■ JPEGs are placed in a TAR archive in the up_param partition


■ The archive is signed… but the signature is not checked at boot
❗ Anyone able to write the flash can modify these JPEGs
■ Parsing JPEG is known to be hard (cf. LogoFail3)

[3]: https://www.binarly.io/blog/inside-the-logofail-poc-from-integer-overflow-to-arbitrary-code-execution
10
Why Targeting the JPEG Loader/Parser

■ JPEGs are placed in a TAR archive in the up_param partition


■ The archive is signed… but the signature is not checked at boot
❗ Anyone able to write the flash can modify these JPEGs
■ Parsing JPEG is known to be hard (cf. LogoFail3)

How are these JPEGs loaded by LK?

[3]: https://www.binarly.io/blog/inside-the-logofail-poc-from-integer-overflow-to-arbitrary-code-execution
11
Heap Overflow in JPEG Loading

_JPEG_BUF = alloc(0x100000);
if (_JPEG_BUF == 0) {
log("%s: img buf alloc fail\n","drawimg");
uVar2 = 0xffffffff;
}
else {
memset(_JPEG_BUF,0,0x100000);
iVar1 = read_jpeg_file(file_name,_JPEG_BUF,0);
if (iVar1 == 0) {
log("%s: read %s from up_param as 0, size\n","drawimg",file_name);
uVar2 = 0xffffffff;
}
// ...

pimage(*(undefined4 *)(&DAT_4c5107fc + param_1 * 0x3c),


*(undefined4 *)(&DAT_4c510800 + param_1 * 0x3c),
0x2d0,0x640,1,_JPEG_BUF,iVar1);

12
Heap Overflow in JPEG Loading

_JPEG_BUF = alloc(0x100000);
if (_JPEG_BUF == 0) {
Heap allocation of log("%s: img buf alloc fail\n","drawimg");
constant size for the uVar2 = 0xffffffff;
}
buffer else {
memset(_JPEG_BUF,0,0x100000);
iVar1 = read_jpeg_file(file_name,_JPEG_BUF,0);
if (iVar1 == 0) {
log("%s: read %s from up_param as 0, size\n","drawimg",file_name);
uVar2 = 0xffffffff;
}
// ...

pimage(*(undefined4 *)(&DAT_4c5107fc + param_1 * 0x3c),


*(undefined4 *)(&DAT_4c510800 + param_1 * 0x3c),
0x2d0,0x640,1,_JPEG_BUF,iVar1);

13
Heap Overflow in JPEG Loading

_JPEG_BUF = alloc(0x100000);
if (_JPEG_BUF == 0) {
log("%s: img buf alloc fail\n","drawimg");
uVar2 = 0xffffffff;
}
else {
memset(_JPEG_BUF,0,0x100000);
iVar1 = read_jpeg_file(file_name,_JPEG_BUF,0);
Read the JPEG in if (iVar1 == 0) {
log("%s: read %s from up_param as 0, size\n","drawimg",file_name);
the buffer uVar2 = 0xffffffff;
}
// ...

pimage(*(undefined4 *)(&DAT_4c5107fc + param_1 * 0x3c),


*(undefined4 *)(&DAT_4c510800 + param_1 * 0x3c),
0x2d0,0x640,1,_JPEG_BUF,iVar1);

14
Heap Overflow in JPEG Loading

_JPEG_BUF = alloc(0x100000);
if (_JPEG_BUF == 0) {
log("%s: img buf alloc fail\n","drawimg");
uVar2 = 0xffffffff;
}
else {
memset(_JPEG_BUF,0,0x100000);
iVar1 = read_jpeg_file(file_name,_JPEG_BUF,0);
if (iVar1 == 0) {
log("%s: read %s from up_param as 0, size\n","drawimg",file_name);
uVar2 = 0xffffffff;
}
// ...

Parse and render pimage(*(undefined4 *)(&DAT_4c5107fc + param_1 * 0x3c),


*(undefined4 *)(&DAT_4c510800 + param_1 * 0x3c),
the JPEG 0x2d0,0x640,1,_JPEG_BUF,iVar1);

15
Heap Overflow in JPEG Loading

_JPEG_BUF = alloc(0x100000);
if (_JPEG_BUF == 0) {
log("%s: img buf alloc fail\n","drawimg");
uVar2 = 0xffffffff;
}
else {
memset(_JPEG_BUF,0,0x100000);
iVar1 = read_jpeg_file(file_name,_JPEG_BUF,0);
if (iVar1 == 0) {
log("%s: read %s from up_param as 0, size\n","drawimg",file_name);
uVar2 = 0xffffffff;
}
// ...

pimage(*(undefined4 *)(&DAT_4c5107fc + param_1 * 0x3c),


*(undefined4 *)(&DAT_4c510800 + param_1 * 0x3c),
0x2d0,0x640,1,_JPEG_BUF,iVar1);

16
Heap Overflow in JPEG Loading

■ read_jpeg_file takes a size as 3rd argument


■ It triggers an error if the file does not fit the size provided

file_size = string_to_int(tar_header_file.size,0,8);
if (size != 0 && size < file_size) {
file_size = print("read fail! (%d < %d)\n",size,file_size,size);
return file_size;
}
iVar1 = read(data_addr,index + 1,file_size,outbuf);

17
Heap Overflow in JPEG Loading

■ read_jpeg_file takes a size as 3rd argument


■ It triggers an error if the file does not fit the size provided
👉 Unless the size provided is 0…

file_size = string_to_int(tar_header_file.size,0,8);
if (size != 0 && size < file_size) {
file_size = print("read fail! (%d < %d)\n",size,file_size,size);
return file_size;
}
iVar1 = read(data_addr,index + 1,file_size,outbuf);

18
Is it exploitable?

19
Exploiting a Heap Overflow in Little Kernel

struct free_chunk_head {
■ The heap algorithm is miniheap
● It relies on a doubly linked list struct free_chunk_head *prev;

■ Chunks are in a unique memory pool struct free_chunk_head *next;


● An overflow may overwrite the metadata size_t len;
of next chunk }

20
From Heap Overflow to Arbitrary Write

■ After allocation, a chunk is removed from the free list


■ next and prev are dereferenced to change the corresponding nodes
⇒ Controlling a free chunk leads to a write-what-where

node->next->prev = node->prev;
node->prev->next = node->next;
node->prev = node->next = 0;

21
From Heap Overflow to Arbitrary Write

■ After allocation, a chunk is removed from the free list


■ next and prev are dereferenced to change the corresponding nodes
⇒ Controlling a free chunk leads to a write-what-where
❗ Both values must writable addresses

node->next->prev = node->prev;
node->prev->next = node->next;
node->prev = node->next = 0;

22
From Arbitrary Write to Code Execution

Important details about LK


❌ No ASLR
❌ No canaries
❌ No bounds checks in the heap algorithm
❌ Heap is executable!

23
From Arbitrary Write to Code Execution

Important details about LK


❌ No ASLR
❌ No canaries
❌ No bounds checks in the heap algorithm
❌ Heap is executable!

Exploit strategy becomes simple:


1. Overwrite a pointer that the code will jump to
👉 the return address in the stack
2. Make it point to a shellcode in our JPEG buffer 24
Exploiting a Heap Overflow in Little Kernel

25
Exploiting a Heap Overflow in Little Kernel

26
Exploiting a Heap Overflow in Little Kernel

27
Exploiting a Heap Overflow in Little Kernel

28
Exploiting a Heap Overflow in Little Kernel

29
Exploiting a Heap Overflow in Little Kernel

30
Exploiting a Heap Overflow in Little Kernel

31
Emulating and Debugging our Exploit

■ We used Unicorn
● Emulates CPU only
● We do not care about full-system emulation
● Easy to setup & tweak
✅ Exploiting the vulnerability is quite straightforward in the emulator
❌ But the same exploit does not work on the real device

32
Emulating and Debugging our Exploit

What can go wrong?

33
Emulating and Debugging our Exploit

What can go wrong?

❌ Heap and stack are different from the ones IRL

34
Emulating and Debugging our Exploit

What can go wrong?

❌ Heap and stack are different from the ones IRL


✅ Dump it from the device

35
Emulating and Debugging our Exploit

What can go wrong?

❌ Heap and stack are different from the ones IRL


✅ Dump it from the device
👉 Memory state (addresses, sizes) is the same every boots

36
Emulating and Debugging our Exploit

What can go wrong?

❌ Heap and stack are different from the ones IRL


✅ Dump it from the device
❌ Heap algo writes something at the address *(shellcode+4)

37
Emulating and Debugging our Exploit

What can go wrong?

❌ Heap and stack are different from the ones IRL


✅ Dump it from the device
❌ Heap algo writes something at the address *(shellcode+4)

node->next->prev = node->prev;
node->prev->next = node->next;
node->prev = node->next = 0;

38
Emulating and Debugging our Exploit

What can go wrong?

❌ Heap and stack are different from the ones IRL


✅ Dump it from the device
❌ Heap algo writes something at the address *(shellcode+4)
✅ Skip the next instruction in the shellcode
add pc, pc, 0x4;
nop
nop

39
Emulating and Debugging our Exploit

What can go wrong?

❌ Heap and stack are different from the ones IRL


✅ Dump it from the device
❌ Heap algo writes something at the address *(shellcode+4)
✅ Skip the next instruction in the shellcode
❌ Heap after exploitation may crash during the next allocation

40
Emulating and Debugging our Exploit

What can go wrong?

❌ Heap and stack are different from the ones IRL


✅ Dump it from the device
❌ Heap algo writes something at the address *(shellcode+4)
✅ Skip the next instruction in the shellcode
❌ Heap after exploitation may crash during the next allocation
✅ Restore the heap in a working state

41
To sum-up

● SVE-2023-2079/CVE-2024-20832
✅ Leads to code execution
✅ Persistent (it survives reboots and factory reset)
✅ Gives full control over Normal World EL1/0
✅ Impacts Samsung devices based on Mediatek SoCs
■ Including those for which MTKClient does not work
❌ Requires to flash the up_param partition

42
How to write our JPEGs in the
up_param partition?

43
Odin: Samsung's recovery protocol

■ Odin is implemented in LK
■ It is available through the Download Mode
● It allows to flash partitions over USB
■ The Odin official client is closed source
■ There is an open-source client: Heimdall4

[4]: https://github.com/Benjamin-Dobell/Heimdall
44
Odin: Samsung's recovery protocol

■ Images are authenticated and contain a footer signature


■ Two internal structures indicate which partitions to flash
● The Partition Information Table (PIT)
● A global structure indicating which partitions to authenticate

45
Odin: Partition Information Table

--- Entry #1 ---


Binary Type: 0 (AP)
■ PIT is retrieved statically from the eMMC Device Type: 2 (MMC)
■ It indicates where partitions are stored Identifier: 70
● Memory type, block count, etc Attributes: Read/Write
■ A partition not present in PIT can't be flashed Update Attributes: 1
■ PIT can be updated, but requires a signed Block Size/Offset: 0
image Block Count: 34
Partition Name: pgpt

46
Odin: Image Authentication

■ A global array indicates how an image should be authenticated


■ An image not present in this array will not be authenticated
● (Except for some specific images)
■ Comparing this array with PIT gives a set of images flashable without
authentication

md5hdr, md_udc, pgpt, sgpt, and vbmeta_vendor

47
GPT: GUID Partition Table

■ pgpt points to the Primary GPT Header


■ sgpt points to the Secondary GPT Header
■ Similarly to the PIT, it describes the partitions
○ (Names, sizes, addresses, etc)
■ Any GPT can be flashed through Odin
❗ No authentication required

Source: https://en.wikipedia.org/wiki/GUID_Partition_Table
48
GPT vs PIT

■ PIT and GPT are used for the same thing: to describe partitions
■ PIT is mainly used for Samsung features in LK
● Odin, JPEGs loading, etc
■ And GPT is used the rest of the time

❗ We can't just rename a partition to up_param to flash our JPEGs

49
PIT Loading

pit_address = 0x4400;
exist = get_part_table("pit");
if (exist == 0) {
pit_address = get_partition_offset("pit");
}
type = storage(3);
iVar1 = storage_read(type,0x4000,(int)pit_address,
(int)((ulonglong)pit_address >> 0x20),
&ODIN_TEMP_BUF_PIT,0x4000);

50
PIT Loading

PIT default address

pit_address = 0x4400;
exist = get_part_table("pit");
if (exist == 0) {
pit_address = get_partition_offset("pit");
}
type = storage(3);
iVar1 = storage_read(type,0x4000,(int)pit_address,
(int)((ulonglong)pit_address >> 0x20),
&ODIN_TEMP_BUF_PIT,0x4000);

51
PIT Loading

PIT default address

pit_address = 0x4400;
exist = get_part_table("pit"); Check for pit partition
if (exist == 0) { And use it if it exists
pit_address = get_partition_offset("pit");
}
type = storage(3);
iVar1 = storage_read(type,0x4000,(int)pit_address,
(int)((ulonglong)pit_address >> 0x20),
&ODIN_TEMP_BUF_PIT,0x4000);

52
PIT Loading

PIT default address

pit_address = 0x4400;
exist = get_part_table("pit");
Uses GPT table 😈
if (exist == 0) {
pit_address = get_partition_offset("pit");
}
type = storage(3);
iVar1 = storage_read(type,0x4000,(int)pit_address,
(int)((ulonglong)pit_address >> 0x20),
&ODIN_TEMP_BUF_PIT,0x4000);

53
Strategy to Bypass Odin Authentication

54
Strategy to Bypass Odin Authentication

55
Strategy to Bypass Odin Authentication

56
Strategy to Bypass Odin Authentication

57
Strategy to Bypass Odin Authentication

58
Strategy to Bypass Odin Authentication

✅ It works (new jpegs are loaded)


❌ Android won't boot without the
vbmeta_vendor partition

59
Strategy to Bypass Odin Authentication

60
Strategy to Bypass Odin Authentication

61
To sum up

■ SVE-2024-0234/CVE-2024-20865
✅ Can bypass authentication in Odin
✅ We can flash anything in the eMMC
✅ Including our up_param partition
✅ Seems to impact most Samsung using
Mediatek SoCs

62
Post Exploitation: bypassing Android Verified Boot

■ Our ultimate goal is to bypass AVB checks in LK to load a modified


Android
● We patch LK code from our shellcode
● Memory already writable → no need to play with MMU

63
Chaining Everything Together

64
To Conclude

■ Chain based on 2 vulnerabilities


✅ Leads to code execution in LK
✅ Persistent (it survives reboots and factory reset)
✅ Impacts Samsung devices based on Mediatek SoCs
● Including those for which MTKClient does not work
✅ Can be triggered over USB thanks to Odin authentication bypass
✅ Gives full control over Normal World EL1/0
❌ Still no access to secrets stored in Secure World

65
Targeting ARM Trusted Firmware

66
Targeting ARM Trusted Firmware

67
Communication between NSW and SW

68
Vulnerability Research on ATF

■ Motivation:
● Highest privilege level → A bug here can be devastating
● Reachable from Normal World through SMCs
■ Code is simple
■ Interacts a lot with HW through unknown registers
● Fuzzing not particularly interesting in this case
■ Our approach: focus on static analysis

69
Few Words about TEEGRIS

■ Trustzone OS designed by Samsung


■ ROM images:
● tee-verified.img: ATF, TEEGRIS kernel, userboot.so
● tzar.img: TEE root filesystem
● super.img: Android system, Trusted Applications and Drivers
■ Excellent references online7

[7]: https://www.riscure.com/tee-security-samsung-teegris-part-1/
70
Extracting ATF

71
SMC Handlers

if ((is_secure & 1) == 0) {
puVar1 = mediatek_plat_sip_handler_secure(smc_id,arg1,arg2,arg3
,arg4,arg5,output);
return puVar1;
}
[...]
if ((origin < 2) && (IN_BOOTLOADER == 0)) {
puVar1 = mediatek_plat_sip_handler_kernel(smc_id,arg1,arg2,arg3
,arg4,arg5,output);
return puVar1;
}
72
SMC Handlers

if ((is_secure & 1) == 0) {
puVar1 = mediatek_plat_sip_handler_secure(smc_id,arg1,arg2,arg3
,arg4,arg5,output);
return puVar1;
}
Arguments of SMC
[...]
if ((origin < 2) && (IN_BOOTLOADER == 0)) {
puVar1 = mediatek_plat_sip_handler_kernel(smc_id,arg1,arg2,arg3
,arg4,arg5,output);
return puVar1;
}
73
Leaking from Virtual Address Space

uint* global_array = (uint *)0x4ce2f578;


[...]
if (smcid == 0x82000526) {
out_value = global_array[arg1 * 4];
goto exit;
}
[...]
output[2] = out_value;
output[1] = arg1;
*output = 0;
return output;
74
Leaking from Virtual Address Space

uint* global_array = (uint *)0x4ce2f578;


[...]
if (smcid == 0x82000526) {
out_value = global_array[arg1 * 4];
goto exit;
Fully controlled by
}
attacker
[...]
output[2] = out_value;
output[1] = arg1;
*output = 0;
return output;
75
Leaking from Virtual Address Space

uint* global_array = (uint *)0x4ce2f578;


[...]
if (smcid == 0x82000526) {
out_value = global_array[arg1 * 4];
goto exit;
Fully controlled by
}
attacker… And never
[...] checked
output[2] = out_value;
output[1] = arg1;
*output = 0;
return output;
76
SVE-2023-2215 (CVE-2024-20820)

■ In mediatek_plat_sip_handler_kernel, reachable from Linux Kernel


■ To exploit it, send the SMC 0x82000526 with
● (arbitrary_address - 0x4ce2f578) / 4
■ Bug introduced by Samsung only in some devices (including A225F)
■ It leaks 4 bytes from ATF virtual address space
● We can read all the internal data of ATF
● But we can't leak anything from other SW components

77
SVE-2023-2215 (CVE-2024-20820)

78
Mapping Any Physical Address in ATF

SMC 0x8200022A calls function spm_actions

if (smc_id == 0x8200022a) {
spm_actions(arg1,arg2,arg3);

79
Mapping Any Physical Address in ATF

SMC 0x8200022A calls function spm_actions

undefined * spm_actions(ulong cmdid,undefined *addr,ulong size) {


switch(cmdid & 0xffffffff) {
[...]
case 1:
if (size < 0x100001) {
mmap_wrap(addr,size);
[...]
}

80
Mapping Any Physical Address in ATF

SMC 0x8200022A calls function spm_actions

undefined * spm_actions(ulong cmdid,undefined *addr,ulong size) {


switch(cmdid & 0xffffffff) {
[...] Arguments fully
case 1: controlled
if (size < 0x100001) {
mmap_wrap(addr,size);
[...]
}

81
Mapping Any Physical Address in ATF

SMC 0x8200022A calls function spm_actions

undefined * spm_actions(ulong cmdid,undefined *addr,ulong size) {


switch(cmdid & 0xffffffff) {
[...] Arguments fully
case 1: controlled
if (size < 0x100001) {
mmap_wrap(addr,size);
[...]
And still no checks on
} the address

82
Mapping Any Physical Address in ATF

SMC 0x8200022A calls function spm_actions

undefined * spm_actions(ulong cmdid,undefined *addr,ulong size) {


switch(cmdid & 0xffffffff) {
[...]
Physical Address
case 1:
if (size < 0x100001) {
mmap_wrap(addr,size);
[...]
And still no checks on
} the address

83
CVE-2024-20021

■ Also in mediatek_plat_sip_handler_kernel
■ Will mmap with physical base address to the same virtual address
● … however we can't munmap
○ So we are limited to 8 consecutives mmaps
○ Meaning we can leak up to 8MB of data
■ Introduced by Mediatek (impacts plenty of Mediatek SoCs)
■ Chained to our leak, we can read everything in Secure World
● Including TEEGRIS

84
Can we use this vulnerability to leak
Keystore keys?

85
Android Keystore system

■ Key storage and crypto services


■ Keys are stored as key blobs
■ Three protection levels:
● Software only
● TEE (default)
● Hardware-backed (StrongBox)
■ Raw key should never leave protected environment

86
Android Keystore system

87
Where to leak?

a22:/ # cat /proc/last_kmsg


[...]
[4425] mblock_reserve-R[5].start: 0x4ce00000, size: 0x60000 map:0
,name:atf-reserved
[...]
[4426] mblock_reserve-R[8].start: 0x7ac00000, size: 0x400000 map:0
,name:tee-secmem
[4426] mblock_reserve-R[9].start: 0x7f300000, size: 0xc0000 map:0
,name:SSPM-reserved
[4426] mblock_reserve-R[10].start: 0x7b200000, size: 0x4000000
, map:0 name:tee-reserved
[...]
[4436] lk finished --> jump to linux kernel 64Bit
88
Where to leak?

a22:/ # cat /proc/last_kmsg


[...]
[4425] mblock_reserve-R[5].start: 0x4ce00000, size: 0x60000 map:0
,name:atf-reserved
[...]
[4426] mblock_reserve-R[8].start: 0x7ac00000, size: 0x400000 map:0
,name:tee-secmem
[4426] mblock_reserve-R[9].start: 0x7f300000, size: 0xc0000 map:0
,name:SSPM-reserved
[4426] mblock_reserve-R[10].start: 0x7b200000, size: 0x4000000
, map:0 name:tee-reserved
[...]
[4436] lk finished --> jump to linux kernel 64Bit
89
Where to leak?

■ TAs should be part of the tee-reserved (0x7b200000) memory block


■ Keymaster TA binary contains many strings
● (path in Android fs: /vendor/tee/00000000-0000-0000-0000-4b45594d5354)
■ Try to find these strings in memory
● Usually present around 0x7c200000

90
Our PoC

1. Import a key into the Android Keystore


2. Encrypt using that key
3. Stop the execution after BeginOperation is called
○ To makes sure the key stays in memory
4. Leak the identified region of memory

91
A Simple PoC

byte[] key = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA".getBytes();


SecretKey yourKey = (SecretKey) new SecretKeySpec(key, 0, key.length,
"AES");
[...]
keyStore = KeyStore.getInstance("AndroidKeystore");
keyStore.load(null);
keyStore.setEntry("key1", new KeyStore.SecretKeyEntry(yourKey), new
KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT |
KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.build());

keyStoreKey = (SecretKey) keyStore.getKey("key1", null);


92
Communication between NSW and SW

93
Hooking Keystore HAL Deamon

94
The result

95
The result

96
Our PoC

1. Import a key into the Android Keystore


2. Encrypt using that key
3. Stop the execution after BeginOperation is called
○ To makes sure the key stays in memory
4. Leak the identified region of memory
5. Try all possible keys from from leak to decrypt ciphertext

97
Demo

98
Conclusion

■ We presented 4 vulnerabilities leading to


● Authentication bypass in Odin
● Code execution with persistence in LK
● Leak of SW memory, including Keystore keys
■ Impact low/middle end Samsung devices
● Vulnerabilities are simple, and yet super impactful
● No mitigations in LK nor ATF
■ All the vulnerabilities are now fixed

99
Thank you!

@max_r_b
[email protected] @DamianoMelotti
@pwissenlit

You might also like