我将以下代码作为可执行文件,希望将其用作课程,以生成具有提升特权的shell。我是levelX的用户,可执行文件的setgid为levelX + 1。我不允许更改任何代码。 由于我没有root权限,因此setguid(0)失败。我无法更改函数或主函数的返回地址。谁能指出正确的方向?
int main (int argc, char** argv)
{
if (exec(argv[1]) != 0)
{
fprintf(stderr, "Cannot execute your command\n");
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 file\n");
return -1;
}
snprintf(entry, 64, "%d: %s\n", getuid(), command);
fprintf(f, entry, NULL);
fclose(f);
f = fopen("sudoers", "r");
if (f == NULL)
{
fprintf(stderr, "Can't open\n");
return -1;
}
while(fgets(line, 256, f) != NULL)
{
if (atoi(line) == getuid())
{
if (setuid(0) == 0) {
system(command);
} else {
fprintf(stderr, "check permissions\n");
}
fclose(f);
return 0;
}
}
fprintf(stderr, "Error\n");
fclose(f);
return -1;
}
答案 0 :(得分:1)
从您发布的代码来看,似乎应该将自己的sudoers
文件写入具有写访问权限的任何目录,然后在该目录中运行该程序,以便读取文件。
因此,只需将您自己的UID写入此伪造的sudoers
文件,然后提供命令参数,例如bash
即可获得外壳。无需进行任何缓冲区溢出利用。
大概是真正的可利用程序在文件许可权中设置了suid位,因此它可以执行setuid(0)
调用。我猜想该练习的目的是演示在处理suid程序时需要如何清除所有输入内容,包括像其他用户一样的相对路径(有效地将当前工作目录作为输入)之类的东西。 -提供的路径和其他输入。
但是,由于该程序仅具有setgid位(如注释中所述),因此您需要找到仅使用组ID进行的操作。可能是该日志文件写入了。您可以使用文件名log
创建一个符号链接,指向要添加到该文件组具有写权限的任何文件。同样,该文件需要具有这样的格式,即日志行格式不会使文件损坏。请记住,您可以在命令行参数中添加换行符!
答案 1 :(得分:0)
毕竟,这是fprintf(f, entry, NULL);
内int exec(char *command)
上的一种格式字符串利用,您在其中用%n格式覆盖了返回地址。