Как работает IP C :: System :: Simple capturex? - PullRequest
3 голосов
/ 03 апреля 2020

В документации из capurex говорится, что функция никогда не вызывает оболочку .

Мое предположение: Поскольку оболочка не является При вызове символы типа * или ; не будут интерпретироваться и, следовательно, не могут причинить вред. Вот почему вызовы внешних программ не (или менее) восприимчивы к случайно искаженному вводу или намеренным инъекционным атакам, как показано в примере ниже (извините за немецкие выходные сообщения):

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);

Вывод:

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:-$ 

Мои вопросы:

  1. Какие терминологии можно использовать для описания того, как код выполняется с capturex? Какие примеры / методы / термины используются в других языках или средах? (например, system call?)

  2. Действительно ли целесообразно использовать эту технику без проверки ввода (я полагаю, нет) и, если нет, по какой причине (вектор атаки)?

Ответы [ 3 ]

6 голосов
/ 04 апреля 2020

Лучший способ получить информацию о том, как работает capturex, - посмотреть на его источник .

Подпрограмма реализует свой собственный открытый канал в "форме списка", чтобы обойти (древние!) Ограничения v5.6.x. Он делает это путем fork -ing процесса, используя piped open и затем "1009 * -ing вручную", вводя команду в дочернем элементе, где он может использовать форму списка. Затем вывод читается в родительском. Следуйте слову «труба» на странице open , а затем перейдите по ссылке perlip c.

Так что тут не может быть никакой оболочки, поскольку exe c в форме LIST использует системный вызов execvp(3) для непосредственного запуска команды. (Что может произойти, если он также работает с одним аргументом, если он не содержит метасимволов оболочки.) Таким образом, символы, имеющие особое значение в оболочке, могут свободно использоваться в качестве буквенных символов в команде.

Что касается второго вопроса - если команда формируется с помощью пользовательского ввода, она всегда должна проверяться действительно тщательно! Обратите внимание, что не следует буквально использовать ввод в команде, но следует поддерживать ключевые слова и параметры, на основе которых программа составляет команду. Конечно, помогает избежать оболочки, но любой пользовательский ввод должен быть проверен.

Ошибка внедрения - скорее ошибка программирования, вследствие которой интерполяция переменных не используется правильно и приводит к непреднамеренной команде; там нет необходимости в злонамеренных действиях, только в «правильном» вводе, раскрывающем ошибку.

2 голосов
/ 04 апреля 2020

Да, проверьте значения, которые вы отправляете внешним командам, даже если вы об этом не думаете, потому что у вас есть какая-то другая функция безопасности.

В вашем примере у вас есть два разных способа выполнения внешних команд :

  1. Передать оболочке одну строку. В кавычках Perl создает всю команду, и если она выглядит так, как будто оболочка должна с ней справиться (globs, et c), оболочка получает шанс засунуть пальцы. Затем оболочка выясняет, что команда означает, интерпретирует свои аргументы и делает работу. Итак, *.tmp по-прежнему глобус:
system $single_string;
exec $single_string;
Передать список в систему и выполнить команду напрямую, без какой-либо оболочки. capturex делает это для вас. Нет оболочки для интерпретации таких вещей, как *.tmp, поэтому аргументы являются их буквальными значениями. Вы могли бы увидеть то же поведение с формами списка system или exec:
system $program, @args;
exec $program, @args

Вы все равно должны быть осторожны, потому что @args может быть пустым, так что выглядит как форма единственного аргумента снова. Есть специальная форма, которая обрабатывает это для вас. Похоже, вы указываете программу дважды, но все работает:

system { $program }, $program, @args;
exec { $program }, $program, @args

Я подробно обсуждаю это в главе Мастеринг Perl, посвященной технике безопасного программирования, но Вы можете прочитать о некоторых из них в perlse c тоже.

2 голосов
/ 04 апреля 2020

Все, что делает capturex, это избавляет вас от необходимости создавать правильную команду оболочки. Некоторая проверка все еще может потребоваться.


Какие терминологии можно использовать для описания того, как код выполняется с capturex?

Источник для последней версии IP C :: System :: Simple найден здесь .

В не Windows системах capturex использует * 1017 Системные вызовы * и execve через функции open(my $pipe, '-|') и exec BLOCK LIST Perl соответственно. Эта форма функции Perl exec выполняет программу напрямую, а не вызывает оболочку.

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, - это избавляет вас от необходимости формировать допустимую команду оболочки.

Возможно, программа-получатель выполняет проверку, она может быть вашей или комбинацией.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...