【问题标题】:setuid(0) and system failssetuid(0) 和系统失败
【发布时间】:2011-09-10 06:07:39
【问题描述】:

我有一个用 C 语言运行的程序。这需要使用系统执行“iptables”命令。

我试过了

setuid(0); 
system("iptables .... ");

setuid 和 system 不能共存。从系统手册页

不要在程序中使用 system() 使用 set-user-ID 或 set-group-ID 特权,因为奇怪的价值观 对于一些 环境变量可能用于破坏系统完整性。 使用 exec(3) 系列函数 反而, 但不是 execlp(3) 或 execvp(3)。 system() 实际上不会工作 正确地从程序中 设置用户 ID 或设置 /bin/sh 为 bash 的系统上的组 ID 权限 版本 2,因为 bash 2 下降 启动时的特权。 (Debian 使用修改后的 bash,它在调用时不会这样做 嘘)

我该如何克服我的问题?

谢谢

【问题讨论】:

    标签: c linux root setuid


    【解决方案1】:

    system() 将与 setuid() 一起工作,但这就是问题所在:主要的安全风险。问题是 system() 使用任何环境启动一个 shell(bash、sh 等),当你打算让它运行“iptables”时,我的 PATH 可以指向我自己的 iptables 版本,我可以很容易地说服你以 root 身份为我竞选。您似乎可以通过使用 iptables 的完整路径来解决这个问题,但可以使用其他环境变量(例如 LD_PRELOAD_PATH)来说服工具加载恶意共享库——同样,以 root 身份运行不希望的东西。

    对于您需要安全地执行的操作,您必须使用 exec() 系列之一,并且您必须控制其操作环境。其他任何事情都要求滥用安全性。 http://pubs.opengroup.org/onlinepubs/009695399/functions/environ.html 似乎是了解更多信息的好地方。

    【讨论】:

      【解决方案2】:

      为什么需要使用system()man page 正在告诉您确切的操作:

      请改用exec(3) 系列函数,但不要使用execlp(3)execvp(3)

      您可能也会对fork(2)wait(2) 系统调用感兴趣。

      【讨论】:

        【解决方案3】:

        这样的事情可能会有所帮助。它未经测试,但应该可以工作。

            char * const argv[] = {"/sbin/iptables", "-L", NULL};
        
            pid = fork();
            switch (pid) {
                    case -1:
                            /* handle error */
                    case 0:
                            execv("/sbin/iptables", argv);
                            /* handle error if you get here */
                    break;
                    default:
                            waitpid(pid, &status, 0);
                            /* check waitpid return code */
                    break;
            }
        

        【讨论】:

        • @downvoter 我将不胜感激一些可以帮助我改进这个答案的反馈:-)
        猜你喜欢
        • 2017-10-12
        • 1970-01-01
        • 1970-01-01
        • 2020-10-21
        • 2018-04-06
        • 2015-02-21
        • 2013-04-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多