简体   繁体   English

setuid(0) 和系统失败

[英]setuid(0) and system fails

I have a program running in C.我有一个程序在 C 中运行。 This needs to execute an "iptables" command using system.这需要使用系统执行“iptables”命令。

I tried我试过了

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

setuid and system do not coexist. setuid 和 system 不能共存。 from the system man page从系统手册页

Do not use system() from a program with set-user-ID or set-group-ID privileges, because strange values for some environment variables might be used to subvert system integrity.不要在具有 set-user-ID 或 set-group-ID 权限的程序中使用 system(),因为某些环境变量的奇怪值可能会破坏系统完整性。 Use the exec(3) family of functions instead, but not execlp(3) or execvp(3).请改用 exec(3) 系列函数,但不要使用 execlp(3) 或 execvp(3)。 system() will not, in fact, work properly from programs with set-user-ID or set- group-ID privileges on systems on which /bin/sh is bash version 2, since bash 2 drops privileges on startup.事实上,system() 在 /bin/sh 为 bash 版本 2 的系统上无法从具有 set-user-ID 或 set-group-ID 权限的程序正常工作,因为 bash 2 在启动时会放弃权限。 (Debian uses a modified bash which does not do this when invoked as sh.) (Debian 使用经过修改的 bash,它在以 sh 调用时不会执行此操作。)

how can I overcome my problem?我怎样才能克服我的问题?

Thanks谢谢

system() will work in conjunction with setuid() but that's the problem: major security risk. system() 将与 setuid() 一起工作,但这就是问题所在:主要的安全风险。 The problem is system() starts a shell (bash, sh, etc.) using whatever environment is in place, and when you intend for it to run "iptables", my PATH could point to my own version of iptables which I could easily convince you to run for me, as root.问题是 system() 使用任何现有环境启动 shell (bash、sh 等),当您打算让它运行“iptables”时,我的 PATH 可以指向我自己的 iptables 版本,我可以轻松地说服你以 root 身份为我竞选。 You can seem to solve that by using a full path to iptables, but other environment variables (LD_PRELOAD_PATH, for example) can be used to convince tools to load rogue shared libraries -- again, running things as root which were not intended.您似乎可以通过使用 iptables 的完整路径来解决这个问题,但可以使用其他环境变量(例如 LD_PRELOAD_PATH)来说服工具加载恶意共享库——再次以 root 身份运行不希望的东西。

For what you need to do, securely, you must use one of the exec() family, and you must take control over its operating environment.对于您需要安全地执行的操作,您必须使用 exec() 系列之一,并且您必须控制其操作环境。 Anything else is asking for security abuse.其他任何事情都要求滥用安全性。 http://pubs.opengroup.org/onlinepubs/009695399/functions/environ.html appears to be a good place to learn more. http://pubs.opengroup.org/onlinepubs/009695399/functions/environ.html似乎是了解更多信息的好地方。

Why do you need to use system() ?为什么需要使用system() The man page is telling you exactly what to do:手册页确切地告诉您该怎么做:

Use the exec(3) family of functions instead, but not execlp(3) or execvp(3) .请改用exec(3)系列函数,但不要execlp(3)execvp(3)

You will probably be interested in the fork(2) and wait(2) system calls as well.您可能也会对fork(2)wait(2)系统调用感兴趣。

Something like this might help.这样的事情可能会有所帮助。 It's untested but should work.它未经测试,但应该可以工作。

    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;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM