BUFFER OVERFLOWS 101
SOME 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 Registers
Small 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 Pointer
Always points to the memory address of the next
instruction to be executed by the CPU
EIP - Instruction Pointer
Always 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 EBP
ret address
main
High Mem Address
Low Mem Address
EBP
ESP
Stack - Foo Function Called
saved EBP
ret address
main
High Mem Address
Low Mem Address
EBPESP
Stack - Foo Function Called
10 bytes
reserved for A
saved EBP
ret address
main
High Mem Address
Low Mem Address
EBP
ESP
Stack - strcopy()
Assume we executed our program with an argument of “AAAAAAAAAA”
AAAA

AAAA

AA
saved EBP
ret 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”
AAAA

AAAA

AA
AAAA
AAAA
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”
AAAA

AAAA

AA
AAAA
AAAA
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”
AAAA

AAAA

AA
AAAA
AAAA
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”
AAAA

AAAA

AA
AAAA
AAAA
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 offset
Using 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?
MSFVENOM
MSFPAYLOAD 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 address
You 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 Crafted

Buffer Overflow
DEMO?
THIS WILL PROBABLY END IN FLAMES
@0XKTWO
K2@KORROSIVESECURITY.COM

Buffer Overflows 101: Some Assembly Required

  • 1.
    BUFFER OVERFLOWS 101 SOMEASSEMBLY REQUIRED KORY KYZAR
  • 2.
    This talk is… Veryhigh level Restricted to stack buffer overflows Restricted to x86 architecture
  • 3.
    What’s a buffer? Abuffer 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
  • 4.
    Ok, and overflow? Storingmore 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.
  • 5.
  • 6.
  • 7.
  • 8.
    So how dowe score?
  • 9.
    So how dowe score? Slow down there Romeo.
  • 10.
    So how dowe score? Slow down there Romeo.
  • 11.
  • 12.
    General Purpose Registers Smallstorage 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.
  • 13.
    EBP - TheBase Pointer Used to track the base of the current frame (function). Can be used for other purposes
  • 14.
    ESP - TheStack 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
  • 15.
    EIP - InstructionPointer Always points to the memory address of the next instruction to be executed by the CPU
  • 16.
    EIP - InstructionPointer Always points to the memory address of the next instruction to be executed by the CPU
  • 17.
  • 18.
    What is thestack? Data structure that store values contiguously in memory Last In First Out structure ESP register marks the top of the stack
  • 19.
    Assume the belowprogram #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
  • 20.
    Stack - ProgramInitializes main High Mem Address Low Mem Address EBP ESP
  • 21.
    Stack - FooFunction Called ret address main High Mem Address Low Mem Address EBP ESP
  • 22.
    Stack - FooFunction Called ret address main High Mem Address Low Mem Address EBP ESP
  • 23.
    Stack - FooFunction Called saved EBP ret address main High Mem Address Low Mem Address EBP ESP
  • 24.
    Stack - FooFunction Called saved EBP ret address main High Mem Address Low Mem Address EBPESP
  • 25.
    Stack - FooFunction Called 10 bytes reserved for A saved EBP ret address main High Mem Address Low Mem Address EBP ESP
  • 26.
    Stack - strcopy()
Assumewe executed our program with an argument of “AAAAAAAAAA” AAAA
 AAAA
 AA saved EBP ret address main High Mem Address Low Mem Address EBP ESP
  • 27.
    Stack - strcopy()
Nowlet’s put our attacker hat on and execute our program with the argument “AAAAAAAAAAAAAAAAAA” AAAA
 AAAA
 AA AAAA AAAA main High Mem Address Low Mem Address EBP ESP
  • 28.
    Stack - strcopy()
Nowlet’s put our attacker hat on and execute our program with the argument “AAAAAAAAAAAAAAAAAA” AAAA
 AAAA
 AA AAAA AAAA main High Mem Address Low Mem Address EBP ESP
  • 29.
    Stack - strcopy()
Nowlet’s put our attacker hat on and execute our program with the argument “AAAAAAAAAAAAAAAAAA” AAAA
 AAAA
 AA AAAA AAAA main High Mem Address Low Mem Address EBP ESP
  • 30.
    Stack - strcopy()
Nowlet’s put our attacker hat on and execute our program with the argument “AAAAAAAAAAAAAAAAAA” AAAA
 AAAA
 AA AAAA AAAA 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.
  • 31.
  • 32.
    Buffer Overflow ShoppingList 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.
  • 33.
    The buffer youwere 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…?
  • 34.
    Finding the offset pattern_create.rbis a ruby script that creates a non repeating sequence of characters of a given length.
  • 35.
    Finding the offset Usingthe 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
  • 36.
    Shellcode Assembly code generated toexecute the payload of the attackers choice Shellcode must be carefully crafted by hand…RIGHT?
  • 37.
    Shellcode Assembly code generated toexecute the payload of the attackers choice Shellcode must be carefully crafted by hand…RIGHT?
  • 38.
    MSFVENOM MSFPAYLOAD AND MSFENCODEHAVE BEEN DEPRECATED IN FAVOR OF MSFVENOM
  • 39.
    So where dowe 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!?”
  • 40.
    So where dowe 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!?”
  • 41.
    Setting the RETaddress You 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.
  • 42.
    Putting it alltogether Padding NOP Sled Shellcode EIP = JMP ESP Padding Our Crafted
 Buffer Overflow
  • 43.
  • 44.