用C语言设置SUID是不够的



出于教学目的,我想在C中设置一个基本的命令注入。我有以下代码:

#include <stdio.h>
#include <unistd.h>
int main(int argc, char **argv) {
char cat[] = "cat ";
char *command;
size_t commandLength;
commandLength = strlen(cat) + strlen(argv[1]) + 1;
command = (char *) malloc(commandLength);
strncpy(command, cat, commandLength);
strncat(command, argv[1], (commandLength - strlen(cat)) );
system(command);
return (0);
}

我编译它,将二进制文件设置为root所有,并将SUID设置为1,如下所示:

gcc injectionos.c -o injectionos
sudo chown root:root injectionos
sudo chmod +s injectionos

我得到以下结果:

ls -la
total 40
drwxr-xr-x 2 olive olive  4096 Jan  6 13:17 .
drwxr-xr-x 3 olive olive  4096 Jan  6 12:15 ..
-rwsr-sr-x 1 root  root  16824 Jan  6 13:17 injectionos
-rw-r--r-- 1 olive olive   415 Jan  6 13:17 injectionos.c
-rwx------ 1 root  root      9 Jan  6 12:43 titi.txt
-rw-r--r-- 1 olive olive     9 Jan  6 12:16 toto.txt`

因此,基本上,在SUID设置为1的情况下,我应该能够通过执行以下注入来打开toto.txt和titi.txt文件:

./injectionos "toto.txt;cat titi.txt"

但是执行这个命令时,我在访问titi.txt时得到了一个permission denied。最后,当我在代码中添加setuid(geteuid());时,注入正在工作,我可以访问titi.txt文件。

考虑到injectionos是作为root运行的,titi.txt属于root,我认为这已经足够了,但显然没有。我在这里缺少什么?

作为system()调用的一部分执行的/bin/sh正在删除特权。参见bash和-p选项的手册页

如果shell是在有效用户(组(id不相等的情况下启动的到真实的用户(组(id,并且没有提供-p选项,否启动文件是读取的,shell函数不是从环境、SHELLOPTS、BASHOPTS、CDPATH和GLOBIGNORE变量(如果出现在环境中(将被忽略,并且有效用户id设置为真实用户id。如果-p选项为在调用时提供,启动行为是相同的,但未重置有效的用户id。

从技术上讲,debian默认使用dash,但它也做同样的事情。

因此,shell的默认行为已经进行了调整,至少在一定程度上减轻了这种注入。

相关内容

  • 没有找到相关文章

最新更新