Perl IPC::System::Simple capturex是如何工作的?

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

capurex的声明函数从不调用shell

我的假设: 因为没有调用shell,所以像
*
这样的字符不会被解释,因此不会造成伤害。
这就是为什么对外部程序的调用不会(或更少)受到以下示例中所示的意外错误输入或预期注入攻击的影响(很抱歉收到德语输出消息):

输出:

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
    仍然是一个全局:
  • 将一个列表传递给系统并直接执行命令,而不使用shell
    capturex
    正在为您执行此操作。没有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