Объяснение команды для проверки снарядов
Вот команда, которую я использовал, чтобы проверить мою оболочку bash на наличие ошибки Shellshock:
env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
Может кто-нибудь, пожалуйста, объясните команду в деталях?
2 ответа
Этот ответ является производным от оригинальной статьи о журнале Fedora Мэтью Миллера, лицензированной по лицензии 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
Ooh. Печальный. Ребенок не унаследовал определение функции. Но это присуще среде - совокупности пар ключ-значение, которые были экспортированы из оболочки. (Это совершенно другая концепция; если вы не знакомы с этим, поверьте мне.) И, оказывается, 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 к чему-то, что выглядит как функция. Функция только одна :, которая на самом деле простая команда, которая определяется как ничего не делать. Но потом, после semi-colon который сигнализирует об окончании определения функции, есть echo команда. Это не должно быть там, но ничто не мешает нам сделать это.
Затем команда для запуска в этой новой среде представляет собой новую оболочку bash, снова с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 запущен как
bash -c "echo this is a test"созданная переменная среды обрабатывается как функция и загружается. Соответственно получается выход
уязвимый
Это тестПримечание: эхо за пределами определения функции было неожиданно выполнено во время запуска bash. Определение функции - это всего лишь шаг к выполнению оценки и эксплуатации, само определение функции и используемая переменная окружения являются произвольными. Оболочка просматривает переменные окружения, видит x, который выглядит так, как будто он соответствует ограничениям, которые он знает о том, как выглядит определение функции, и он оценивает строку, непреднамеренно выполняя также эхо (которое может быть любой командой, злонамеренной или нет), Также смотрите это