AVR Workshops
AVR Workshops
Firmware
Reversing
and
Exploit
Development
for
AVR-‐based
Embedded
Devices
Alexander
@dark_k3y
Bolshev
Boris
@dukeBarman Ryutin
Agenda
Part
1:
Quick
RJMP to
AVR
+
Introduction
example
Part
2:
Pre-‐exploitation
Part
3:
Exploitation
and
ROP-‐chains
building
Part
4:
Post-‐exploitation
and
tricks
Thus:
If
you
have
a
question,
please
interrupt and
ask
immediately
Disclaimer:
1)
Training
is
VERY fast-‐paced
2)
Training
is
highly-‐practical
3)
You
may
encounter
information
overflow
4)
My
English
is
far
from
perfect
Image Credit: Marac Kolodzinski
Part
1:
What
is
AVR?
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
AVR
inside
home
automation
dimmer
Harvard
Architecture
Harvard
Architecture
• Physically
separated
storage
and
signal
pathways
for
instructions
and
data
• Originated
from
the
Harvard
Mark
I
relay-‐based
computer
…allows
the
contents
of
the
instruction
memory
to
be
accessed
as
if
it
were
data1
Image:
http://www.cs.jhu.edu/~jorgev/cs333/usbkey/uC_3.JPG
Note:
code
is
separated from
data
Memory
map
Memory:
registers
• R0-‐R25
– GPR
• X,Y,Z
– pair
“working”
registers,
e.g.
for
memory
addressing
operations
• I/O
registers
– for
accessing
different
“hardware”
Memory:
special
registers
• PC
– program
counter,
16-‐bit
register
LPM
command!
Memory
addressing
directions
• Direct
to
register
• Direct
to
I/O
• SRAM
direct
• SRAM
indirect (pre-‐ and
post-‐ increment)
• Flash
direct
Datasheets
are
your
best
friends!
Interrupts
• Interrupts
interrupt
normal
process
of
code
execution
for
handling
something
or
reacting
to
some
event
• Interrupt
handler
is
a
procedure
to
be
executed
after
interrupt;
address
stored
in
the
interrupt
vector
• Examples
of
interrupts:
- Timers
- Hardware
events
- Reset
AVR
assembly
Very
quickly
Instruction
types
• Arithmetic
and
logic
• Bit
manipulation/test
• Memory
manipulation
• Unconditional
jump/call
• Branch
commands
• SREG
manipulation
• Special
(watchdog,
etc)
Instruction
mnemonics
mov r16,r0 ; Copy r0 to r16
out PORTA, r16 ; Write r16 to PORTA
16-‐bit
long
“Intel
syntax”
(destination
before source)
A
bit
more
about
architecture
Fuses
and
Lock
Bits
• Several bytes of permanent storage
• Set internal hardware and features
configuration, including oscillator
(int or ext), bootloader, pins, ability
to debug/program, etc.
• 2 lock bits controls programming
protection.
AVR
bootloader – what
is
it?
• Part
of
code
that
starts
BEFORE RESET
interrupt.
• Could
be
used
for
self-‐programmable
(i.e.
without
external
device)
systems,
in
case
you
need
update
the
firmware
of
your
IoT device.
• Bootloader address
and
behavior
configured
via
FUSEs.
• BLB
lock
bits
controls
bootloader ability
to
update
application
and/or
bootloader parts
of
flash.
AVR
bootloaders
• Arduino
bootloader
• USB
bootloaders (AVRUSBBoot)
• Serial
programmer
bootloaders (STK500-‐compatible)
• Cryptobootloaders
•…
• Tons
of
them!
Watchdog
• Timer
that
could
be
used
to
interrupt
or
reset
device.
• Cleared
with
WDR instruction.
http://ardiri.com/blog/entries/20141028/watchdog.jpg
Development
for
AVR
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
JTAG
for
AVRs
AVR
JTAGIce3
cd /home/radare/workshop/ex1.1
avarice --mkI --jtag /dev/ttyUSB0 -p -e --file hello.hex
For
debugging:
avarice --mkI --jtag /dev/ttyUSB0 -p -e --file hello.hex -d :4242
Simulator
cd /home/radare/workshop/ex1.1_simulator
simulavr -d atmega128 -f hello.elf -F 16000000 -x -,E1,9600 -y -,E0,9600
For
debugging:
simulavr -d atmega128 -f hello.elf -F 16000000 -x -,E1,9600 -y -,E0,9600 -g
avr-gdb
(gdb) target remote :1212
Ex
1.2:
Blink!
cd /home/radare/workshop/ex1.2
avarice --mkI --jtag /dev/ttyUSB0 -p -e --file blink.hex
For
debugging:
avarice --mkI --jtag /dev/ttyUSB0 -p -e --file blink.hex -d :4242
avr-gdb
(gdb) target remote :4242
Part
2:
Pre-‐exploitation
You
have
a
device.
First
steps?
Fuzz
Decide
Determine
Search
for
Search
for
Acquire
and/or
what
you
target
I/O
debug
the
static
want platform point(s) point(s) firmware
analysis
Let’s
start
with
a
REAL
example
• Let’s
use
training
kit
board
as
an
example
• Imagine
that
you
know
nothing
about
it
• We
will
go
through
all
steps,
one
by
one
What
we
want?
To
start
with,
decide
what
you
want:
Complexity
• Abuse
of
functionality
• Read
something
from
EEPROM/Flash/SRAM
• Stay
persistent
Determine
target
platform
• Look
at
the
board
and
search
for
all
ICs…
CP2102
Atmega128
16AU
ESP8266EX
Digikey/Octopart/Google…
External
connectors
USB
Antenna
Search
for
I/O(s):
tools
Jtagulator
JTAG
Search
for
debug
interface(s):
tools
Or cheaper
cd ~/workshop/JTAGenum
make upload (click
reset
on
arduino just
before
it)
screen /dev/ttyACM0 115200
• Press
“s”
Search
for
debug
&
I/O:
real
device
Connector ICS
bus
Button 2
JTAGs
Ethernet ISPs
LEDs
Acquire
the
firmware
• From
vendor
web-‐site
J
• Sniffing
the
firmware
update
session
• From
device
itself
Acquiring
the
firmware:
sniff
it!
Acquiring
the
firmware:
JTAG
or
ISP
• Use
JTAG
or
ISP
programmer
to
connect
to
the
board
debug
ports
• Use:
- Atmel
Studio
- AVRDude
- Programmer-‐specific
software
to
read
flash
“Normal”
disassemblers:
• IDA
Pro
• Radare
IDA
PRO:
AVR
specifics
• Incorrect
AVR
elf-‐handling
• Incorrect
LPM
command
behavior
• Addressing
issues
• Sometimes
strange
output
...
• Still
usable,
but
“with
care”
Radare2
• Opensource reverse
engineering
framework
(RE,
debugger,
forensics)
• Crossplatform (Linux,Mac,Windows,QNX,Android,iOS,
…)
• Scripting
• A
lot
of
architectures
/
file-‐formats
•…
• Without
“habitual”
GUI
(c)
pancake
Radare2:
Tools
• radare2 • rarun2
• rabin2 • rax2
• radiff2 • r2agent
• rafind2 • ragg2
• rasm2 • rahash2
• r2pm • rasign2
Radare2:
Usage
• Install
from
git
#
git clone
https://github.com/radare/radare2
#
cd
radare2
#
sys/install.sh
• Packages
(yara,
retdec /
radeco decompilers,
…):
#
r2pm
-‐i radare2
• 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
Radare2:
Basic
commands
• 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
Best
combinations
for
AVR
RE
• Both
Radare2
and
IDA
Pro
have
pitfalls
when
working
with
AVR
• That’s
why
I am
using
the
following
combination
Here
we
will
focus
on
Radare2
+
GDB,
because
not
everyone
can
afford
latest
IDA
Pro
L
Ex
2.1:
Hello!
RE
cd /home/radare/workshop/ex2.1
avr-objcopy –I ihex –O binary hello.hex hello.bin
r2 –a avr hello.bin
Now
we
will
scrutinize
every
line of
disassembled
code.
Boring,
but
is
required
for
further
understanding
http://reallycuteanimals.co.uk/wp-‐content/uploads/2012/06/120519-‐cat-‐keyboard_thumb.jpg
Interrupts
vector
&&
init section
Interrupts
vector
Init section
main()
à
Program
halt
Memory
manipulation:
stack
push
push r14 ; save r14 on the Stack
What
is
the
0x3f,
0x3e,
0x3d
and
where
to
find
them?
Datasheets
are
your
best
friends!
(2)
P.
366
of
Atmega128L
datasheet
So,
what’s
going
on
here?
1
2
3
1. SREG
(Status
REGister)
is
cleared
(set
to
r1
value,
which
is
0x00)
2. SPL
ß r28
(0xFF)
3. SPH
ß r29
(0x10)
After
init:
SREG
=
0,
SP
=
0x10FF
=
4351(SRAM
limit)
Going
further
Memory
manipulation:
lds/sts
lds r2,0xFA00 ; r2 = *0xFA00
sts 0xFA00,r0 ; *0xFA00 = r0
Here:
1. *0x98 ß r1 (0x00)
2. r24 ß 0x67
3. *0x99 ß r24 (0x67)
Datasheets
are
your
best
friends!
(3)
P.
365
of
Atmega128L
datasheet
What
is
it
all
about
and
why
sts and
not
out?
UBRR1H
=
(
BAUD_PRESCALE
>>
8)
;
10929800 sts 0x0098, r1
UBRR1L
=
(
BAUD_PRESCALE
)
;
87e6 ldi r24, 0x67
80939900 sts 0x0099, r24
breq 10 ; Z ? PC ← PC + 1 + 10
brne -4 ; !Z ? PC ← PC + 1 - 4
…
Why
-‐4?
UDR1
=
byte;
Conditional
“skip”
sbrc r0, 7 ; skip if bit 7 in r0 cleared
Direct
Indirect
Memory
manipulation:
flash
lpm r16, Z ; r16 = *(r31:r30), but from flash
cd /home/radare/workshop/ex2.2
avr-objcopy –I ihex –O binary blink.hex blink.bin
r2 –a avr blink.bin
Questions:
1. Identify
main()
function,
define
and
rename
it
2. Find
the
LED
switching
command
3. What
type
of
delay
is
used
and
why
accuracy
of
MCU
frequency
important?
4. Locate
interrupt
vector
and
init code,
explain
what
happens
inside
init code
Reversing:
function
szignatures
• Majority
of
firmware
contains
zero
or
little
strings.
• How
to
start?
• Use
function
signatures.
• However,
in
AVR
world
signatures
may
be
to
vary.
• Be
prepared
to
guess
target
compiler/library/RTOS
and
options…
or
bruteforce it.
• In
R2,
signatures
are
called
zignatures.
Working
with
zignatures
Embedded
code
priorities
• Size
• Speed
• Hardware
limits
• Redundancy
•…
•…
•…
•…
• Security
Fuzzing specifics
• Fuzzing
is
a
fuzzing.
Everywhere.
• But…
we’re
in embedded
world
• Sometimes
you
can detect
crash
through
test/debug
UART
or
pins
• In
most
cases,
you
can
detect
crash
only
by
noticing
that
device
is
no
longer
response
• Moreover,
watchdog
timer can
limit
your
detection
capabilities
by
resetting
the
device
• So
how
to
detect
crash?
Fuzzing:
ways
to
detect
crash
• JTAG
debugger
– break
on
RESET
• External
analysis
of
functionality
– detect
execution
pauses
• Detect
bootloader/initialization
code
(e.g.
for
SRAM)
behavior
with
logic
analyzer
and/or
FPGA
• Detect
power
consumption
change
with
oscilloscope/DAQ
Sometimes
Arduino
is
enough
to
detect
• I2C and
SPI
init sequences
could
be
captured
by
Arduino
GPIOs
• In
case
bootloader is
slow
and
has
~1
second
loading
delay,
this
power
consumption
reduction
could
be reliably
detected
with
cheap
current
sensor,
e.g.:
cd /home/radare/workshop/ex3.1
avarice --mkI --jtag /dev/ttyUSB0 -p -e --file build-
crumbuino128/ex3.1.hex -d :4242
http://www.atmel.com/webdoc/AVRLibcReferenceManual/malloc_1malloc_tunables.html
Memory
maps
– external
SRAM/separated
stack
Memory
maps
– external
SRAM/mixed
stack
Detecting
“standard”
functions
• In
AVR
world
there
are
a
lot
of
different
compilers,
libraries
and
even
RToSes
• Thus,
“standard”
function
could
vary
• More
bad
news:
memory
model
and
optimization
options
can
change
function
• The
best
approach
is
to
try
to
detect
functions
like
malloc/str(n)cpy
and
then
find
the
exact
compiler/options
that
generates
this
code
• After
that,
use
function
signatures
to
restore
the
rest
of
the
code
• In
Radare2,
you
could
use
zignatures or
Yara
Example
3.3
More
complex
ROP
Exercise
3.1
ret
2
function
Build
exploit
that
starts
with
ABC
but
calls
switchgreen()
function
Exercise
3.3
Print
something
else
3.3.1
Build
exploit
that
prints
“a
few
seconds…”
3.3.2
(homework)
Build
exploit
that
prints
“blink
a
few
seconds…”
Ex
3.4
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
WiFi “esp_<your3digitnumber>”
(password:
1234567890)
and
type
http://192.168.4.1
in
your
browser
Example
3.4
Blink
using
HTTP
GET
Exercise
3.4
UARTing using
HTTP
query
Exercise
3.5
Blink
using
HTTP
Post
(homework)
It is
possible
to
construct
ROP
with
a
debugger…
…But
if
you
don’t
have
one,
how
could
you
determine
the
overflow
point?
cd /home/radare/workshop/ex_arduino
make upload (click
reset
on
arduino just
before
it)
Don’t
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
coding/Don’t
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 (but
it
won’t
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
modern
MCUs
(more
secure
against
various
hardware
attacks)
• Use
external
safety
controls/processors