Perl IPC::System::Simple capturex是如何工作的?
capurex的声明函数从不调用shell 我的假设: 因为没有调用shell,所以像Perl IPC::System::Simple capturex是如何工作的?,perl,Perl,capurex的声明函数从不调用shell 我的假设: 因为没有调用shell,所以像*或这样的字符不会被解释,因此不会造成伤害。 这就是为什么对外部程序的调用不会(或更少)受到以下示例中所示的意外错误输入或预期注入攻击的影响(很抱歉收到德语输出消息): 输出: user@host:-$ perl shell-injection.pl -1 \*.pl \; hostname shell-injection.pl host ---------- ls: Zugriff auf '*.pl' n
*
或这样的字符代码>不会被解释,因此不会造成伤害。
这就是为什么对外部程序的调用不会(或更少)受到以下示例中所示的意外错误输入或预期注入攻击的影响(很抱歉收到德语输出消息):
输出:
user@host:-$ perl shell-injection.pl -1 \*.pl \; hostname
shell-injection.pl
host
----------
ls: Zugriff auf '*.pl' nicht möglich: Datei oder Verzeichnis nicht gefunden
ls: Zugriff auf ';' nicht möglich: Datei oder Verzeichnis nicht gefunden
ls: Zugriff auf 'hostname' nicht möglich: Datei oder Verzeichnis nicht gefunden
"ls" unexpectedly returned exit value 2 at shell-injection.pl line 11.
user@host:-$
我的问题是:
可以使用哪些术语来描述代码是如何使用capturex
执行的?其他语言或环境中使用了哪些示例/技术/术语?(例如,系统调用
?)
在不进行输入检查的情况下使用这种技术(我假设不是)是否明智?如果不是,原因是什么(攻击向量)
了解capturex
如何运行的最佳方法是查看
sub以“列表形式”实现自己的管道打开,以绕过(古老的!)v5.6.x限制。它通过fork
-使用piped open调用一个进程,然后在子进程中“手动”exec
-调用命令,在子进程中可以使用列表表单。然后在父级中读取输出。跟随页面中的“管道”一词,然后是指向的链接
因此不可能涉及shell,因为列表表单中使用execvp(3)
system调用直接运行命令。(如果它不包含shell元字符,那么在使用单个参数运行时可能会发生什么情况。)因此,在shell中具有特殊含义的字符可以在命令中自由地用作文字字符
至于第二个问题——如果命令是由用户输入形成的,则必须始终认真检查!请注意,不应该在命令中直接使用输入,而应该支持程序编写命令所基于的关键字和参数。避免使用shell当然有帮助,但必须检查任何用户输入
注入错误更多的是编程错误,即变量插值没有正确使用,导致意外命令;这里不需要恶意行为,只需要暴露错误的“正确”输入。capturex所做的一切就是避免您必须生成有效的shell命令。可能仍然需要一些验证
可以使用哪些术语来描述代码是如何使用capturex
执行的
找到了IPC::System::Simple最新版本的源代码
在非Windows系统上,capturex
分别通过和Perl函数使用fork
和execve
系统调用。这种形式的Perl的exec
函数直接执行程序,而不是调用shell
exec "ls foo"; # Executes /bin/sh
exec { "/bin/sh" } "/bin/sh", "-c", "ls foo"; # Equivalent to previous.
exec { "ls" } "ls", "foo"; # Executes ls
在不进行输入检查的情况下使用这种技术(我假设不是)是否明智?如果不是,原因是什么(攻击向量)
如果您提供了要执行的程序的相对路径,并且用户设置了所使用的path
env var,该怎么办
如果您提供一个文件的相对路径作为参数,并且用户设置了当前工作目录,该怎么办
如果传递一个以-
开头的字符串,该怎么办?这可以解释为一种选择,而不是争论。(这就是为什么要使用'ls'、'-'、$file
而不是'ls'、$file
)
如果您通过。/../../../../../../etc/passwd
,该怎么办?如果程序在文件路径中使用参数,则可能会产生不期望的效果
如果您将正则表达式传递给一个程序,而正则表达式需要比宇宙寿命更长的时间才能匹配,该怎么办
可能还需要进行一些验证。capturex所能做的就是使您不必形成有效的shell命令
执行验证可能是接收程序的工作,也可能是您的工作,也可能是一个组合。是的,检查发送给外部命令的值,即使您认为自己不是,因为您有其他安全功能
在示例中,执行外部命令有两种不同的路径:
将一根字符串传递给shell。在backticks中,Perl构造了整个命令,如果shell需要处理它(globs等),那么shell就有机会插入它的手指。然后,shell会找出该命令的含义,解释其参数,并执行该工作。因此,*.tmp
仍然是一个全局:
将一个列表传递给系统并直接执行命令,而不使用shellcapturex
正在为您执行此操作。没有shell来解释诸如*.tmp
之类的内容,因此参数是它们的文本值。您将在system
或exec
的列表表单中看到相同的行为:
您仍然需要小心,因为@args
可能是空的,所以看起来还是单参数形式。有一个特殊的表单为您处理这个问题。看起来您已经指定了两次程序,但都能正常工作:
system { $program }, $program, @args;
exec { $program }, $program, @args
我在的“安全编程技术”一章中详细讨论了这一点,但您也可以在中阅读其中的一些内容。我从下面的答案中得出的结论大致如下:1)“capturex”使用“execvp”,这是对底层操作系统的“系统调用”。2) 因为没有使用shell,所以shell注入是不可能的,但这本身不是一个安全特性,因此不应该依赖。你们能帮我投票吗,哪个答案应该被接受再次感谢system$program,@args
可以在Windows上调用shell,即使@args
不是空的。我认为这样做是为了使shell内置的md
,copy
,del
等看起来像是POSIX对应的实用程序
system $single_string;
exec $single_string;
system $program, @args;
exec $program, @args
system { $program }, $program, @args;
exec { $program }, $program, @args