IPC::System::Simple capturex 如何工作?

Bor*_*pen 3 perl

文档capurex,指出该功能从未调用外壳

我的假设: 由于没有调用 shell,字符喜欢*;不会被解释,因此不会造成伤害。这就是为什么调用外部程序不会(或不太容易)受到意外格式错误的输入或预期注入攻击的影响,如下例所示(抱歉,德语输出消息):

use v5.26;
use IPC::System::Simple 'capturex';

# (very) vulnerable to shell injection
say `ls @ARGV`;

# just a visual line
say '----------';

# no shell injection "possible" (?)
say capturex('ls', @ARGV);
Run Code Online (Sandbox Code Playgroud)

输出:

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:-$ 
Run Code Online (Sandbox Code Playgroud)

我的问题:

  1. 可以使用哪些术语来描述代码是如何执行的capturex?在其他语言或环境中使用的示例/技术/术语是什么?(例如system call?)

  2. 在没有输入检查的情况下使用这种技术实际上是可取的(我认为不是),如果不是,出于什么原因(攻击向量)?

zdi*_*dim 6

了解其capturex运作方式的最佳方式是查看其来源

The sub implements its own piped open in "list-form", to work around the (ancient!) v5.6.x limitations. It does so by fork-ing a process using piped open and then "manually" exec-ing the command in the child, where it can use the list-form. Then the output is read in the parent. Follow the word "pipe" in the open page, and then the link to perlipc.

So there can be no shell involved since exec in the LIST form uses execvp(3) system call to directly run the command. (What may happen when it runs with a single argument as well, if it contains no shell meta-charactes.) Thus the characters that (would) have a special meaning in the shell may be used freely as literal characters in the command.

As for the second question -- if a command is formed with user-input it must always be checked really carefully! Note that one shouldn't literally use input in a command, but rather support keywords and parameters based on which the program composes the command. Avoiding the shell of course helps but any user input must be checked.

The injection bug is more of a programming error, whereby variable interpolation isn't used right and results in an unintended command; there is no need for malicious acts there, just for the "right" input that exposes the bug.