Practical Reversing
Practical Reversing
Practical Reversing
; cat /dev/user(s)
Alexander Bolshev (@dark_key), Security
Researcher, Ph.D., Assistant Professor @ SPbETU
Agenda
Hour 1
Hours 2-3:
Part 2: Pre-exploitation
Part 3: Exploitation and ROP-chains building
Part 4: Post-exploitation and tricks
Hour 4:
Mitigations
CFP! (Powered by Roman Bazhin)
If you have a
question, please
interrupt and ask
immediately
Disclaimer:
1) Workshop is VERY fast-paced.
2) Workshop is highly-practical
3) You may encounter information
overflow
Image Credit: Marac Kolodzinski
AVR
Alf (Egil Bogen) and Vegard (Wollan)s RISC processor
Modified Harvard architecture 8-bit RISC single-chip microcontroller
Developed by Atmel in 1996 (now Dialog/Atmel)
http://www.eetimes.com/document.asp?doc_id=1323739&image_number=1
Harvard Architecture
Harvard Architecture
Physically separated storage and signal pathways for instructions and
data
Originated from the Harvard Mark I relay-based computer
1but
Introduction example:
Were still able to exploit!
AVR features
AVR-8
MCU (MicroController Unit) -- single computer chip designed for
embedded applications
Low-power
Integrated RAM and ROM (SRAM + EEPROM + Flash)
Some models could work with external SRAM
8-bit, word size is 16 bit (2 bytes)
Higher integration
Single core/Interrupts
Low-freq (<20MHz in most cases)
Higher Integration
Why Atmega128?
Old, but very widespread chip.
At90can128 popular analogue for CAN buses in automotive
application
Cheap JTAG programmer
Much SRAM == ideal for ROP-chain construction training
Image: http://www.cs.jhu.edu/~jorgev/cs333/usbkey/uC_3.JPG
Memory map
Memory: registers
R1-R25 GPR
X,Y,Z pair working
registers, e.g. for memory
addressing operations
I/O registers for accessing
different hardware
Memory addressing
SRAM/EEPROM 16-bit addressing, 8-bit element
Flash 16(8)-bit addressing, 16-bit element
LPM
command!
Interrupts
Interrupts normal process of code
execution for handling something
or reacting to some event
Interrupt handler procedure to
be executed after interrupt;
address stored in the interrupt
vector
Examples of interrupts:
Timers
Hardware events
Reset
AVR assembly
In a very quick
manner
Instruction types
Arithmetic and logic
Bit manipulation/test
Memory manipulation
Unconditional jump/call
Branch commands
SREG manipulation
Special (watchdog, etc)
Instruction mnemonics
mov
out
r16,r0
PORTA, r16
; Copy r0 to r16
; Write r16 to PORTA
16-bit long
Intel syntax (destination before source)
AVR bootloaders
Arduino bootloader
USB bootloaders (AVRUSBBoot)
Serial programmer bootloaders (STK500-compatible)
Cryptobootloaders
Tons of them!
Watchdog
Timer that could be used for interrupt or reset device.
Cleared with WDR instruction.
http://ardiri.com/blog/entries/20141028/watchdog.jpg
Atmel studio
AVR-GCC
Main compiler/debugger kit for the platform
Used by Atmel studio
Use AVR libc -- http://www.nongnu.org/avr-libc/
Several optimization options, several memory models
Other tools
Arduino
CodeVision AVR
IAR Embedded workbench
Debugging AVR
JTAG
Joint Test Action Group (JTAG)
Special debugging interface added to a chip
Allows testing, debugging, firmware manipulation and boundary
scanning.
Requires external hardware
AVR JTAGIce3
Avarice
Open-source interface between AVR JTAG and GDB
Also allow to flash/write eeprom, manipulate fuse and lock bits.
Could capture the exeuction flow to restore the firmware
Example usage:
avarice --program --file test.elf --part atmega128 --jtag /dev/ttyUSB0 :4444
AVR-GDB
Part of nongnu AVR gcc kit.
Roughly ported standard gdb to AVR platform
Doesnt understand Harvard architecture, i.e. to read flash you will
need to resolve it by reference of $pc:
(gdb) x/10b $pc + 100
Simulators
Atmel Studio simulator
Proteus simulator
Simavr
Simulavr
VM access:
Login: radare
Password: radare
Simulator
cd /home/radare/workshop/ex1.1_simulator
simulavr -P atmega128 -F 16000000 f build-crumbuino128/ex1.1.elf
avr-gdb
Ex 1.2: Blink!
Real hardware
cd /home/radare/workshop/ex1.2
avarice --mkI --jtag /dev/ttyUSB0 -p -e --file build-crumbuino128/ex1.2.hex -g :4242
avr-gdb
AVR RE
Radare2
Opensource reverse engineering framework (RE, debugger, forensics)
Crossplatform (Linux,Mac,Windows,QNX,Android,iOS, )
Scripting
A lot of Architectures / file-formats
Radare2. Tools
radare2
rabin2
radiff2
rafind2
rasm2
r2pm
rarun2
rax2
r2agent
ragg2
rahash2
rasign2
Radare2. Using
Install from git
# git clone https://github.com/radare/radare2
# cd radare2
# sys/install.sh
Console commands
# r2 -d /bin/ls debugging
# r2 a avr sample.bin architecture
# r2 b 16 sample.bin specify register size in bits
# r2 sample.bin i script include script
aaa analyze
axt xrefs
s seek
p disassemble
~ - grep
! run shell commands
/ search
/R search ROP
/c search instruction
? help
Radare2. Disassembling
p?
pd/pD - dissamble
pi/pI print instructions
Examples:
> pd 35 @ function
Radare2. Options
~/.radarerc
e asm.describe=true
e scr.utf8=true
e asm.midflags=true
e asm.emu=true
eco solarized
Radare2. Interfaces
ASCII VV
Visual panels V! (vim like controls)
Web-server r2 -c=H file
Bokken
Part 2: Pre-exploitation
Decide
what you
want
Determine
target
platform
Search for
I/O
point(s)
Search for
debug
point(s)
Acquire
the
firmware
Fuzz
and/or
static
analysis
What we want?
Complexity
ESP8266EX
Atmega128 16AU
Digikey/Octopart/Google
External connectors
UART
External connectors
Antenna
Jtagulator
Bus pirate
Arduino
JTAG
Or cheaper
Jtagulator
Arduino + JTAGEnum
JTAGEnum against
Atmega128 demoboard
Connector
Button
2 JTAGs
ISPs
Ethernet
LEDs
Ex 2.1: Hello! RE
Arithmetic instructions
add
add
and
clr
inc
neg
r1,r2
r28,r28
r2,r3
r18
r0
r0
;
;
;
;
;
;
r1
r28
r2
r18
r0
r0
=
=
=
=
=
=
r1 + r2
r28 + r28
r2 & r3
0
r0 + 1
-r0
r0
r1
r15
ror
r16
cbr
sbr
cbi
r18,1
r16, 3
$16, 1
; r0 << 2
; r1 >> 2
; cyclic shift r16 bits to the
left
; cyclic shift r16 bits to the
right
; clear bit 1 in r18
; set bits 0 and 1 in r16
; PORTB[1] = 0
Memory manipulation
mov
ldi
lds
sts
st
st
std
in
out
r1, r2
r0, 10
r2,$FA00
$FA00,r0
Z, r0
Z, r1
Z+5, r2
r15, $16
$16, r0
;
;
;
;
;
;
;
;
;
r1 = r2
r0 = 10
r2 = *0xFA00
*0xFA00 = r0
*Z(r31:r30) = r0
*Z-- = r0
*(Z+5) = r2
r15 = PORTB
PORTB = r0
Same
for LD*
r14
pop
r15
Unconditional jump/call
jmp
rjmp
$ABC1
5
; PC = 0xABC1
; PC = PC + 5 + 1
call
$ABC1
; push PC+2
; jmp $ABC
ret
; pop PC
Carry flag
Zero flag
Negative flag
twos complement oVerflow indicator
N V, for Signed tests
Half carry flag
Transfer bit (BLD/BST)
global Interrupt enable/disable flag
Conditional jump
cpse
r1, r0
; r1 == r2 ?
PC PC + 2 : PC PC + 3
breq
brne
10
11
; Z ? PC PC + 1 + 10
; !Z ? PC PC + 1 + 10
SREG manipulations
sec/clc set/clear carry
sei/cli set/clear global interruption flag
se*/cl* set/clear * flag in SRGE
Special
break debugger break
nop no operation
sleep enter sleep mode
wdr watchdog reset
Ex 2.2: Blink! RE
Real hardware & Simulator
cd /home/radare/workshop/ex2.1
Questions:
1. Identify main() function and describe it using af
2. Find the LED switching command
3. What type of delay is used and why accurate frequency is required?
4. Locate interrupt vector and init code, explain what happens inside init code.
Security
Fuzzing specifics
Fuzzing is Fuzzing. Everywhere.
But were in embedded world.
Sometimes you could detect crash through test/debug UART or pins
In most cases, you could detect crash only by noticing, that device is
no longer response
Moreover, watchdog timer will could limit your detection capabilities,
because it will reset device.
So how to detect crash?
+
SparkFun Low Current Sensor Breakout - ACS712
https://www.sparkfun.com/products/8883
Part 3: Exploitation
Notice: Arduino
The next examples/exercises will be based upon Arduio libc (in fact,
Non-GNU AVR libc + Arduino wiring libs)
Were using Arduino because its complex, full of gadgets but free
(against IAR or CV which are also complex and full of gadgets)
Also, Arduino is fairly popular today, due to enormous number of
libraries and quick start (e.g. quick bugs)
Ex 3.1 3.3
Real hardware
cd /home/radare/workshop/ex3.1
avarice --mkI --jtag /dev/ttyUSB0 -p -e --file build-crumbuino128/ex3.1.hex -g :4242
avr-gdb
Simulator
cd /home/radare/workshop/ex3.1_simulator
simulavr -P atmega128 -F 16000000 f build-crumbuino128/ex3.1.elf
avr-gdb
Or: node exploit.js
Example
For
int func (char a, long b);
a will be passed in R24.
b will be passed in R20, R21, R22 and R23 with the LSB in R20 and the
MSB in R23.
the result is returned in R24 (LSB) and R25 (MSB).
http://www.atmel.com/webdoc/AVRLibcReferenceManual/malloc_1malloc_tunables.html
Ex 3.4
Real hardware
cd /home/radare/workshop/ex3.1
in Blink.ino change APNAME constant from esp_123 to esp_your3digitnumber
make
avr-objdump I ihex O binary build-crumbuino128/ex3.4.hex ex3.4.bin
avarice --mkI --jtag /dev/ttyUSB0 -p -e --file build-crumbuino128/ex3.4.hex -g :4242
avr-gdb
Connect to esp_your3digitnumber and type http://192.168.4.1 in your browser
Simulator
cd /home/radare/workshop/ex3.4_simulator
On 1st terminal: node exploit.js
On 2nd terminal: tail f serial1.txt
Part 4: Post-exploitation
&& Tricks
Reading EEPROM/Flash
Ok, in most cases its almost easy to find gadget(s) that reads byte
from EEPROM or flash and stores it somewhere.
We could send it back over UART or any external channel gadgets
Not always possible, but there are good chances
Writing flash
Writing flash is locked during normal program execution
However, if you use jump-to-bootloader trick, you could write flash
from bootloader sections.
To do this, you need bootloader of that has enough gadgets.
However, modern bootloaders are big and sometimes you could be
lucky (e.g. Arduino bootloader)
Remember to disable interrupts before jumping to bootloader.
Infinite-ROP trick*
1. Set array to some upper stack address (A1) and N to some value
(128/256/etc) and JMP to read(..)
2. Output ROP-chain from UART to A1.
3. Set SPH/SPL to A1 (gadgets could be got from init code)
4. JMP to RET.
5. ???
6. Profit!
Dont forget to include 1 and 3-4 gadgets in the ROP-chain that you are
sending by UART.
*Possible on firmwares with read(array, N) from UART functions and complex init code
Mitigations
Mitigations (software)
Safe code/Dont trust external data (read 24 deadly sins of computer
security)
Reduce code size (less code -> less ROP gadgets)
Use rjmp/jmp instead of call/ret (ofc, it wont save you from ret2
function)
Use inconvenient memory models with small stack
Use stack canaries in your RTOS
Limit external libraries
Use watchdogs
Periodically check stack limits (to avoid stack expansion tricks)
Mitigations (hardware)
Disable JTAG/debuggers/etc, remove pins/wires of JTAG/ISP/UART
Write lock bits to 0/0
Use multilayered PCBs
Use external/hardware watchdogs
Use new ICs (more secure against various hardware attacks)
Use external safety controls/processors
And last, but not least:
Beware of Dmitry Nedospasov ;)
Part 4: Post-exploitation
&& Tricks
Conclusions
RCE on embedded systems isnt so hard as it seems.
Abusing of functionality is the main consequence of such attacks
However, more scary things like extracting cipherkeys or rewriting the
flash is possible
When developing embedded system remember that security also
should be part of the Software DLC process.
Books/links
.. AVR
Atmega128 disasm thread: http://www.avrfreaks.net/forum/disassembly-atmega128-bin-file
Exploiting buffer overflows on arduino: http://electronics.stackexchange.com/questions/78880/exploitingstack-buffer-overflows-on-an-arduino
Code Injection Attacks on Harvard-Architecture Devices: http://arxiv.org/pdf/0901.3482.pdf
Radare2. Links
http://radare.org
https://github.com/pwntester/cheatsheets/blob/master/radare2.
md
https://www.gitbook.com/book/radare/radare2book/details
https://github.com/radare/radare2ida
Any Q?
@dark_k3y
@dukeBarman
http://radare.org/r/
http://dsec.ru
http://eltech.ru
http://zorsecurity.ru