lectures.alex.balgavy.eu

Lecture notes from university.
git clone git://git.alex.balgavy.eu/lectures.alex.balgavy.eu.git
Log | Files | Refs | Submodules

index.md (5180B)


      1 +++
      2 title = 'Exploitation for embedded systems'
      3 +++
      4 # Exploitation for embedded systems
      5 Typical embedded systems vulnerabilities:
      6 - weak access control/authentication
      7 - insecure config
      8 - vulnerable web interfaces
      9 - improper use of cryptography
     10 - programming errors:
     11   - can easily lead to buffer overflows, memory corruption
     12   - classic defenses (ASLR, canaries..) may not be present
     13 
     14 ## ARM architecture
     15 32-bit ("aarch32")
     16 - 32 bit regs and address space
     17 - little/big endian
     18 - 32-bit fixed-width instructions, 16-bit with Thumb instruction set
     19 - Thumb instruction set:
     20   - 15-bit encoding for improved code density
     21   - different processor states: "ARM" and "Thumb", switched via `bx` and `blx` instruction
     22 
     23 64-bit ("aarch64")
     24 - new instruction set, 64-bit regs and address space, 32-bit instruction length
     25 - user-space compatible with aarch32
     26 
     27 Application binary interface: Procedure Call Standard for the ARM Architecture (AAPCS)
     28 
     29 ![AAPCS table](aapcs.png)
     30 
     31 ARM Linux system calls:
     32 - arguments in r0-r6
     33 - return value r0
     34 - EABI: system call via `svc #0` instruction with call number in r7
     35 - OABI: system call via `swi NR` instruction
     36   - (`swi` and `svc` are the same instruction)
     37 
     38 
     39 ## ARMv6-M (Cortex-M0+)
     40 Thumb-2, so classic 32-bit ARM not supported.
     41 Has a built-in interrupt controller.
     42 Optional privileged/unprivileged and MPU (memory protection unit) support, both present on STM32G0B1RET6 (the board we have).
     43 
     44 Protected Memory System Architecture (PMSAv6):
     45 - provides memory protection unit (MPU)
     46   - separates flat address space into regions, smallest size 32 byte
     47   - implementation-dependent number of regions
     48   - requires privileged/unprivileged extension
     49 - can be configured via MMIO
     50 - provides access permissions and "execute never" (XN) bit
     51 
     52 ![PMSAv6 bits table](pmsav6-bits-table.png)
     53 
     54 Nested Vector Interrupt Controller (NVIC)
     55 - interrupts can occur (and be served) while an interrupt is already being handled
     56 - vector set up via VTOR
     57 - up to 32 external interrupts, 6 predefined exceptions
     58 
     59 xPSR: combined program status register:
     60 - application program status register (APSR): flags
     61 - interrupt program status register (IPSR): exception number
     62 - execution program status register (EPSR): thumb-bit (always 1)
     63 
     64 ![xPSR diagram](xpsr.png)
     65 
     66 Assembly:
     67 - arithmetic: `MNEMONIC{s} Rdest, Rsrc1, Rsrc2` (`Rsrc2` can also be `#imm`)
     68   - S-suffix updates condition flags, optional for ADD/SUB but mandatory for other arithmetic
     69   - examples:
     70     - `ADD r0, r1, r2`: `r0 = r1 + r2`
     71     - `EORS r0, r0, r0`: `r0 = r0 XOR r0`, updating flags
     72     - `SUBS r3, r4, #8`: `r3 = r4 - 8`, updating flags
     73 - `MOV`: can only mov to register, from register/immediate
     74   - `MOVT` moves immediate into top halfword
     75   - `MVN` moves negative (logical ones' complement)
     76 - `PUSH`
     77   - only registers
     78   - r0 to r12 and lr
     79   - example: `PUSH {r0, lr}`
     80 - `POP`
     81   - only registers
     82   - r0 to r12 and pc, or r0 to r12 and lr
     83   - examples: `POP {pc}`, `POP {r0-r6, lr}`
     84 - load/store: `LDR`, `STR`
     85   - `MNEMONIC Rdst, [Rsrc, #offset]` (`#offset` can also be register)
     86   - examples:
     87     - `LDR r0, [pc, #16]`: `r0 = *(pc+16)`
     88     - `STR r0, [r3, #0]`: `*r3 = r0`
     89 - branches:
     90   - `B`: branch relative to `pc`, allows `c` suffix for conditional
     91   - `BX` (branch and exchange): branch via register and exchange instruction set
     92     - "exchange instruction set" means to switch between THUMB and ARM mode
     93     - information of mode is stored in LSB of address
     94       - this works because in ARM, instructions always aligned on 2-byte or 4-byte granularity
     95     - ARMv6-M is Thumb-2 only, so all addresses need LSB set to 1
     96   - `BLX` (branch with link and exchange): set `lr` and branch relative to `pc` or via register
     97   - `BL` (branch with link): sets link register and branches relative to `pc`, like a `call`
     98 
     99 ## Exploitation techniques
    100 32-byte ARM usually has null bytes, but if you switch to thumb mode, instruction set compression makes null bytes unlikely:
    101 
    102 ```asm
    103 add r3, pc, #1
    104 bx r3
    105 ```
    106 
    107 Example shellcode (from [shell-storm](https://shell-storm.org)):
    108 
    109 ```asm
    110 add r3, pc, #1 // switch to thumb mode
    111 bx r3
    112 
    113 mov r0, pc // prepare arguments
    114 adds r0, #8
    115 subs r1, r1, r1 // r1 = 0
    116 subs r2, r2, r2 // r2 = 0
    117 
    118 movs r7, #11 // set syscall number
    119 svc 1 // execute syscall
    120 
    121 str r7, [r5, #32] // set up data: /bin/sh\0
    122 ldr r1, [r5, #100]
    123 strb r7, [r5, #12]
    124 lsls r0, r5, #1
    125 ```
    126 
    127 ROP on ARM:
    128 - if XN memory, or no OS with system call abstraction
    129 - strategy: overwrite stack with attacker-controlled data, chain "gadgets" to form meaningful program
    130 - usually fewer gadgets than x86, e.g. `pop {pc}` is much less common than `ret`
    131 - don't forget about Thumb-bit -- faults if set wrongly
    132 
    133 Heap exploitation:
    134 - implementations are application/device specific
    135 - usually fewer consistency checks than on desktop
    136 - often need reverse engineering heap implementation
    137   - might be on vendor-provided toolchain though
    138 
    139 Interrupt oriented programming:
    140 - interrupts push SR+PC onto stack, interrupts are nestable, and ROM resides below RAM in memory
    141 - so, stack growing exploit:
    142   - nest interrupts until RAM exceeded
    143   - stack grows into ROM
    144   - unable to write SR+PC, so subsequent return from IRQ will use value from ROM