我正在查看Android漏洞 Rage Against The Cage 的实施情况。其背后的想法是,为了 shell UID,它可以创建尽可能多的进程来到RLIMIT_NPROC
,以便下次Android Debug Bridge(ADB)守护程序尝试从其中删除其权限时 root 到 shell ,对setuid()
的调用失败,并继续执行 root (通过检查结果修复了该错误在继续之前调用setuid()
。
根据setrlimit()
documentation,RLIMIT_NPROC
定义为:
最大进程数(或者更准确地说是在Linux上, 线程)可以创建 [强调我的] 为真实用户ID 呼叫过程。遇到此限制时,fork(2)将失败 错误EAGAIN。不强制执行此限制 具有CAP_SYS_ADMIN或。的进程 CAP_SYS_RESOURCE功能。
此外,这就是利用漏洞的方式:
/* generate many (zombie) shell-user processes so restarting
* adb's setuid() will fail.
* The whole thing is a bit racy, since when we kill adb
* there is one more process slot left which we need to
* fill before adb reaches setuid(). Thats why we fork-bomb
* in a seprate process.
*/
if (fork() == 0) { // 'true' for the child
close(pepe[0]);
for (;;) {
if ((p = fork()) == 0) {
exit(0); // child exits (???)
} 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;
}
}
}
因此,RLIMIT_NPROC
被定义为&#34;可以创建的最大进程数&#34; - 创建,而不是&#34;同时执行&#34; - 并通过终止由第二个fork创建的每个子进程来实现该定义的秒数。
首先,我无法理解如何限制每个UID创建的进程数量可能有效(我们必须不时重新启动我们的计算机以重置该计数,并且不会我们?)。其次,即使是reverse engineered漏洞获取与上面显示的实现相当的实现的人,也会以不同的方式定义RLIMIT_NPROC
:
[exploit] 利用RLIMIT_NPROC max,这是一个定义的值 给定的UID可以运行多少个进程。
那说,RLIMIT_NPROC实际上是如何运作的?哪个定义更准确?
答案 0 :(得分:0)
限制确实是当前进程的数量,而不是自系统启动以来创建的进程总数。
漏洞利用代码如何运作的关键是僵尸进程。即使子进程调用了exit(),它们仍然被操作系统保留,并计入限制,直到父进程放弃它们或调用wait()。在这种情况下,父级不执行此操作,因此它们会一直存在,直到父级本身退出。