利用 c - linux setuid 和系统命令
Exploiting c - linux setuid and system commands
我有以下代码作为可执行文件,我想在课程中利用它来生成具有提升权限的 shell。我是 levelX 的用户,可执行文件的 setgid 为 levelX+1。我不允许更改任何代码。
由于我没有 root 权限,setguid(0) 失败。我无法更改函数或主函数的 return 地址。谁能指出正确的方向?
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;
}
从您发布的代码来看,您似乎应该将自己的 sudoers
文件写入您具有写入权限的任何目录,然后 运行 该程序在该目录中,因此它读取你的文件。
所以,干脆把自己的UID写到这个假的sudoers
文件里,然后给一个命令参数比如bash
就可以得到一个shell。无需进行任何缓冲区溢出利用。
推测真正的可利用程序在文件权限中设置了 suid 位,因此它可以执行 setuid(0)
调用。我想这个练习的目的是演示在处理 suid 程序时需要如何清理 all 输入,包括相对路径(有效地将当前工作目录作为输入)就像任何用户提供的路径和其他输入一样。
但是,由于该程序只有 setgid 位(如评论中所述),您需要找到仅使用组 ID 执行的操作。那个东西可能是那个日志文件写的。您可以创建一个文件名为 log
的符号 link,指向您要附加到的任何文件,该组对其具有写入权限。此外,该文件需要具有这样的格式,即日志行格式不会使文件损坏。请记住,您可以将换行符等放入命令行参数!
毕竟它是 int exec(char *command)
内 fprintf(f, entry, NULL);
上的格式字符串漏洞,您用 %n 格式覆盖 return 地址。
我有以下代码作为可执行文件,我想在课程中利用它来生成具有提升权限的 shell。我是 levelX 的用户,可执行文件的 setgid 为 levelX+1。我不允许更改任何代码。 由于我没有 root 权限,setguid(0) 失败。我无法更改函数或主函数的 return 地址。谁能指出正确的方向?
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;
}
从您发布的代码来看,您似乎应该将自己的 sudoers
文件写入您具有写入权限的任何目录,然后 运行 该程序在该目录中,因此它读取你的文件。
所以,干脆把自己的UID写到这个假的sudoers
文件里,然后给一个命令参数比如bash
就可以得到一个shell。无需进行任何缓冲区溢出利用。
推测真正的可利用程序在文件权限中设置了 suid 位,因此它可以执行 setuid(0)
调用。我想这个练习的目的是演示在处理 suid 程序时需要如何清理 all 输入,包括相对路径(有效地将当前工作目录作为输入)就像任何用户提供的路径和其他输入一样。
但是,由于该程序只有 setgid 位(如评论中所述),您需要找到仅使用组 ID 执行的操作。那个东西可能是那个日志文件写的。您可以创建一个文件名为 log
的符号 link,指向您要附加到的任何文件,该组对其具有写入权限。此外,该文件需要具有这样的格式,即日志行格式不会使文件损坏。请记住,您可以将换行符等放入命令行参数!
毕竟它是 int exec(char *command)
内 fprintf(f, entry, NULL);
上的格式字符串漏洞,您用 %n 格式覆盖 return 地址。