Push updates...
1. Cleanup/Linting/Tweaks/Fixes/etc - Default Prettier config w/ 999 line length - Default eslint config "problems" list trimmed down 2. Fixed corrupt pointer cleanup by abc 3. Fixed `ip6po_rthdr` offset for PS5 by abc 4. Verified the number of blocking requests needed to be two by abc 5. Only run kernel exploit once by checking setuid by @JTAG7371 6. Kernel patches from pOOBs4 by @ChendoChap (Ported for 8.00-9.60) 7. Payload loader from pOOBs4 by @ChendoChap 8. Restore syscall 661 (`sys_aio_submit()`) after patching by @janisslsm 9. Add `PROT_READ`, `PROT_WRITE`, `PROT_EXEC` constants for payload loader by @janisslsm The ONLY things that should need changes are the `/rop/ps4/*.mjs` files (850, 900, and 950). Firmware 8.00 appears to be stable/have a good success rate now.
This commit is contained in:
168
src/send.mjs
168
src/send.mjs
@@ -55,109 +55,96 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
// For a LibcInternal import we searched for strlen() but you can search for
|
||||
// any libc function such as memcpy().
|
||||
|
||||
import * as config from './config.mjs';
|
||||
import * as config from "./config.mjs";
|
||||
|
||||
import { Int } from './module/int64.mjs';
|
||||
import { Addr, mem } from './module/mem.mjs';
|
||||
import { make_buffer, find_base, resolve_import } from './module/memtools.mjs';
|
||||
import { KB, MB } from './module/offset.mjs';
|
||||
import { Int } from "./module/int64.mjs";
|
||||
import { Addr, mem } from "./module/mem.mjs";
|
||||
import { make_buffer, find_base, resolve_import } from "./module/memtools.mjs";
|
||||
import { KB, MB } from "./module/offset.mjs";
|
||||
|
||||
import {
|
||||
log,
|
||||
align,
|
||||
die,
|
||||
send,
|
||||
} from './module/utils.mjs';
|
||||
import { log, align, die, send } from "./module/utils.mjs";
|
||||
|
||||
import * as rw from './module/rw.mjs';
|
||||
import * as o from './module/offset.mjs';
|
||||
import * as rw from "./module/rw.mjs";
|
||||
import * as o from "./module/offset.mjs";
|
||||
|
||||
const origin = window.origin;
|
||||
const port = '8000';
|
||||
const port = "8000";
|
||||
const url = `${origin}:${port}`;
|
||||
|
||||
const textarea = document.createElement('textarea');
|
||||
const textarea = document.createElement("textarea");
|
||||
// JSObject
|
||||
const js_textarea = mem.addrof(textarea);
|
||||
|
||||
// boundaries of the .text + PT_SCE_RELRO portion of a module
|
||||
function get_boundaries(leak) {
|
||||
const lib_base = find_base(leak, true, true);
|
||||
const lib_end = find_base(leak, false, false);
|
||||
const lib_base = find_base(leak, true, true);
|
||||
const lib_end = find_base(leak, false, false);
|
||||
|
||||
return [lib_base, lib_end]
|
||||
return [lib_base, lib_end];
|
||||
}
|
||||
|
||||
// dump a module's .text and PT_SCE_RELRO segments only
|
||||
function dump(name, lib_base, lib_end) {
|
||||
// assumed size < 4GB
|
||||
const lib_size = lib_end.sub(lib_base).lo;
|
||||
log(`${name} base: ${lib_base}`);
|
||||
log(`${name} size: ${lib_size}`);
|
||||
const lib = make_buffer(
|
||||
lib_base,
|
||||
lib_size
|
||||
);
|
||||
send(
|
||||
url,
|
||||
lib,
|
||||
`${name}.sprx.text_${lib_base}.bin`,
|
||||
() => log(`${name} sent`)
|
||||
);
|
||||
// assumed size < 4GB
|
||||
const lib_size = lib_end.sub(lib_base).lo;
|
||||
log(`${name} base: ${lib_base}`);
|
||||
log(`${name} size: ${lib_size}`);
|
||||
const lib = make_buffer(lib_base, lib_size);
|
||||
send(url, lib, `${name}.sprx.text_${lib_base}.bin`, () => log(`${name} sent`));
|
||||
}
|
||||
|
||||
// dump for libSceNKWebKit.sprx
|
||||
function dump_libwebkit() {
|
||||
let addr = js_textarea;
|
||||
// WebCore::HTMLTextAreaElement
|
||||
addr = addr.readp(0x18);
|
||||
let addr = js_textarea;
|
||||
// WebCore::HTMLTextAreaElement
|
||||
addr = addr.readp(0x18);
|
||||
|
||||
// vtable for WebCore::HTMLTextAreaElement
|
||||
// in PT_SCE_RELRO segment (p_type = 0x6100_0010)
|
||||
addr = addr.readp(0);
|
||||
// vtable for WebCore::HTMLTextAreaElement
|
||||
// in PT_SCE_RELRO segment (p_type = 0x6100_0010)
|
||||
addr = addr.readp(0);
|
||||
|
||||
log(`vtable: ${addr}`);
|
||||
const vtable = make_buffer(addr, 0x400);
|
||||
send(url, vtable, `vtable_${addr}.bin`, () => log('vtable sent'));
|
||||
log(`vtable: ${addr}`);
|
||||
const vtable = make_buffer(addr, 0x400);
|
||||
send(url, vtable, `vtable_${addr}.bin`, () => log("vtable sent"));
|
||||
|
||||
const [lib_base, lib_end] = get_boundaries(addr);
|
||||
dump('libSceNKWebKit', lib_base, lib_end);
|
||||
const [lib_base, lib_end] = get_boundaries(addr);
|
||||
dump("libSceNKWebKit", lib_base, lib_end);
|
||||
|
||||
return lib_base;
|
||||
return lib_base;
|
||||
}
|
||||
|
||||
// dump for libkernel_web.sprx
|
||||
function dump_libkernel(libwebkit_base) {
|
||||
const offset = 0x8d8;
|
||||
const vtable_p = js_textarea.readp(0x18).readp(0);
|
||||
// __stack_chk_fail
|
||||
const stack_chk_fail_import = libwebkit_base.add(offset);
|
||||
const offset = 0x8d8;
|
||||
const vtable_p = js_textarea.readp(0x18).readp(0);
|
||||
// __stack_chk_fail
|
||||
const stack_chk_fail_import = libwebkit_base.add(offset);
|
||||
|
||||
const libkernel_leak = resolve_import(stack_chk_fail_import);
|
||||
log(`__stack_chk_fail import: ${libkernel_leak}`);
|
||||
const libkernel_leak = resolve_import(stack_chk_fail_import);
|
||||
log(`__stack_chk_fail import: ${libkernel_leak}`);
|
||||
|
||||
const [lib_base, lib_end] = get_boundaries(libkernel_leak);
|
||||
dump('libkernel_web', lib_base, lib_end);
|
||||
const [lib_base, lib_end] = get_boundaries(libkernel_leak);
|
||||
dump("libkernel_web", lib_base, lib_end);
|
||||
}
|
||||
|
||||
// dump for libSceLibcInternal.sprx
|
||||
function dump_libc(libwebkit_base) {
|
||||
const offset = 0x918;
|
||||
const vtable_p = js_textarea.readp(0x18).readp(0);
|
||||
// strlen
|
||||
const strlen_import = libwebkit_base.add(offset);
|
||||
const offset = 0x918;
|
||||
const vtable_p = js_textarea.readp(0x18).readp(0);
|
||||
// strlen
|
||||
const strlen_import = libwebkit_base.add(offset);
|
||||
|
||||
const libc_leak = resolve_import(strlen_import);
|
||||
log(`strlen import: ${libc_leak}`);
|
||||
const libc_leak = resolve_import(strlen_import);
|
||||
log(`strlen import: ${libc_leak}`);
|
||||
|
||||
const [lib_base, lib_end] = get_boundaries(libc_leak);
|
||||
dump('libSceLibcInternal', lib_base, lib_end);
|
||||
const [lib_base, lib_end] = get_boundaries(libc_leak);
|
||||
dump("libSceLibcInternal", lib_base, lib_end);
|
||||
}
|
||||
|
||||
function dump_webkit() {
|
||||
const libwebkit_base = dump_libwebkit();
|
||||
dump_libkernel(libwebkit_base);
|
||||
dump_libc(libwebkit_base);
|
||||
const libwebkit_base = dump_libwebkit();
|
||||
dump_libkernel(libwebkit_base);
|
||||
dump_libc(libwebkit_base);
|
||||
}
|
||||
|
||||
// See globalFuncEval() from
|
||||
@@ -183,23 +170,18 @@ function dump_webkit() {
|
||||
// For example, the expression "eval(1)" has the JSValue encoding of 1 passed
|
||||
// to *(rdi + 0x30).
|
||||
function dump_eval() {
|
||||
let addr = js_textarea;
|
||||
// WebCore::HTMLTextAreaElement
|
||||
addr = addr.readp(0x18);
|
||||
let addr = js_textarea;
|
||||
// WebCore::HTMLTextAreaElement
|
||||
addr = addr.readp(0x18);
|
||||
|
||||
// vtable for WebCore::HTMLTextAreaElement
|
||||
// in PT_SCE_RELRO segment (p_type = 0x6100_0010)
|
||||
addr = addr.readp(0);
|
||||
// vtable for WebCore::HTMLTextAreaElement
|
||||
// in PT_SCE_RELRO segment (p_type = 0x6100_0010)
|
||||
addr = addr.readp(0);
|
||||
|
||||
const libwebkit_base = find_base(addr, true, true);
|
||||
const impl = mem.addrof(eval).readp(0x18).readp(0x38);
|
||||
const offset = impl.sub(libwebkit_base);
|
||||
send(
|
||||
url,
|
||||
make_buffer(impl, 0x800),
|
||||
`eval_dump_offset_${offset}.bin`,
|
||||
() => log('sent')
|
||||
);
|
||||
const libwebkit_base = find_base(addr, true, true);
|
||||
const impl = mem.addrof(eval).readp(0x18).readp(0x38);
|
||||
const offset = impl.sub(libwebkit_base);
|
||||
send(url, make_buffer(impl, 0x800), `eval_dump_offset_${offset}.bin`, () => log("sent"));
|
||||
}
|
||||
|
||||
// Initially we just used the vtable offset from pOOBs4 (0x1c8) and tested if
|
||||
@@ -207,25 +189,17 @@ function dump_eval() {
|
||||
// See howto_code_exec.txt about code execution via the vtable of a textarea
|
||||
// element.
|
||||
function dump_scrollLeft() {
|
||||
let proto = Object.getPrototypeOf(textarea);
|
||||
proto = Object.getPrototypeOf(proto);
|
||||
proto = Object.getPrototypeOf(proto);
|
||||
let proto = Object.getPrototypeOf(textarea);
|
||||
proto = Object.getPrototypeOf(proto);
|
||||
proto = Object.getPrototypeOf(proto);
|
||||
|
||||
const scrollLeft_get =
|
||||
Object.getOwnPropertyDescriptors(proto).scrollLeft.get
|
||||
;
|
||||
const scrollLeft_get = Object.getOwnPropertyDescriptors(proto).scrollLeft.get;
|
||||
// get the JSCustomGetterSetterFunction
|
||||
const js_func = mem.addrof(scrollLeft_get);
|
||||
const getterSetter = js_func.readp(0x28);
|
||||
const getter = getterSetter.readp(8);
|
||||
|
||||
// get the JSCustomGetterSetterFunction
|
||||
const js_func = mem.addrof(scrollLeft_get);
|
||||
const getterSetter = js_func.readp(0x28);
|
||||
const getter = getterSetter.readp(8);
|
||||
|
||||
const libwebkit_base = find_base(getter, true, true);
|
||||
const offset = getter.sub(libwebkit_base);
|
||||
send(
|
||||
url,
|
||||
make_buffer(getter, 0x800),
|
||||
`scrollLeft_getter_dump_offset_${offset}.bin`,
|
||||
() => log('sent')
|
||||
);
|
||||
const libwebkit_base = find_base(getter, true, true);
|
||||
const offset = getter.sub(libwebkit_base);
|
||||
send(url, make_buffer(getter, 0x800), `scrollLeft_getter_dump_offset_${offset}.bin`, () => log("sent"));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user