Inception: System-Wide Security Testing of Real- World Embedded - - PowerPoint PPT Presentation
Inception: System-Wide Security Testing of Real- World Embedded - - PowerPoint PPT Presentation
Inception: System-Wide Security Testing of Real- World Embedded Systems Software Nassim Corteggiani (Maxim Integrated / EURECOM) Giovanni Camurati (EURECOM) Aurlien Francillon (EURECOM) 08/15/18 Embedded Systems Are Everywhere [1]
Embedded Systems Are Everywhere
| Maxim Integrated | EURECOM 2
[1] https://community.arm.com/processors/b/bl
- g/posts/arm-cortex-m3-processor-the-core-
- f-the-iot
Embedded Systems Are Everywhere
Low Power Micro-controllers
| Maxim Integrated | EURECOM 3
[1] https://community.arm.com/processors/b/bl
- g/posts/arm-cortex-m3-processor-the-core-
- f-the-iot
Embedded Systems Are Everywhere
Low Power Micro-controllers Over 32 billions of ARM Cortex M3 shipped in 2018 [1] [1] https://community.arm.com/processors/b/bl
- g/posts/arm-cortex-m3-processor-the-core-
- f-the-iot
Cover a wide range of fields
| Maxim Integrated | EURECOM 4
Why the Security of Such Systems Matters?
| Maxim Integrated | EURECOM 5
Why the Security of Such Systems Matters?
- Highly connected -> large scale attacks
| Maxim Integrated | EURECOM 6
Why the Security of Such Systems Matters?
- Highly connected -> large scale attacks
- Difficulty to patch the code
> Mask ROM → mask applied on the chip during the fabrication > Off-line devices
| Maxim Integrated | EURECOM 7
Why the Security of Such Systems Matters?
- Highly connected -> large scale attacks
- Difficulty to patch the code
> Mask ROM → mask applied on the chip during the fabrication > Off-line devices
- Store sensitive data
> Bitcoin wallet > Payment terminal
| Maxim Integrated | EURECOM 8
Why the Security of Such Systems Matters?
- Highly connected -> large scale attacks
- Difficulty to patch the code
> Mask ROM → mask applied on the chip during the fabrication > Off-line devices
- Store sensitive data
> Bitcoin wallet > Payment terminal
- Drive sensitive hardware system
> Physical damage > Production line outage > Signaling systems (red light)
| Maxim Integrated | EURECOM 9
Exemple of Recent Security Issues
Recent attacks
| Maxim Integrated | EURECOM 10
Exemple of Recent Security Issues
Recent attacks
- Nintendo Switch Tegra X1 bootrom exploit 2018
> buffer overflow in the USB stack embedded in the mask ROM > Cannot be patched > Give access to the entire software stack
| Maxim Integrated | EURECOM 11
How Can We Test Such Firmware Programs?
- Symbolic Execution
> High path coverage > Return test case for bugs
| Maxim Integrated | EURECOM 12
Symbolic Execution Example
i = symb_i Int buffer[2]
i = <input> int buffer[2] = {0, 1};
| Maxim Integrated | EURECOM 13
Symbolic Execution Example
¬(𝟏 ≤ 𝒋 < 𝟑) 𝟏 ≤ 𝒋 < 𝟑 i = symb_i Int buffer[2] buffer[i]
TRUE FALSE i = <input> int buffer[2] = {0, 1}; if( buffer[i] == 0 ) { Out of bounds access
| Maxim Integrated | EURECOM 14
Symbolic Execution Example
¬(𝟏 ≤ 𝒋 < 𝟑) 𝟏 ≤ 𝒋 < 𝟑 i = symb_i Int buffer[2] buffer[i]
TRUE FALSE i = <input> int buffer[2] = {0, 1}; if( buffer[i] == 0 ) { buffer[i] = 0xDEADBEEF; }
¬(𝒋 = 𝟏) 𝒋 = 𝟏 buffer[i] == 0xDEADBEAF buffer[i] == 0
TRUE FALSE
| Maxim Integrated | EURECOM 15
Out of bounds access
Building A Symbolic Executor For Firmware Programs
Klee as a basis
- Inception is based on Klee a symbolic virtual machine:
| Maxim Integrated | EURECOM 16
Building A Symbolic Executor For Firmware Programs
Klee as a basis
- Inception is based on Klee a symbolic virtual machine:
> Widely deployed, efficient and based on the LLVM framework.
| Maxim Integrated | EURECOM 17
Building A Symbolic Executor For Firmware Programs
Klee as a basis
- Inception is based on Klee a symbolic virtual machine:
> Widely deployed, efficient and based on the LLVM framework. > Find memory safety violations
| Maxim Integrated | EURECOM 18
Building A Symbolic Executor For Firmware Programs
Klee as a basis
- Inception is based on Klee a symbolic virtual machine:
> Widely deployed, efficient and based on the LLVM framework. > Find memory safety violations > High code coverage
| Maxim Integrated | EURECOM 19
Building A Symbolic Executor For Firmware Programs
Klee as a basis
- Inception is based on Klee a symbolic virtual machine:
> Widely deployed, efficient and based on the LLVM framework. > Find memory safety violations > High code coverage
C/C++ source code
| Maxim Integrated | EURECOM 20
Building A Symbolic Executor For Firmware Programs
Klee as a basis
- Inception is based on Klee a symbolic virtual machine:
> Widely deployed, efficient and based on the LLVM framework. > Find memory safety violations > High code coverage
C/C++ source code Clang
| Maxim Integrated | EURECOM 21
Building A Symbolic Executor For Firmware Programs
Klee as a basis
- Inception is based on Klee a symbolic virtual machine:
> Widely deployed, efficient and based on the LLVM framework. > Find memory safety violations > High code coverage
C/C++ source code Clang LLVM bit-code
| Maxim Integrated | EURECOM 22
Building A Symbolic Executor For Firmware Programs
Klee as a basis
- Inception is based on Klee a symbolic virtual machine:
> Widely deployed, efficient and based on the LLVM framework. > Find memory safety violations > High code coverage
C/C++ source code Clang LLVM bit-code Klee
| Maxim Integrated | EURECOM 23
Why testing source code instead of binary code ?
Source VS Binary
| Maxim Integrated | EURECOM 24
Why testing source code instead of binary code ?
Source VS Binary
char b1[2]; char b2[2]; char getElement(int index) { return b1[index]; } b1: .space 2 b2: .space 2 getElement(int): ldr r2, .L3 add r3, r2, r0 ldrb r0, [r3] bx lr .L3: .word b1
| Maxim Integrated | EURECOM 25
Why testing source code instead of binary code ?
Source VS Binary
char b1[2]; char b2[2]; char getElement(int index) { return b1[index]; } b1: .space 2 b2: .space 2 getElement(int): ldr r2, .L3 add r3, r2, r0 ldrb r0, [r3] bx lr .L3: .word b1
| Maxim Integrated | EURECOM 26
Why testing source code instead of binary code ?
Source ( Klee/Clang…) VS Binary (SE2, angr, BAP)
define i8 @getElement(i32 %index){ entry: %0 = load i32* %index.addr %1 = getelementptr inbounds [2 x i8]* @b1, i32 0, i32 %0 %2 = load i8* %1 ret i8 %2 } char b1[2]; char b2[2]; char getElement(int index) { return b1[index]; } b1: .space 2 b2: .space 2 getElement(int): ldr r2, .L3 add r3, r2, r0 ldrb r0, [r3] bx lr .L3: .word b1 define i8 @getElement(i32 index) { entry: store i32 %index, i32* @R0 store i32 268436792, i32* @R2 %R2_1 = load i32* @R2 %R0_1 = load i32* @R0 %R2_2 = add i32 %R2_1, %R0_1 %R3_0 = inttoptr i32 %R2_2 to i32* %R3_1 = bitcast i32* %R3_0 to i8* %R3_2 = load i8* %R3_1 %R3_3 = zext i8 %R3_2 to i32
| Maxim Integrated | EURECOM 27
Why testing source code instead of binary code ?
Source ( Klee/Clang…) VS Binary (SE2, angr, BAP)
define i8 @getElement(i32 %index){ entry: %0 = load i32* %index.addr %1 = getelementptr inbounds [2 x i8]* @b1, i32 0, i32 %0 %2 = load i8* %1 ret i8 %2 } char b1[2]; char b2[2]; char getElement(int index) { return b1[index]; } b1: .space 2 b2: .space 2 getElement(int): ldr r2, .L3 add r3, r2, r0 ldrb r0, [r3] bx lr .L3: .word b1 define i8 @getElement(i32 index) { entry: store i32 %index, i32* @R0 store i32 268436792, i32* @R2 %R2_1 = load i32* @R2 %R0_1 = load i32* @R0 %R2_2 = add i32 %R2_1, %R0_1 %R3_0 = inttoptr i32 %R2_2 to i32* %R3_1 = bitcast i32* %R3_0 to i8* %R3_2 = load i8* %R3_1 %R3_3 = zext i8 %R3_2 to i32
| Maxim Integrated | EURECOM 28
Source vs Binary
- When source available testing binary is possible however:
> Types are lost > Corruption will be detected later if at all > Worse on embedded systems
- See: Muench et. al. What you corrupt is not what you crash, NDSS 2018
- Goal of Inception: improve testing for firmware during development
> Limit requirements on code
| Maxim Integrated | EURECOM 29
Major Challenges For Symbolic Execution of Firmware Programs
Is C/C++ Support Enough To Test Real World Firmware ?
- Number of functions including assembly instructions
in real world embedded software
22 98 108 80 1 10 100 1000 STM32(demos) FreeRTOS(STM32) Mbed OS ChibiOS Functions2
| Maxim Integrated | EURECOM 30
Major Challenges For Symbolic Execution of Firmware Programs
Is C/C++ Support Enough To Test Real World Firmware ?
- Number of functions including assembly instructions
in real world embedded software
22 98 108 80 1 10 100 1000 STM32(demos) FreeRTOS(STM32) Mbed OS ChibiOS Functions2
- Assembly code :
> Multithreading > Optimizations > Side channel counter-measures > Hardware features e.g. ultra low power mode
| Maxim Integrated | EURECOM 31
Major Challenges For Symbolic Execution of Firmware Programs
Is C/C++ Support Enough To Test Real World Firmware ?
- Presence of assembly instructions in real
world embedded software
500 1000 1500 2000 2500 3000 STM32(demos) FreeRTOS(STM32) Mbed OS ChibiOS Functions with inline asm Functions2
- Assembly code :
> Multithreading > Optimizations > Side channel counter-measures > Hardware features e.g. ultra low power mode
Challenge 1 : Firmware source code contains a mix of C/C++, assembly and binary
| Maxim Integrated | EURECOM 32
Major Challenges For Symbolic Execution of Firmware Programs
Hardware environment
| Maxim Integrated | EURECOM 33
Major Challenges For Symbolic Execution of Firmware Programs
Hardware environment
- Hardware interactions
> Memory Mapped I/O
| Maxim Integrated | EURECOM 34
Major Challenges For Symbolic Execution of Firmware Programs
Hardware environment
- Hardware interactions
> Memory Mapped I/O
- Memory
- Peripherals
#define UART_STATUS 0x40000000 #define UART_DATA 0x40000004 char* RX_BUFFER = 0x20000000; while(!*UART_STATUS) { char* data = (char*)UART_DATA; strncpy(RX_BUFFER++, data, 4); } Internal/external memory Internal/external peripherals
| Maxim Integrated | EURECOM 35
Major Challenges For Symbolic Execution of Firmware Programs
Hardware environment
- Hardware interactions
> Memory Mapped I/O
- Memory
- Peripherals
> Interrupt driven programs
#define UART_STATUS 0x40000000 #define UART_DATA 0x40000004 char* RX_BUFFER = 0x20000000; while(!*UART_STATUS) { char* data = (char*)UART_DATA; strncpy(RX_BUFFER++, data, 4); } Internal/external memory Internal/external peripherals Interrupt Controller void interrupt_handler() { }
| Maxim Integrated | EURECOM 36
Major Challenges For Symbolic Execution of Firmware Programs
Hardware environment
- Hardware interactions
> Memory Mapped I/O
- Memory
- Peripherals
> Interrupt driven programs
#define UART_STATUS 0x40000000 #define UART_DATA 0x40000004 char* RX_BUFFER = 0x20000000; while(!*UART_STATUS) { char* data = (char*)UART_DATA; strncpy(RX_BUFFER++, data, 4); } Internal/external memory Internal/external peripherals Interrupt Controller void interrupt_handler() { }
Challenge 2 : Firmware programs highly interact with their hardware environment
| Maxim Integrated | EURECOM 37
Building A Symbolic Executor For Firmware Programs
| Maxim Integrated | EURECOM 38
Building A Symbolic Executor For Firmware Programs
Firmware (C/C++, asm, binary) Clang LLVM bit-code
| Maxim Integrated | EURECOM 39
Building A Symbolic Executor For Firmware Programs
Firmware (C/C++, asm, binary) Clang LLVM bit-code ELF ARM Backend
| Maxim Integrated | EURECOM 40
Building A Symbolic Executor For Firmware Programs
Firmware (C/C++, asm, binary) Clang LLVM bit-code ELF Inception Translator LLVM bit-code Mixed IR ARM Backend
- Inception translator:
> Lift assembly directives and binary code in LLVM bit-code > Merge lifted bit-code with other
- High-IR : obtained from C/C++
- Glue-IR : glue code
- Low-IR : lifted assembly/binary
| Maxim Integrated | EURECOM 41
Building A Symbolic Executor For Firmware Programs
Firmware (C/C++, asm, binary) Clang LLVM bit-code Modified Klee ELF Inception Translator LLVM bit-code Mixed IR ARM Backend
| Maxim Integrated | EURECOM 42
- Inception translator:
> Lift assembly directives and binary code in LLVM bit-code > Merge lifted bit-code with other
- High-IR : obtained from C/C++
- Glue-IR : glue code
- Low-IR : lifted assembly/binary
> Support Cortex M3 ISA
Challenge 1 : Supporting C/C++/Asm/Binary code
Inception-translator
| Maxim Integrated | EURECOM 52
Inception Translator : Merging High-IR and Low-IR
| Maxim Integrated | EURECOM 53
int a = 4; boo(a); <boo>: 1000045C: 80 B4 push {r7} 1000045E: 83 B0 sub sp, #0xc
Inception Translator : Merging High-IR and Low-IR
High IR %a = alloca i32 store i32 4, i32* %a %0 = load i32* %a %call = call i32 @boo(i32 %0) ret void }
| Maxim Integrated | EURECOM 54
int a = 4; boo(a); <boo>: 1000045C: 80 B4 push {r7} 1000045E: 83 B0 sub sp, #0xc
Inception Translator : Merging High-IR and Low-IR
Low IR High IR int a = 4; boo(a); %a = alloca i32 store i32 4, i32* %a %0 = load i32* %a %call = call i32 @boo(i32 %0) ret void } <boo>: 1000045C: 80 B4 push {r7} 1000045E: 83 B0 sub sp, #0xc "boo+0": ; preds = %entry %R7_1 = load i32* @R7 %SP1 = load i32* @SP %SP2 = sub i32 %SP1, 4 %SP3 = inttoptr i32 %SP2 to i32* store i32 %R7_1, i32* %SP3 store i32 %SP2, i32* @SP %SP4 = load i32* @SP %SP5 = add i32 %SP4, -13 %SP6 = add i32 %SP5, 1
| Maxim Integrated | EURECOM 55
Inception Translator : Merging High-IR and Low-IR
Glue IR Low IR High IR int a = 4; boo(a); define i32 @boo(i32 %a){ entry: store i32 %a, i32* @R0 br label %"boo+0" %a = alloca i32 store i32 4, i32* %a %0 = load i32* %a %call = call i32 @boo(i32 %0) ret void } <boo>: 1000045C: 80 B4 push {r7} 1000045E: 83 B0 sub sp, #0xc "boo+0": ; preds = %entry %R7_1 = load i32* @R7 %SP1 = load i32* @SP %SP2 = sub i32 %SP1, 4 %SP3 = inttoptr i32 %SP2 to i32* store i32 %R7_1, i32* %SP3 store i32 %SP2, i32* @SP %SP4 = load i32* @SP %SP5 = add i32 %SP4, -13 %SP6 = add i32 %SP5, 1
| Maxim Integrated | EURECOM 56
Unified Memory Layout
| Maxim Integrated | EURECOM 57
Unified Memory Layout
Glue IR : lower the level of semantic Low IR High IR Glue IR : higher the level of semantic High IR Execution path
| Maxim Integrated | EURECOM 58
Unified Memory Layout
- Allocate Low IR memory : stack, virtual CPU registers, heap
Glue IR : lower the level of semantic Low IR High IR Glue IR : higher the level of semantic High IR Execution path
| Maxim Integrated | EURECOM 59
Unified Memory Layout
- Allocate Low IR memory : stack, virtual CPU registers, heap
- Fill gaps in global data sections
- When no C/C++ symbols point to this area
Glue IR : lower the level of semantic Low IR High IR Glue IR : higher the level of semantic High IR Execution path
| Maxim Integrated | EURECOM 60
Unified Memory Layout
- Allocate Low IR memory : stack, virtual CPU registers, heap
- Fill gaps in global data sections
- When no C/C++ symbols point to this area
- Allocate High-IR objects at location defined in the ELF symbols table
Glue IR : lower the level of semantic Low IR High IR Glue IR : higher the level of semantic High IR Execution path
| Maxim Integrated | EURECOM 61
Low IR Hardware Mechanisms Emulation
- Challenge we solved:
> Indirect calls (Indirect Call Promotion) > Seamless hardware mechanisms (Context switching) > Supervisor call
> Update specific registers values (LR, MSP, PSP, BASEPRI, ITSTATE, …)
Glue IR : lower the level of semantic Low IR High IR Glue IR : higher the level of semantic High IR Execution path Emulation
| Maxim Integrated | EURECOM 62
Challenge 2 : Hardware interactions
Inception-analyzer
| Maxim Integrated | EURECOM 63
The Inception System Overview
Mixed Bytecode config.json Klee-based Symbolic Virtual Machine ELF
| Maxim Integrated | EURECOM 64
The Inception System Overview
Mixed Bytecode config.json Klee-based Symbolic Virtual Machine Memory Mapped stack Globals heap Data are allocated according to the information present in the symbol table User configuration (config.json):
- Local memory
- Redirected memory
- Symbolic memory
ELF
| Maxim Integrated | EURECOM 65
The Inception System Overview: Inception debugger
Mixed Bytecode config.json Klee-based Symbolic Virtual Machine Memory Mapped stack Globals heap ELF Real Device Custom Inception Debugger USB 3.0 link Jtag
| Maxim Integrated | EURECOM 66
The Inception System Overview: Inception debugger
- Inspired by Surrogates and Avatar
| Maxim Integrated | EURECOM 67
Memory Mapped stack Globals heap Real Device Custom Inception Debugger USB 3.0 link Jtag
Zaddach et. al. AVATAR: A Framework to Support Dynamic Security Analysis of Embedded Systems' Firmwares, NDSS 2014 Koscher et. al. SURROGATES: Enabling Near-Real-Time Dynamic Analyses of Embedded Systems, WOOT 2015
The Inception System Overview: Inception debugger
Mixed Bytecode config.json Klee-based Symbolic Virtual Machine Memory Mapped stack Globals heap ELF Real Device Custom Inception Debugger USB 3.0 link Interrupt Controller Jtag
| Maxim Integrated | EURECOM 68
Evaluation
| Maxim Integrated | EURECOM 69
Performance
Average time to complete 1 × 106 read or write requests for SURROGATES and Inception. Performance comparison between native execution and Inception. * Current bottleneck is bit-code execution
10000 20000 30000 40000 50000 60000 70000 80000 Reads Writes Buffered Reads Inception Surrogates 0,1 1 10 100 1000 10000 Wget Ping UART Inception Native
| Maxim Integrated | EURECOM 70
Average IO per second Average runtime [ms]
Bug Detection
Evolution of corruption detection vs. number of assembly functions in the EXPACT XML parser (4 vulnerabilities [1], symbolic inputs, and a timeout of 90s). Corruption detection of real-world security flaws based on FreeRTOS and the Juliet 1.3 test suites.
1 2 3 4 1 2 3 4 5 Detected Undetected 0% 20% 40% 60% 80% 100% Division by Zero Null Pointer Dereference Use After Free Free Memory Not
- n Heap
Heap-Based Buffer Overflow Integer Overflow Detected Undetected
[1] MUENCH et. al. What you corrupt is not what you crash: Challenges in fuzzing embedded devices. In NDSS 2018.
| Maxim Integrated | EURECOM 71
% of detected bugs Average number of detected vuln.
Verification
- Intensive verification of the lifter and the modified Klee
> 53K tests comparison between Inception and native > 1562 tests based on NIST Juliet 1.3 tests suite > 40 tests based on the Klockwork tests suite > Several demos for the STM32 L152RE and the LPC1850 DB1 boards > 1 Mbed TLS test suite > Several embedded operating systems (FreeRTOS, mini-arm-os)
| Maxim Integrated | EURECOM 72
Conlusion
- Extends analysis to mixed languages: assembly, C/C++, binary
- Fit well in chip life-cycle :
> test without hardware
> FPGA-based design > silicium
- Already used on proprietary real world Mask ROM code at Maxim
> Bugs found before mask manufacturing
- Inception is open-sourced:
> Getting started at https://inception-framework.github.io/inception/ > Github and docker
| Maxim Integrated | EURECOM 73
Questions?
| Maxim Integrated | EURECOM 74
Free icons license : https://icons8.com