Почему способность определять функции в переменной среды сама по себе не является угрозой безопасности?

9

Насколько я понимаю, в целом считается безопасным позволять кому-либо предоставлять информацию, которая будет храниться в переменной среды. Проблема заключается в том, что в конце определения функции внутри переменной среды будет выполняться код, когда запускается новый экземпляр bash, и вы, очевидно, не хотите, чтобы кто-либо выполнял какой-либо код на вашем сервере. , Сами определения функций, по-видимому, не являются угрозой безопасности, и допускаются, потому что они должны явно вызываться для выполнения кода.

Мой вопрос заключается в том, почему злоумышленник не может просто определить функцию, содержащую его вредоносный код, как обычную команду, lsа затем надеяться, что сценарий (или что-то еще выполняется) будет использовать эту команду в какой-то момент?

Пример того, что я имею в виду:

$ export ls='() { echo "doing bad things..."; }'
$ bash -c ls
doing bad things...
Рид Эспиноза
источник

Ответы:

10

Это риск для безопасности. Именно поэтому вы не можете сделать это при переключении в другой контекст (удаленное управление системой, изменение пользователей и т. Д.).

Если у вас есть возможность создать любую переменную среды, которую вы хотите, существует множество возможных способов выполнения произвольного кода.
Взять хотя $LD_PRELOADбы пример. Если у вас есть возможность установить эту переменную, вы можете заменить библиотечные функции и вставить туда свой код. Вы можете установить $DISPLAYпеременную и перенаправить экран X, к которому подключается программа, чтобы получить контроль над приложением.

Вот почему такие вещи, как sudoлишить окружение всех переменных. sudoпозволяет только несколько переменных выбора. И из этих переменных он очищает их (он проходит через $TERMпеременную, но не будет, если он содержит необычные символы).

Патрик
источник
Ух ты, я всегда удивлялся, почему у некоторых огромных скриптов, которые я делаю в BASH, были странные тайные сбои при запуске с sudo, особенно вокруг путей, которые заставили меня проверить запуск sudo и заблокировать их, но я никогда не знал, почему это произошло, и это было проблема, спасибо за хорошее объяснение re sudo, удаляя переменные среды.
Lizardx
3

Я бы сказал, когда bash - это ваш / bin / sh. Это не особенность оболочки Bourne, и я готов поспорить, что это не особенность оболочки Posix, на самом деле они могут явно запретить это.

Bash на самом деле представляет собой скорее оболочку производного от korn, чем оболочку bourne, несмотря на свое название, и это единственная оболочка, похожая на Korn, которая имеет такую ​​особенность, и, на мой взгляд, это особенность кухонной раковины, которая не имеет практических достоинств. Разработчики, которые избегают использования функций bash для стандартов, таких как оболочка bourne, оболочка posix или подмножество ksh88, общих для современных оболочек, или, другими словами, приверженных передовым методам и стандартным идиомам, шокированы, когда их программное обеспечение включено Linux и Mac и теперь потенциально уязвимы, так как авторы эксплойтов могут свободно использовать «bashisms», несмотря на их намерения. Насколько улучшена совместимость, когда она вызывается как / bin / sh, по сравнению с другими производными оболочки korn, только если / bin / sh является вашей оболочкой для входа в систему или интерактивной оболочкой, когда bash ведет себя больше как оболочка bourne, чем оболочка korn,

Я постараюсь убедить вас, что это функция кухонной раковины, с двумя случаями: вы - встроенный разработчик, который делает такие устройства, как маршрутизаторы, сетевое хранилище, на 1-е место больше, означает больше, память, а значит, больше стоимость, так меньше прибыли, поэтому, если это было причиной для использования этой функции bash, разве вы не должны вместо этого использовать FPATH и автозагрузку, функции ksh88? вместо передачи всей функции байт за байт в среде? Вы могли бы даже рассмотреть синтаксический анализ и обрезку среды оптом, прежде чем она доберется до сценария оболочки, который может неправильно анализировать переменную, например, просто отфильтровать ^ $ (. *) $ И т. П.

Это подчеркивает, что является уникальным в этом отношении, не имеет значения, что это за переменная, и скрипт не должен ссылаться или использовать переменную, он все равно может быть уязвим.

#!/bin/sh
exec /usr/local/myapp/support/someperlscript.pl

Для всего, что находится под солнцем, вышесказанное должно быть таким же безопасным, как сценарий perl, вы не используете переменные, как вы могли бы их пропустить? Изменение на

#!/bin/bash -norc
exec /usr/local/myapp/support/someperlscript.pl

Также не помогает, это не имеет ничего общего с ENV или чем-то подобным - все обжигаются, потому что bash должен быть уникальным. Тот факт, что у bash версии 2 есть проблема, для меня доказывает, что никто никогда не использовал эту функцию для своих приложений, потому что в противном случае она не должна была бы скрываться так долго. И что еще хуже, в принципе не избежать этой функции . Вот пример с: с 'su -', который, если вы спросите кого-то, объяснит, что он отбрасывает среду, проверьте страницу руководства, и вы найдете только 99,9%. Я протестировал этот правильный путь, так как в этой системе / bin / sh является оболочкой входа пользователя root, а / bin / sh - НО bash , в этом примере я пытаюсьзакалить мой .bash_profile. Я переименовал свой существующий для root (который включен), но я думал, что если su, то, возможно, sudo, в любом случае, я изменил на это:

exec env -i TERM=vt102 LOGNAME=root USER=root HOME=/var/root /bin/ksh -i

Итак, я на самом деле полностью отбрасываю среду и использую минимальный env, а затем запускаю оболочку, у которой не должно быть проблемы, вместо текущего процесса. Тогда вместо стандартного примера попробуйте:

%dock='() { echo -e "\e[2t\c"; echo dockshock;} ; dock' su 

Это показывает, что это не имеет никакого отношения к анализу какой-либо конкретной функции, и эксплойт может ссылаться на эту функцию и использовать ее. Вы можете представить себе функцию, имеющую логику для проверки на наличие прав root и т. Д. В этом случае это просто модифицированная форма функции для пиктограммы или закрепления окна терминала с использованием escape-последовательности, что довольно стандартно, поэтому после нажатия кнопки deiconify я увидеть док-шок - но что с того? Теперь попробуйте это:

%TERM='() { echo -e "\e[2t\c"; echo dockshock;} ; TERM' su - 

И угадайте, что? Окно засасывается в док. Вот как это выглядит потом ..

%TERM='() { echo -e "\e[2t\c"; echo dockshock;} ; TERM' su -
Password:
dockshock
# env
_=/usr/bin/env
HOME=/var/root
LOGNAME=root
TERM=vt102
USER=root
# echo $0
/bin/ksh
#

Итак, так много за это! Экспортируемые функции на самом деле имеют приоритет над сценариями rc. Вы не можете увернуться от этого.

Дэн ЛаБелл
источник
1
POSIX разрешил экспортируемые функции в проекте 2 и запретил их впоследствии. Эта особенность безумна.
mikeserv