此(Are system() calls evil?)帖子中的帖子说:
您的程序的权限由其衍生的程序继承。如果您的应用程序曾作为特权用户运行,那么所有人必须做的就是将自己的程序与您所支持的东西的名称放在一起,然后可以执行任意代码(这意味着您永远不应该运行使用系统的程序) root或setuid root)。
但是system("PAUSE")
和system("CLS")
是操作系统的外壳,所以如果黑客只能封装到硬盘驱动器上的特定安全位置,黑客怎么可能介入?
在调用系统之前使用fflush或_flushall显式刷新还是关闭任何流消除所有风险?
答案 0 :(得分:2)
系统函数将命令传递给命令解释器,命令解释器将字符串作为操作系统命令执行。系统使用COMSPEC和PATH环境变量来定位命令解释程序文件CMD.exe。如果command为NULL,则该函数仅检查命令解释器是否存在。
在调用系统之前,必须使用fflush或_flushall明确刷新 - 或关闭任何流。
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/system-wsystem
如果有任何疑问,这是MS实施的实际片段(非常简单明了):
// omitted for brevity
argv[1] = _T("/c");
argv[2] = (_TSCHAR *) command;
argv[3] = NULL;
/* If there is a COMSPEC defined, try spawning the shell */
/* Do not try to spawn the null string */
if (argv[0])
{
// calls spawnve on value of COMSPEC vairable, if present
// omitted for brevity
}
/* No COMSPEC so set argv[0] to what COMSPEC should be. */
argv[0] = _T("cmd.exe");
/* Let the _spawnvpe routine do the path search and spawn. */
retval = (int)_tspawnvpe(_P_WAIT,argv[0],argv,NULL);
// clean-up part omitted
至于对_tspawnvpe
实际可能做的事情的关注,答案是:没有什么神奇之处。 spawnvpe
和朋友的确切调用顺序如下(因为任何拥有许可版本的MSVC的人都可以通过检查spanwnvpe.c
源文件轻松学习):
_tspawnve
。如果文件名表示可执行文件的绝对路径或相对于当前工作目录的有效路径,则spawnve
将成功。没有进一步的检查 - 所以是的,如果当前目录中存在名为cmd.exe
的文件,它将在system()
调用的讨论的上下文中首先被调用。spwanvpe
,检查是否成功就是这样。没有特别的技巧/检查。
答案 1 :(得分:1)
原始问题引用POSIX而非Windows。这里没有COMSPEC
(有SHELL
但system()
故意不使用它);但/bin/sh
完全是完全脆弱的。
假设/ opt / vuln / program system("/bin/ls");
看起来完全无害,对吧?都能跟得上!
$ PATH=. IFS='/ ' /opt/vuln/program
这将在当前目录中运行名为bin
的程序。哎呀。防范这种事情是如此困难,应该留给极端的专家,比如撰写sudo
的人。消毒环境非常困难。
所以你可能会想到system()
api是什么。我实际上并不知道它是为什么被创建的,但是如果你想做一个像ftp
这样的功能,那么!在shell中本地执行!命令你可以做... else if (terminalline[0] == '!') system(terminalline+1); else ...
因为它是'无论如何,这将是完全不安全的,没有必要使其安全。当然,一个真正现代的用例不会这样做,因为system()
并没有看$SHELL
但是很好。