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

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

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

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

Может ли кто-нибудь подробно объяснить команду?

решение1

Этот ответ является производным оторигинальная статья в Fedora MagazineМэтью Миллер, лицензированоCreative Commons Attribution-Share Alike 4.0лицензия.

Позволь мне объяснить:

env x='() { :;}; echo OOPS' bash -c :

В уязвимой системе это выведет сообщение «OOPS», но при этом произойдет тихое завершение работы, если bash был исправлен.

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

Это выведет сообщение «OOPS» на уязвимой системе, но выведет сообщение, “this is a test”если bash был исправлен.

И вы, вероятно, слышали, что это как-то связано с переменными окружения. Но почему код в переменных окружения выполняется? Ну, так не должно быть — но из-за функции, которую я склонен назвать слишком умной для ее же блага, есть место для изъяна. Bash — это то, что вы видите как приглашение терминала, но это также язык сценариев, и он может определять функции. Вы делаете это так:

$ Ubuntu()  { echo "Ubuntu is awesome."; }

и затем у вас есть новая команда. Помните, что echoздесь это еще не выполняется на самом деле; это просто сохранено как то, что произойдет, когда мы запустим нашу новую команду. Это будет важно через минуту!

$ Ubuntu
 Ubuntu is awesome.

Полезно! Но, скажем, по какой-то причине нам нужно выполнить новый экземпляр bash как подпроцесс и мы хотим запустить мою потрясающую новую команду в нем. Оператор bash -c somecommandделает именно это: запускает указанную команду в новой оболочке:

$ bash -c Ubuntu
  bash: Ubuntu: command not found

Ох. ​​Печально. Дочерний элемент не унаследовал определение функции. Но он наследует окружение — набор пар ключ-значение, которые были экспортированы из оболочки. (Это совершенно 'nuther-концепция; если вы с ней не знакомы, доверьтесь мне на данный момент.) И, оказывается, bash также может экспортировать функции. Итак:

$ export -f Ubuntu
$ bash -c Ubuntu
  Ubuntu is awesome.

Это все хорошо и замечательно — за исключением того, что механизм, с помощью которого это достигается,какой-то подозрительный. По сути, поскольку нет магии Linux/Unix для выполнения функций в переменных окружения, функция экспорта на самом деле просто создает обычную переменную окружения, содержащую определение функции. Затем, когда вторая оболочка считывает «входящую» среду и встречает переменную с содержимым, похожим на функцию, она оценивает ее.

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

Этого никогда не произойдет, если функция, сохраненная в переменной окружения, создана легитимно, с помощью export -f. Но зачем быть легитимным? Злоумышленник может просто придумать любую старую переменную окружения, и если она будет выглядеть как функция, новые оболочки bash подумают, что это так!

Итак, в нашем первом примере:

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

Команда envзапускает команду с заданным набором переменных. В этом случае мы устанавливаем xчто-то, что выглядит как функция. Функция — это просто один :, который на самом деле является простой командой, которая определена как ничего не делающая. Но затем, после which, semi-colonкоторый сигнализирует об окончании определения функции, идет команда echo. Она не должна быть там, но ничто не мешает нам сделать это.

Затем команда, заданная для запуска в этой новой среде, представляет собой новую оболочку bash, снова с командой « echo this is a test» или «ничего не делать :», после чего она завершит работу, совершенно безвредно.

Но — упс! Когда эта новая оболочка запускается и считывает среду, она добирается до переменной x, и поскольку она выглядит как функция, она ее оценивает. Определение функции безвредно загружается — и затем также запускается наша вредоносная полезная нагрузка. Так что, если вы запустите вышеописанное в уязвимой системе, вы получите “OOPS”распечатку обратно. Или злоумышленник может сделать гораздо хуже, чем просто распечатать что-то.

решение2

Внепатченная версия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 запускается как bash -c "echo this is a test", созданная переменная окружения обрабатывается как функция и загружается. Соответственно, получается вывод

    уязвимый
    Это тест

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

Связанный контент