Download - Buffer Overflows 101: Some Assembly Required
BUFFER OVERFLOWS 101SOME ASSEMBLY REQUIRED KORY KYZAR
This talk is…
Very high level
Restricted to stack buffer overflows
Restricted to x86 architecture
What’s a buffer?A buffer can be thought of as an allocated space in memory intended to hold a certain amount of data.
char A[10];
Allocate 10 bytes for the variable A
Ok, and overflow?Storing more data in the buffer than it is designed to hold.
t o o m u c h d a t a
strcopy(A, “toomuchdata”);
A
Data is written to memory outside the region allocated to A. We’ve overflowed the buffer.
So What Happens?
Crash
Score
So how do we score?
So how do we score?
Slow down there Romeo.
So how do we score?
Slow down there Romeo.
CPU REGISTERS
General Purpose RegistersSmall storage areas on the CPU that allow for very fast access.
x86 CPUs have 8 general purpose registers.
Basically, data from memory is loaded into a register, some form of processing is done, then the data is saved back to memory.
Main ones we are concerned with are EBP and ESP.
EIP is not considered a general purpose register, but we are interested in it as well.
EBP - The Base Pointer
Used to track the base of the current frame (function).
Can be used for other purposes
ESP - The Stack Pointer
Used to track the top of the stack.
As data is moved onto (PUSH) or off of (POP), the ESP register is incremented or decremented accordingly
EIP - Instruction PointerAlways points to the memory address of the next instruction to be executed by the CPU
EIP - Instruction PointerAlways points to the memory address of the next instruction to be executed by the CPU
THE STACK
What is the stack?
Data structure that store values contiguously in memory
Last In First Out structure
ESP register marks the top of the stack
Assume the below program#include <string.h> void foo (char *bar){ char A[10]; strcpy(A, bar); // no bounds checking} int main (int argc, char **argv){ foo(argv[1]);}
Program simply takes an argument on the
command line and copies it into a variable that is allocated 10 bytes (A)
https://en.wikipedia.org/wiki/Stack_buffer_overflow
Stack - Program Initializes
main
High Mem Address
Low Mem Address
EBP
ESP
Stack - Foo Function Called
ret address
main
High Mem Address
Low Mem Address
EBP
ESP
Stack - Foo Function Called
ret address
main
High Mem Address
Low Mem Address
EBP
ESP
Stack - Foo Function Called
saved EBPret address
main
High Mem Address
Low Mem Address
EBP
ESP
Stack - Foo Function Called
saved EBPret address
main
High Mem Address
Low Mem Address
EBPESP
Stack - Foo Function Called
10 bytes reserved for A
saved EBPret address
main
High Mem Address
Low Mem Address
EBP
ESP
Stack - strcopy()Assume we executed our program with an argument of “AAAAAAAAAA”
AAAAAAAA
AA
saved EBPret address
main
High Mem Address
Low Mem Address
EBP
ESP
Stack - strcopy()Now let’s put our attacker hat on and execute our program with the argument “AAAAAAAAAAAAAAAAAA”
AAAAAAAA
AAAAAAAAAA
main
High Mem Address
Low Mem Address
EBP
ESP
Stack - strcopy()Now let’s put our attacker hat on and execute our program with the argument “AAAAAAAAAAAAAAAAAA”
AAAAAAAA
AAAAAAAAAA
main
High Mem Address
Low Mem Address
EBP
ESP
Stack - strcopy()Now let’s put our attacker hat on and execute our program with the argument “AAAAAAAAAAAAAAAAAA”
AAAAAAAA
AAAAAAAAAA
main
High Mem Address
Low Mem Address
EBP
ESP
Stack - strcopy()Now let’s put our attacker hat on and execute our program with the argument “AAAAAAAAAAAAAAAAAA”
AAAAAAAA
AAAAAAAAAA
main
High Mem Address
Low Mem Address
EBP
ESP
We just overwrote the RET address,meaning we can tell the CPU
which instruction to execute next.
CONGRATULATIONS!YOU CRASHED.
Buffer Overflow Shopping List
We need…..
The offset in the buffer at which EIP is overwritten.
Code to perform the exploit.
A way to direct EIP to the code we want to run.
The buffer you were trying to overflow was larger than 10 bytes? Let’s say we have a large buffer of an unknown size.
We could write a fuzzer that submits an increasing number of “A”s and make note of the length that causes the crash.
But how do we know which of the “A”’s overwrote EIP?
What if…?
Finding the offset pattern_create.rb is a ruby script that creates a non repeating sequence of characters of a given length.
Finding the offsetUsing the string generated by pattern_create.rb as your input, you would analyze where the program crashed in a debugger. (i.e. Access violation when executing 30614239)
Then you would check where that series of characters was in string with pattern_offset.rb
Now you have the exact position in the buffer to place your return address
Shellcode
Assembly code generated to execute the payload of the attackers choice
Shellcode must be carefully crafted by hand…RIGHT?
Shellcode
Assembly code generated to execute the payload of the attackers choice
Shellcode must be carefully crafted by hand…RIGHT?
MSFVENOMMSFPAYLOAD AND MSFENCODE HAVE BEEN DEPRECATED IN FAVOR OF MSFVENOM
So where do we point EIP?
We need to get the CPU to execute our shellcode
“So just set EIP to the address at the beginning of your shellcode!?”
So where do we point EIP?
We need to get the CPU to execute our shellcode
“So just set EIP to the address at the beginning of your shellcode!?”
Setting the RET addressYou can’t hardcode the EIP address in since the program will be loaded into different places in memory at each execution.
JMP ESP - one of the most common methods of getting back to your shellcode is to point EIP to a JMP ESP command. This can be used since its relative.
This causes EIP to go to the address in the ESP register, which you should be able to use to access your shellcode.
Putting it all together
Padding
NOP Sled
Shellcode
EIP = JMP ESP
Padding
Our CraftedBuffer Overflow
DEMO?THIS WILL PROBABLY END IN FLAMES