Course Link
You can find all the files required for the exercises on GitHub.
Prerequisites
You’ll need an X86 Machine, ensure that the following command outputs x86_64
uname -m
You’ll also need to install the tools Pwndbg, Pwntools and GCC Multilib with the following commands (this works under the assumption that you’re running a Kali Linux machine).
git clone https://github.com/pwndbg/pwndbg && \
cd pwndbg && ./setup.sh && \
sudo apt-get install -y gcc-multilib && \
sudo pip install ropper
You’ll also need to understand the basics of the Linux command line, and assembly and C.
Understanding The Stack Frame
The stack frame is a data structure used by a program’s runtime environment to manage function calls.
It contains the local variables, function parameters, and the return address which is created when a function is called and is destroyed when the function returns.
Let’s take for instance this sample C code here, and visualise how the stack looks one step at a time.
int main() {
char buffer[16];
gets(buffer);
return 0;
}
During the creation of a stack frame (function call), the return address is pushed onto the stack. Next, the address of EBP is pushed onto the stack. EBP is then moved to the location of ESP. Therefore, the first and only item on the stack is now the previous stack frame’s EBP address, while the return address is just below the stack.
push ret_addr
push ebp
mov ebp, esp
Now that the stack frame has been initialised, memory can be allocated. In this case, 16 bytes has been allocated to the stack (do note that the contents in the stack is whatever is present in that memory location at that point of time). The user inserts Lorem_ipsum_nec
to fill 16 bytes (15 bytes + 1 null byte).
sub esp 0x10
call gets
When the function exits, ESP is moved to where EBP is located (do note that the data written to the stack is not erased, it is just not tracked anymore). The one and only value that is popped from the stack to EBP is the location of EBP in the previous frame. Finally, the return address is popped into the instruction pointer and the program will continue execution on where it left off before the function call.
mov esp, ebp
pop ebp
pop eip
Excellent! We now understand how the stack frame works! Now let’s think about how we could exploit this. Could be perhaps write more than 16 bytes to the buffer? What if we could, what information would we like to overwrite?