Tweaks before tackling the new ROP chains
- Added read8/read16/write8/write16 functions - Simplify shellcode a little bit more - Didn't init chain before using it for setuid check
This commit is contained in:
@@ -17,8 +17,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
// 8.00, 8.01, 8.03
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "utils.h"
|
||||
|
||||
@@ -31,8 +29,8 @@ struct kexec_args {
|
||||
u64 arg5;
|
||||
};
|
||||
|
||||
void do_patch(void);
|
||||
void restore(struct kexec_args *uap);
|
||||
static inline void restore(struct kexec_args *uap);
|
||||
static inline void do_patch(void);
|
||||
|
||||
__attribute__((section (".text.start")))
|
||||
int kpatch(void *td, struct kexec_args *uap) {
|
||||
@@ -41,10 +39,11 @@ int kpatch(void *td, struct kexec_args *uap) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void restore(struct kexec_args *uap) {
|
||||
__attribute__((always_inline))
|
||||
static inline void restore(struct kexec_args *uap) {
|
||||
u8 *pipe = uap->arg1;
|
||||
u8 *pipebuf = uap->arg2;
|
||||
for (size_t i = 0; i < 0x18; i++) {
|
||||
for (int i = 0; i < 0x18; i++) {
|
||||
pipe[i] = pipebuf[i];
|
||||
}
|
||||
u64 *pktinfo_field = uap->arg3;
|
||||
@@ -53,16 +52,15 @@ void restore(struct kexec_args *uap) {
|
||||
*pktinfo_field2 = 0;
|
||||
}
|
||||
|
||||
void do_patch(void) {
|
||||
// offset to fast_syscall()
|
||||
const size_t off_fast_syscall = 0x1c0;
|
||||
void * const kbase = (void *)rdmsr(0xc0000082) - off_fast_syscall;
|
||||
__attribute__((always_inline))
|
||||
static inline void do_patch(void) {
|
||||
// get kernel base
|
||||
const u64 xfast_syscall_off = 0x1c0;
|
||||
void * const kbase = (void *)rdmsr(0xc0000082) - xfast_syscall_off;
|
||||
|
||||
disable_cr0_wp();
|
||||
|
||||
// ChendoChap's patches from pOOBs4 ///////////////////////////////////////
|
||||
|
||||
// Initial patches
|
||||
// ChendoChap's patches from pOOBs4
|
||||
write16(kbase, 0x62d254, 0x9090); // veriPatch
|
||||
write8(kbase, 0xacd, 0xeb); // bcopy
|
||||
write8(kbase, 0x25e10d, 0xeb); // bzero
|
||||
@@ -176,12 +174,13 @@ void do_patch(void) {
|
||||
// int sys_kexec(struct thread td, struct args *uap) {
|
||||
// asm("jmp qword ptr [rsi]");
|
||||
// }
|
||||
const u64 sysent_11_off = 0x10fc6e0;
|
||||
// .sy_narg = 2
|
||||
write32(kbase, 0x10fc6e0, 2);
|
||||
write32(kbase, sysent_11_off, 2);
|
||||
// .sy_call = gadgets['jmp qword ptr [rsi]']
|
||||
write64(kbase, 0x10fc6e0 + 8, kbase + 0xe629c);
|
||||
write64(kbase, sysent_11_off + 8, kbase + 0xe629c);
|
||||
// .sy_thrcnt = SY_THR_STATIC
|
||||
write32(kbase, 0x10fc6e0 + 0x2c, 1);
|
||||
write32(kbase, sysent_11_off + 0x2c, 1);
|
||||
|
||||
enable_cr0_wp();
|
||||
}
|
||||
|
||||
@@ -17,8 +17,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
// 8.50, 8.52
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "utils.h"
|
||||
|
||||
@@ -31,8 +29,8 @@ struct kexec_args {
|
||||
u64 arg5;
|
||||
};
|
||||
|
||||
void do_patch(void);
|
||||
void restore(struct kexec_args *uap);
|
||||
static inline void restore(struct kexec_args *uap);
|
||||
static inline void do_patch(void);
|
||||
|
||||
__attribute__((section (".text.start")))
|
||||
int kpatch(void *td, struct kexec_args *uap) {
|
||||
@@ -41,10 +39,11 @@ int kpatch(void *td, struct kexec_args *uap) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void restore(struct kexec_args *uap) {
|
||||
__attribute__((always_inline))
|
||||
static inline void restore(struct kexec_args *uap) {
|
||||
u8 *pipe = uap->arg1;
|
||||
u8 *pipebuf = uap->arg2;
|
||||
for (size_t i = 0; i < 0x18; i++) {
|
||||
for (int i = 0; i < 0x18; i++) {
|
||||
pipe[i] = pipebuf[i];
|
||||
}
|
||||
u64 *pktinfo_field = uap->arg3;
|
||||
@@ -53,16 +52,15 @@ void restore(struct kexec_args *uap) {
|
||||
*pktinfo_field2 = 0;
|
||||
}
|
||||
|
||||
void do_patch(void) {
|
||||
// offset to fast_syscall()
|
||||
const size_t off_fast_syscall = 0x1c0;
|
||||
void * const kbase = (void *)rdmsr(0xc0000082) - off_fast_syscall;
|
||||
__attribute__((always_inline))
|
||||
static inline void do_patch(void) {
|
||||
// get kernel base
|
||||
const u64 xfast_syscall_off = 0x1c0;
|
||||
void * const kbase = (void *)rdmsr(0xc0000082) - xfast_syscall_off;
|
||||
|
||||
disable_cr0_wp();
|
||||
|
||||
// ChendoChap's patches from pOOBs4 ///////////////////////////////////////
|
||||
|
||||
// Initial patches
|
||||
// ChendoChap's patches from pOOBs4
|
||||
write16(kbase, 0x624674, 0x9090); // veriPatch
|
||||
write8(kbase, 0xacd, 0xeb); // bcopy
|
||||
write8(kbase, 0x3a403d, 0xeb); // bzero
|
||||
@@ -176,12 +174,13 @@ void do_patch(void) {
|
||||
// int sys_kexec(struct thread td, struct args *uap) {
|
||||
// asm("jmp qword ptr [rsi]");
|
||||
// }
|
||||
const u64 sysent_11_off = 0x10fc7d0;
|
||||
// .sy_narg = 2
|
||||
write32(kbase, 0x10fc7d0, 2);
|
||||
write32(kbase, sysent_11_off, 2);
|
||||
// .sy_call = gadgets['jmp qword ptr [rsi]']
|
||||
write64(kbase, 0x10fc7d0 + 8, kbase + 0xc810d);
|
||||
write64(kbase, sysent_11_off + 8, kbase + 0xc810d);
|
||||
// .sy_thrcnt = SY_THR_STATIC
|
||||
write32(kbase, 0x10fc7d0 + 0x2c, 1);
|
||||
write32(kbase, sysent_11_off + 0x2c, 1);
|
||||
|
||||
enable_cr0_wp();
|
||||
}
|
||||
|
||||
@@ -17,8 +17,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
// 9.00
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "utils.h"
|
||||
|
||||
@@ -31,8 +29,8 @@ struct kexec_args {
|
||||
u64 arg5;
|
||||
};
|
||||
|
||||
void do_patch(void);
|
||||
void restore(struct kexec_args *uap);
|
||||
static inline void restore(struct kexec_args *uap);
|
||||
static inline void do_patch(void);
|
||||
|
||||
__attribute__((section (".text.start")))
|
||||
int kpatch(void *td, struct kexec_args *uap) {
|
||||
@@ -41,10 +39,11 @@ int kpatch(void *td, struct kexec_args *uap) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void restore(struct kexec_args *uap) {
|
||||
__attribute__((always_inline))
|
||||
static inline void restore(struct kexec_args *uap) {
|
||||
u8 *pipe = uap->arg1;
|
||||
u8 *pipebuf = uap->arg2;
|
||||
for (size_t i = 0; i < 0x18; i++) {
|
||||
for (int i = 0; i < 0x18; i++) {
|
||||
pipe[i] = pipebuf[i];
|
||||
}
|
||||
u64 *pktinfo_field = uap->arg3;
|
||||
@@ -53,16 +52,15 @@ void restore(struct kexec_args *uap) {
|
||||
*pktinfo_field2 = 0;
|
||||
}
|
||||
|
||||
void do_patch(void) {
|
||||
// offset to fast_syscall()
|
||||
const size_t off_fast_syscall = 0x1c0;
|
||||
void * const kbase = (void *)rdmsr(0xc0000082) - off_fast_syscall;
|
||||
__attribute__((always_inline))
|
||||
static inline void do_patch(void) {
|
||||
// get kernel base
|
||||
const u64 xfast_syscall_off = 0x1c0;
|
||||
void * const kbase = (void *)rdmsr(0xc0000082) - xfast_syscall_off;
|
||||
|
||||
disable_cr0_wp();
|
||||
|
||||
// ChendoChap's patches from pOOBs4 ///////////////////////////////////////
|
||||
|
||||
// Initial patches
|
||||
// ChendoChap's patches from pOOBs4
|
||||
write16(kbase, 0x626874, 0x9090); // veriPatch
|
||||
write8(kbase, 0xacd, 0xeb); // bcopy
|
||||
write8(kbase, 0x2713fd, 0xeb); // bzero
|
||||
@@ -176,12 +174,13 @@ void do_patch(void) {
|
||||
// int sys_kexec(struct thread td, struct args *uap) {
|
||||
// asm("jmp qword ptr [rsi]");
|
||||
// }
|
||||
const u64 sysent_11_off = 0x1100520;
|
||||
// .sy_narg = 2
|
||||
write32(kbase, 0x1100520, 2);
|
||||
write32(kbase, sysent_11_off, 2);
|
||||
// .sy_call = gadgets['jmp qword ptr [rsi]']
|
||||
write64(kbase, 0x1100520 + 8, kbase + 0x4c7ad);
|
||||
write64(kbase, sysent_11_off + 8, kbase + 0x4c7ad);
|
||||
// .sy_thrcnt = SY_THR_STATIC
|
||||
write32(kbase, 0x1100520 + 0x2c, 1);
|
||||
write32(kbase, sysent_11_off + 0x2c, 1);
|
||||
|
||||
enable_cr0_wp();
|
||||
}
|
||||
|
||||
@@ -17,8 +17,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
// 9.03, 9.04
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "utils.h"
|
||||
|
||||
@@ -31,8 +29,8 @@ struct kexec_args {
|
||||
u64 arg5;
|
||||
};
|
||||
|
||||
void do_patch(void);
|
||||
void restore(struct kexec_args *uap);
|
||||
static inline void restore(struct kexec_args *uap);
|
||||
static inline void do_patch(void);
|
||||
|
||||
__attribute__((section (".text.start")))
|
||||
int kpatch(void *td, struct kexec_args *uap) {
|
||||
@@ -41,10 +39,11 @@ int kpatch(void *td, struct kexec_args *uap) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void restore(struct kexec_args *uap) {
|
||||
__attribute__((always_inline))
|
||||
static inline void restore(struct kexec_args *uap) {
|
||||
u8 *pipe = uap->arg1;
|
||||
u8 *pipebuf = uap->arg2;
|
||||
for (size_t i = 0; i < 0x18; i++) {
|
||||
for (int i = 0; i < 0x18; i++) {
|
||||
pipe[i] = pipebuf[i];
|
||||
}
|
||||
u64 *pktinfo_field = uap->arg3;
|
||||
@@ -53,16 +52,15 @@ void restore(struct kexec_args *uap) {
|
||||
*pktinfo_field2 = 0;
|
||||
}
|
||||
|
||||
void do_patch(void) {
|
||||
// offset to fast_syscall()
|
||||
const size_t off_fast_syscall = 0x1c0;
|
||||
void * const kbase = (void *)rdmsr(0xc0000082) - off_fast_syscall;
|
||||
__attribute__((always_inline))
|
||||
static inline void do_patch(void) {
|
||||
// get kernel base
|
||||
const u64 xfast_syscall_off = 0x1c0;
|
||||
void * const kbase = (void *)rdmsr(0xc0000082) - xfast_syscall_off;
|
||||
|
||||
disable_cr0_wp();
|
||||
|
||||
// ChendoChap's patches from pOOBs4 ///////////////////////////////////////
|
||||
|
||||
// Initial patches
|
||||
// ChendoChap's patches from pOOBs4
|
||||
write16(kbase, 0x624834, 0x9090); // veriPatch
|
||||
write8(kbase, 0xacd, 0xeb); // bcopy
|
||||
write8(kbase, 0x27107d, 0xeb); // bzero
|
||||
@@ -176,12 +174,13 @@ void do_patch(void) {
|
||||
// int sys_kexec(struct thread td, struct args *uap) {
|
||||
// asm("jmp qword ptr [rsi]");
|
||||
// }
|
||||
const u64 sysent_11_off = 0x10fc520;
|
||||
// .sy_narg = 2
|
||||
write32(kbase, 0x10fc520, 2);
|
||||
write32(kbase, sysent_11_off, 2);
|
||||
// .sy_call = gadgets['jmp qword ptr [rsi]']
|
||||
write64(kbase, 0x10fc520 + 8, kbase + 0x5325b);
|
||||
write64(kbase, sysent_11_off + 8, kbase + 0x5325b);
|
||||
// .sy_thrcnt = SY_THR_STATIC
|
||||
write32(kbase, 0x10fc520 + 0x2c, 1);
|
||||
write32(kbase, sysent_11_off + 0x2c, 1);
|
||||
|
||||
enable_cr0_wp();
|
||||
}
|
||||
|
||||
@@ -17,8 +17,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
// 9.50, 9.51, 9.60
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "utils.h"
|
||||
|
||||
@@ -31,8 +29,8 @@ struct kexec_args {
|
||||
u64 arg5;
|
||||
};
|
||||
|
||||
void do_patch(void);
|
||||
void restore(struct kexec_args *uap);
|
||||
static inline void restore(struct kexec_args *uap);
|
||||
static inline void do_patch(void);
|
||||
|
||||
__attribute__((section (".text.start")))
|
||||
int kpatch(void *td, struct kexec_args *uap) {
|
||||
@@ -41,10 +39,11 @@ int kpatch(void *td, struct kexec_args *uap) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void restore(struct kexec_args *uap) {
|
||||
__attribute__((always_inline))
|
||||
static inline void restore(struct kexec_args *uap) {
|
||||
u8 *pipe = uap->arg1;
|
||||
u8 *pipebuf = uap->arg2;
|
||||
for (size_t i = 0; i < 0x18; i++) {
|
||||
for (int i = 0; i < 0x18; i++) {
|
||||
pipe[i] = pipebuf[i];
|
||||
}
|
||||
u64 *pktinfo_field = uap->arg3;
|
||||
@@ -53,16 +52,15 @@ void restore(struct kexec_args *uap) {
|
||||
*pktinfo_field2 = 0;
|
||||
}
|
||||
|
||||
void do_patch(void) {
|
||||
// offset to fast_syscall()
|
||||
const size_t off_fast_syscall = 0x1c0;
|
||||
void * const kbase = (void *)rdmsr(0xc0000082) - off_fast_syscall;
|
||||
__attribute__((always_inline))
|
||||
static inline void do_patch(void) {
|
||||
// get kernel base
|
||||
const u64 xfast_syscall_off = 0x1c0;
|
||||
void * const kbase = (void *)rdmsr(0xc0000082) - xfast_syscall_off;
|
||||
|
||||
disable_cr0_wp();
|
||||
|
||||
// ChendoChap's patches from pOOBs4 ///////////////////////////////////////
|
||||
|
||||
// Initial patches
|
||||
// ChendoChap's patches from pOOBs4
|
||||
write16(kbase, 0x624ae4, 0x9090); // veriPatch
|
||||
write8(kbase, 0xacd, 0xeb); // bcopy
|
||||
write8(kbase, 0x201c0d, 0xeb); // bzero
|
||||
@@ -176,12 +174,13 @@ void do_patch(void) {
|
||||
// int sys_kexec(struct thread td, struct args *uap) {
|
||||
// asm("jmp qword ptr [rsi]");
|
||||
// }
|
||||
const u64 sysent_11_off = 0x10f9500;
|
||||
// .sy_narg = 2
|
||||
write32(kbase, 0x10f9500, 2);
|
||||
write32(kbase, sysent_11_off, 2);
|
||||
// .sy_call = gadgets['jmp qword ptr [rsi]']
|
||||
write64(kbase, 0x10f9500 + 8, kbase + 0x15a6d);
|
||||
write64(kbase, sysent_11_off + 8, kbase + 0x15a6d);
|
||||
// .sy_thrcnt = SY_THR_STATIC
|
||||
write32(kbase, 0x10f9500 + 0x2c, 1);
|
||||
write32(kbase, sysent_11_off + 0x2c, 1);
|
||||
|
||||
enable_cr0_wp();
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ TARGET_VERSIONS = 800 850 900 903 950
|
||||
|
||||
CC = gcc
|
||||
OBJCOPY = objcopy
|
||||
CFLAGS = -Os -std=gnu11 -Wno-int-conversion -masm=intel -nostartfiles -Tscript.ld
|
||||
CFLAGS = -O3 -std=gnu11 -Wno-int-conversion -masm=intel -nostartfiles -fcf-protection=none -Tscript.ld
|
||||
|
||||
.PHONY: all
|
||||
ALL_SOURCES = $(TARGET_VERSIONS:%=%.c)
|
||||
|
||||
@@ -15,7 +15,8 @@ GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#pragma once
|
||||
#ifndef TYPES_H_
|
||||
#define TYPES_H_
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
@@ -26,3 +27,5 @@ typedef signed char s8;
|
||||
typedef signed short s16;
|
||||
typedef signed int s32;
|
||||
typedef signed long long s64;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -15,14 +15,14 @@ GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#ifndef UTILS_H_
|
||||
#define UTILS_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
static inline u64 rdmsr(u32 msr) {
|
||||
u32 low, high;
|
||||
u32 low;
|
||||
u32 high;
|
||||
|
||||
asm("rdmsr" : "=a" (low), "=d" (high) : "c" (msr));
|
||||
return (low | ((u64)high << 32));
|
||||
@@ -44,18 +44,20 @@ static inline void disable_cr0_wp(void) {
|
||||
::: "rax");
|
||||
}
|
||||
|
||||
static inline void write8(void *addr, size_t offset, u8 value) {
|
||||
static inline void write8(void *addr, u64 offset, u8 value) {
|
||||
*(u8 *)(addr + offset) = value;
|
||||
}
|
||||
|
||||
static inline void write16(void *addr, size_t offset, u16 value) {
|
||||
static inline void write16(void *addr, u64 offset, u16 value) {
|
||||
*(u16 *)(addr + offset) = value;
|
||||
}
|
||||
|
||||
static inline void write32(void *addr, size_t offset, u32 value) {
|
||||
static inline void write32(void *addr, u64 offset, u32 value) {
|
||||
*(u32 *)(addr + offset) = value;
|
||||
}
|
||||
|
||||
static inline void write64(void *addr, size_t offset, u64 value) {
|
||||
static inline void write64(void *addr, u64 offset, u64 value) {
|
||||
*(u64 *)(addr + offset) = value;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user