Вот команда, я раньше проверял мою оболочку удара на ошибку Контузии:
env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
Кто-либо может объяснить команду в деталях?
Этот ответ является производной исходной статьи о Журнале Fedora Matthew Miller, лицензируемого под Долей Атрибуции Creative Commons Одинаково 4,0 лицензии.
Позвольте мне объяснить:
env x='() { :;}; echo OOPS' bash -c :
Это распечатает “OOPS” в уязвимой системе, но выйдет тихо, если удар был исправлен.
env x='() { :;}; echo OOPS' bash -c "echo this is a test"
Это распечатает “OOPS” в уязвимой системе, но печать “this is a test”
если удар был исправлен.
И Вы, вероятно, услышали, что это имеет некоторое отношение к переменным среды. Но, почему код в переменных среды выполнен? Ну, это, как предполагается, не — но из-за функции, которую я испытываю желание назвать немного слишком умным для ее собственной пользы, существует некоторое место для дефекта. Bash - то, что Вы рассматриваете как терминальную подсказку, но это также - язык сценариев и имеет способность определить функции. Вы делаете это как это:
$ Ubuntu() { echo "Ubuntu is awesome."; }
и затем у Вас есть новая команда. Следует иметь в виду что echo
здесь еще на самом деле не выполняется; это просто сохраняется как, что произойдет, когда мы выполним нашу новую команду. Это будет важно через минуту!
$ Ubuntu
Ubuntu is awesome.
Полезный! Но, скажем, по некоторым причинам, Мы должны выполнить новый экземпляр удара, как подпроцесс, и хотеть выполнить мою потрясающую новую команду под этим. Оператор bash -c somecommand
делает точно это: выполняет данную команду в новой оболочке:
$ bash -c Ubuntu
bash: Ubuntu: command not found
Ох. Печальный. Ребенок не наследовал функциональное определение. Но, это делает свойственный среда — набор пар "ключ-значение", которые были экспортированы из оболочки. (Это - целое ‘nuther понятие; если Вы не знакомы с этим, доверяете мне на данный момент.) И, это складывается, удар может экспортировать функции также. Так:
$ export -f Ubuntu
$ bash -c Ubuntu
Ubuntu is awesome.
Который является всем хорошо и хороший — за исключением того, что механизм, которым это выполняется, является видом изворотливых. В основном с тех пор нет никакого волшебства Linux/Unix для того, чтобы сделать функции в переменных среды, функция экспорта на самом деле просто создает регулярную переменную среды, содержащую функциональное определение. Затем когда вторая оболочка читает “входящую” среду и встречается с переменной с содержанием, которое похоже на функцию, она оценивает его.
В теории это совершенно безопасно, потому что, помните, определение функции на самом деле не выполняет ее. Кроме — и это - то, почему мы здесь — была ошибка в коде, где оценка не остановилась, когда конец функционального определения был достигнут. Это просто kepts движение.
Этого никогда не происходило бы, когда функция, сохраненная в переменной среды, сделана законно, с export -f
. Но, почему быть законным? Взломщик может просто составить любую старую переменную среды, и если она будет похожа на функцию, то новые оболочки удара будут думать, что это!
Так, в нашем первом примере:
env x='() { :;}; echo OOPS' bash -c "echo this is a test"
env
управляйте выполняет команду с данным переменным набором. В этом случае мы устанавливаем x
к чему-то, что похоже на функцию. Функция является просто синглом :
, который является на самом деле простой командой, которая определяется как выполнение ничего. Но затем, после semi-colon
который сигнализирует о конце функционального определения, существует echo
команда. Это, как предполагается, не там, но нет ничего мешающего нам делать его.
Затем команда, данная выполненному с этой новой средой, является новой оболочкой удара, снова с “echo this is a test
” или “ничего не делают :
” команда, после которой это выйдет, полностью безопасно.
Но — ой! Когда та новая оболочка запускает и читает среду, это добирается до x
переменная, и так как это похоже на функцию, это оценивает его. Функциональное определение безопасно загружается — и затем наша злонамеренная полезная нагрузка инициирована также. Так, при выполнении вышеупомянутого в уязвимой системе Вы доберетесь “OOPS”
распечатанный назад в Вас. Или, взломщик мог сделать намного хуже, чем просто вещи печати.
В неисправленной версии bash
это хранит экспортируемые функциональные определения как переменные среды.
Сохраните функцию x
как,
$ x() { bar; }
$ export -f x
И проверьте его определение как,
$ env | grep -A1 x
x=() { bar
}
Таким образом, можно было использовать это путем определения его собственных переменных среды и интерпретирует их как функциональные определения. Например, env x='() { :;}'
рассматривался бы как
x() { :;
}
env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
От man env
,
env
- запустите программу в измененной среде.
:
сделайте только выходы со статусом выхода 0
. посмотрите больше
Когда новый экземпляр неисправленного удара, запущенного как bash -c "echo this is a test"
, обработанную переменную окружения рассматривают как функцию и загружают. Соответственно каждый получает вывод
vulnerable this is a test
Примечание: Эхо вне функционального определения было неожиданно выполнено во время запуска удара. Функциональным определением является просто шаг, чтобы заставить оценку и использование происходить, само функциональное определение и используемая переменная среды произвольны. Оболочка смотрит на переменные среды, видит x, который похож на нее, встречает ограничения, которые она знает о том, на что похоже функциональное определение, и она оценивает строку, неумышленно также выполняя эхо (который мог быть любой командой, злонамеренной или не). Также Посмотрите это