An introduction to exploit development.
I gave this talk at Hack the North 2014, and most of this information is pulled out of classics like Smashing the Stack for Fun and Profit, so there shouldn't be anything novel in here.
4. Agenda
1. Anatomy of a stack
2. Smashing it
3. Real (wo)men program
in shellcode
4. Canaries, DEP, and
ASLR, oh my!
5. Hack the planet.
5. WTF is a stack?!?
● Three types of memory regions:
a. Text
Program code, read-only
b. Data
Static variables
The heap
c. Stack
Where the magic happens
6. Data Structures 101 - Stacks
● An abstract data type with two operations
o PUSH - Adds an element to the start of a collection
o POP - Removes an element from the end of a
collection
● Last-In-First-Out
o Imagine a stack of paper
7. ...and that’s useful because?
● Used to implement
functions at a low-level
● Returning from
procedures,
passing arguments,
etc
8. Calling a Function
void foo(int a, int b) {
char buffer[10];
}
void main() {
foo(1, 2);
}
● Push the arguments
onto the stack, in
reverse order
● Push the instruction
pointer onto the stack
● Allocate space for the
variables in foo
16. Returning From a Function
1. POP the old frame
pointer off FP
2. Set SP to this
value
3. POP the return
address off the
stack
4. Jump to this address
Old Frame Pointer (EBP)
Return Address (EIP)
1
2
FP
12-Byte Buffer
SP
Heap
17. What does this mean?
● If unchecked, the buffer can overrun into the rest of the
stack!
● Buffer overflow attack
o Overwrite return address
o Overwrite local variables
o Own the system.
● What if we fill the buffer with:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA….
19. Returning Fr- wait what?
void bar() {
printf(“Hack the North!”);
}
void foo(int a, int b) {
char buffer[10];
int *ret;
ret = buffer + 12;
(*ret) = &bar;
}
● foo overwrites an
address after the buffer
to point to bar
● We just overwrote foo’s
return address!
● An attacker can use this
for evil.
o Assume the buffer is filled with
unchecked user input
20. Shellcode, or How I learned to Stop Worrying and Love the Compiler
● By overwriting the return address, we can run any code
in the program
o What if the code we want isn’t in the program?
o Add it! Put our code in the buffer, and jump to it
● We need bytecode that will spawn a shell - shellcode!
22. WTF does that mean?
0x8000130 <main>: pushl %ebp
0x8000131 <main+1>: movl %esp,%ebp
0x8000133 <main+3>: subl $0x8,%esp
0x8000136 <main+6>: movl $0x80027b8,0xfffffff8(%ebp)
0x800013d <main+13>: movl $0x0,0xfffffffc(%ebp)
0x8000144 <main+20>: pushl $0x0
0x8000146 <main+22>: leal 0xfffffff8(%ebp),%eax
0x8000149 <main+25>: pushl %eax
0x800014a <main+26>: movl 0xfffffff8(%ebp),%eax
0x800014d <main+29>: pushl %eax
0x800014e <main+30>: call 0x80002bc <__execve>
0x8000153 <main+35>: addl $0xc,%esp
0x8000156 <main+38>: movl %ebp,%esp
0x8000158 <main+40>: popl %ebp
0x8000159 <main+41>: ret
0x8000130 <main>: Save the frame pointer
0x8000131 <main+1>: Move the stack pointer
0x8000133 <main+3>: Allocate space for the ‘name’ buffer
0x8000136 <main+6>: Copy the address of “/bin/sh” into the
buffer
0x800013d <main+13>: Copy NULL into the buffer
0x8000144 <main+20>: Push NULL onto the stack
0x8000146 <main+22>: Load the address of our buffer into EAX
0x8000149 <main+25>: Push that address onto the stack
0x800014a <main+26>: Load the address of ‘/bin/sh’ into EAX
0x800014d <main+29>: Push that address onto the stack
0x800014e <main+30>: Call execve
23. And now for execve...
● Disassemble execve too
● Not going to show it here, but go through the same
process.
● We need…
o EAX = 0xB
o ECX points to “/bin/sh”
o EDX points to NULL
● Then call “int $0x80”
24. Let’s write that in assembly...
jmp 0x2a
popl %esi
movl %esi,0x8(%esi)
movb $0x0,0x7(%esi)
movl $0x0,0xc(%esi)
movl $0xb,%eax
movl %esi,%ebx
leal 0x8(%esi),%ecx
leal 0xc(%esi),%edx
int $0x80
.string "/bin/sh"
● Compile this with
NASM, and grab the
hexadecimal
representation…
● xebx2ax5ex89x76
x08xc6x46x07x00
xc7x46x0cx00x00
x00… etc
● Watch this.
26. Putting It Together
● Find a buffer
overflow
● Find a way of
exploiting it
● Fill some buffer
with shellcode
● Use your overflow
to jump to it
27. It’s not that easy.
● Nowadays, operating systems are smarter than that
● Shellcode restrictions
o No NULL bytes allowed
o Only alphanumeric characters, etc
● Stack Canaries
● Address Space Layout Randomization
● Data Execution Prevention
● We can defeat all of these methods.
28. Stack Canaries
● Essentially checksums
● Placed after a buffer
o Overflowing the buffer will overwrite the canary
o If the canary is wrong, handle the overflow
● Generated by the compiler.
● Use another exploit to leak memory
o printf format string exploits for example
29. ASLR
● At runtime, randomize the positions of
important memory regions
o The stack, the heap, data segment, etc
● Like stack canaries, need a memory leak to
bypass
o Leak the address of a buffer
o Create a NOP-sled and guess
o Plenty of techniques
30. Data Execution Prevention
● Mark memory segments as either writable or
executable
o Never both!
● We can’t put our shellcode on the stack
anymore.
● Use return-oriented programming
31. Return-Oriented Programming
● Construct our payload entirely of “Gadgets”
found in the existing codes
o Sub-sequences of assembly found at the end of
existing functions
● Chain them together by overwriting return
addresses on the stack
● Always possible!*
32. Nothing is Safe.
● Exploit development is hard.
o Really hard.
o Target architectures you’ve never used before
o Fail cleanly to avoid detection
● But!
o No protection is infallible
o It’s fun. Like, really fun. More on this later.
33. You Can (and should) do it!
● Capture the Flag - competitive hacking
o The hackathons of security
o There’s always one going on
CSAW is running right now, it’s for college
students with no security experience
● Incredibly fun problems.
o For example...
34. Polyglot
● Write an exploit
that will run on four
machines
o x86
o ARM Little-Endian
o ARM Big-Endian
o PowerPC
● Insane implications
for the internet of
things
● Read my talk on
solving it with graph
theory
35. Getting Started
● Micro Corruption - a 20 problem CTF built by
Square and Matasano Security for teaching
exploit development
● Compete! Right now! Seriously, this
weekend!
o CSAW - You can solve some of these, I promise.