我有以下代码作为可执行文件,我想在课程中利用这些代码来生成具有提升权限的shell。我是levelX的用户,可执行文件的setgid为levelX+1。我不能更改任何代码。由于我没有root权限,setguid(0(失败。我无法更改函数或主函数的返回地址。有人能指出正确的方向吗?
int main (int argc, char** argv)
{
if (exec(argv[1]) != 0)
{
fprintf(stderr, "Cannot execute your commandn");
return -1;
}
return 0;
}
int exec(char *command)
{
FILE *f = NULL;
char entry[64];
char line[256];
f = fopen("log", "a");
if (f == NULL)
{
fprintf(stderr, "Can't open filen");
return -1;
}
snprintf(entry, 64, "%d: %sn", getuid(), command);
fprintf(f, entry, NULL);
fclose(f);
f = fopen("sudoers", "r");
if (f == NULL)
{
fprintf(stderr, "Can't openn");
return -1;
}
while(fgets(line, 256, f) != NULL)
{
if (atoi(line) == getuid())
{
if (setuid(0) == 0) {
system(command);
} else {
fprintf(stderr, "check permissionsn");
}
fclose(f);
return 0;
}
}
fprintf(stderr, "Errorn");
fclose(f);
return -1;
}
从您发布的代码中,您似乎应该将自己的sudoers
文件写入到您有写访问权限的任何目录,然后在该目录中运行此程序,以便它读取您的文件。
因此,只需将您自己的UID写入这个伪造的sudoers
文件,然后给定一个命令参数(如bash
(即可获得shell。没有必要进行任何缓冲区溢出利用。
据推测,真正可利用的程序在文件权限中设置了suid位,因此它可以执行setuid(0)
调用。我想这个练习的目的是演示在处理suid程序时,所有输入都需要如何净化,包括相对路径(有效地将当前工作目录作为输入(之类的东西,比如任何用户提供的路径和其他输入。
但是,由于程序只有setgid位(如注释中所述(,您需要找到只使用组id执行的操作。这可能是日志文件写入的操作。您可以创建一个文件名为log
的符号链接,指向要附加到的任何文件,该组对该文件具有写入权限。此外,该文件需要具有这样的格式,即日志行格式不会使文件损坏。记住,您可以将换行符等放入命令行参数中!
毕竟,在int exec(char *command)
内部的fprintf(f, entry, NULL);
上存在格式字符串漏洞,您可以用%n格式覆盖返回地址。