我有一个在C中运行的程序。这需要使用system执行“iptables”命令。
我试过
setuid(0);
system("iptables .... ");
setuid和系统不共存。来自系统手册页
不要使用程序中的system() 使用set-user-ID或set-group-ID 特权,因为奇怪的价值观 对于一些 环境变量可能用于破坏系统完整性。 使用exec(3)系列函数 代替, 但不是execlp(3)或execvp(3)。事实上,system()不会起作用 适当的程序与 set-user-ID或set- / bin / sh为bash的系统上的group-ID权限 版本2,因为bash 2下降 启动时的权限。 (Debian使用修改后的bash,当调用时不会这样做 SH)
我怎样才能克服我的问题?
由于
答案 0 :(得分:4)
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似乎是了解更多内容的好地方。
答案 1 :(得分:2)
为什么需要使用system()
? man page正在告诉您该做什么:
答案 2 :(得分:2)
这样的事可能会有所帮助。这是未经测试但应该有效。
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;
}