Объяснение команды для проверки контузии

Вот команда, я раньше проверял мою оболочку удара на ошибку Контузии:

env x='() { :;}; echo vulnerable' bash -c "echo this is a test"

Кто-либо может объяснить команду в деталях?

32
задан 29 September 2014 в 13:40

2 ответа

Этот ответ является производной исходной статьи о Журнале 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” распечатанный назад в Вас. Или, взломщик мог сделать намного хуже, чем просто вещи печати.

45
ответ дан 16 November 2019 в 11:15

В неисправленной версии 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,

  1. env - запустите программу в измененной среде.

  2. : сделайте только выходы со статусом выхода 0. посмотрите больше

  3. Когда новый экземпляр неисправленного удара, запущенного как bash -c "echo this is a test", обработанную переменную окружения рассматривают как функцию и загружают. Соответственно каждый получает вывод

    vulnerable
    this is a test

Примечание: Эхо вне функционального определения было неожиданно выполнено во время запуска удара. Функциональным определением является просто шаг, чтобы заставить оценку и использование происходить, само функциональное определение и используемая переменная среды произвольны. Оболочка смотрит на переменные среды, видит x, который похож на нее, встречает ограничения, которые она знает о том, на что похоже функциональное определение, и она оценивает строку, неумышленно также выполняя эхо (который мог быть любой командой, злонамеренной или не). Также Посмотрите это

2
ответ дан 16 November 2019 в 11:15

Другие вопросы по тегам:

Похожие вопросы: