我有一个Setuid二进制文件,它具有一个printf格式字符串漏洞,应该与“%n”一起利用以覆盖authenticated全局变量的值。使用/ bin / bash时authenticated = 1,使用root Setuid权限可以执行/ bin / bash ,但authenticated = 0使用exploit时则不能。
我已经尝试过ls并且可以正常工作,所以exec正在发生。我也尝试过authenticated = 1在源代码中进行制作,因此它可以自动运行bash而不会被利用。这适用于生成根外壳。使用漏洞利用程序时,程序将按预期方式调用授予访问权限的功能,但在exec处结束,并且永远不会达到错误。但是,父进程死了,这意味着bash的执行程序一定已经发生。Bash必须正在执行,但是它在启动时崩溃/退出。
#define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <errno.h> int authenticated = 0; void read_flag() { if (!authenticated) { printf("Sorry, you are not *authenticated*!\n"); } else { printf("Access Granted.\n"); int cpid = fork(); if(cpid == 0){ printf("child!\n"); execlp("/bin/bash", "bash", NULL); perror("error"); } else{ wait(NULL); } } } int main(int argc, char **argv) { setvbuf(stdout, NULL, _IONBF, 0); char buf[64]; // Set the gid to the effective gid // this prevents /bin/sh from dropping the privileges setreuid(geteuid(), getuid()); printf("Would you like a shell? (yes/no)\n"); fgets(buf, sizeof(buf), stdin); if (strstr(buf, "no") != NULL) { printf("Okay, Exiting...\n"); exit(1); } else if (strstr(buf, "yes") == NULL) { puts("Received Unknown Input:\n"); printf(buf); } read_flag(); }
通过authenticated = 0,我使用gdb查找authenticated0x0804a050之类的地址。我使用AAAA%x%x%x …运行该程序,以发现它buf从第4个堆栈位置开始。然后,我的漏洞利用是:python -c “print(‘\x50\xa0\x04\x08%x%x%x%n’)”它成功地将全局var覆盖为“ Access Granted!”。打印。永远无法达到这种恐惧,Bash必须生成,但是父进程死亡,因此Bash进程也必定已经死亡。时不会发生这种情况authenticated = 1。在这种情况下,Setuid二进制文件的行为符合预期,并弹出一个根shell。
我的问题是:为什么Bash会在启动时死掉,而只有在使用Detuid二进制文件时才会死掉?Bash必须快死了,因为ps -aux它没有列出新的Bash进程,并且运行exit退出调用bash实例。