Красиво просим выполнить команду root и получить ее

Однажды была встреча по обзору SEV, и на ней мы рассмотрели какой-то инцидент, когда произошло что-то плохое, связанное с чем-то, что запускалось как root. Я уже не помню более тонких моментов этого, но резидент-вице-президент, который руководил шоу, вслух задавался вопросом, сколько «корневого воздействия» у нас было в целом в нашей инфра-части. Это привлекло мое внимание.

Я решил попытаться получить на него ответ. Во время встречи я собрал свой небольшой набор данных обо всем, что работает на любой производственной машине, затем сузил его до всего, что работает как root (то есть uid 0), а также с некоторыми (TCP) сетевыми портами прослушивания. Я подумал, что их будет легче всего “хлопнуть”. Подумайте о типе вещей «ВЫБРАТЬ … ОТ … ГДЕ uid = 0 И порты НЕ НУЛЕНЫ».

После того, как собрание закончилось без использования всех 90 минут, комната все еще была зарезервирована для другого 15 – 20 минут или около того, и несколько человек вышли посмотреть список. Можно было заметить, что эта единственная служба, работающая повсюду, имеет следующие варианты команд «до» и «после». Это была служба, которая обычно использовалась для измерения производительности и включала запуск внешней команды. Вы бы сказали: «Хорошо, проанализируйте это для меня», и он ненадолго откатится и откатит кучу точек данных по тому, на что вы нацелились. Это было нормально, но, к сожалению, вы могли указать произвольные команды для запуска до или после запроса.

Один из людей придумал тест и создал команду, которая должна запускать «touch / tmp / (их имя) -was-here». Затем они запустили его, и другой человек посмотрел, и, конечно же, файл появился в / tmp, принадлежащий пользователю root. (Я должен отметить, что у этого человека не было никаких магических разрешений для этой службы, чтобы вы не подумали, что здесь произошло именно это.)

Это была довольно пугающая дыра: вы могли попросить его запустить что угодно , и эти команды будут запускаться от имени пользователя root. Эээ, вздох, да, это сразу же превратилось в SEV службы безопасности. Каждая чертова машина, на которой запущено это программное обеспечение, может принадлежать любому, кто отправит правильно отформатированный запрос службе на коробке.

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

Итак, теперь это означало, что у нас практически везде есть корневая дыра, и невозможно узнать, использовалась ли она когда-либо. Это была ужасная ситуация. Затем следующим шагом было вернуться к исходному коду и выяснить, когда была добавлена ​​функция до и после публикации, когда она была отправлена ​​в производство, а затем выполнить математические вычисления даты, чтобы выяснить, как долго объекты были уязвимы. Когда выяснилось, что он был там в течение многих лет, что ж, теперь мы понятия не имели, нашел ли его кто-то другой, использовал его и удалил давным-давно, и все это с нулевым обнаружением.

Что еще могло сделать хуже? Что ж, мы обнаружили, что есть Actual Business Stuff, использующий эту функцию до и после публикации, и поэтому мы не могли просто отключить ее в ожидании исправления, по крайней мере, не без нарушения этой функции. Весело, правда?

К счастью, когда это произошло, один из сотрудников службы был доступен и отзывчив, и точно понимал, как закрыть иголку, чтобы закрыть дыру и не сломать бизнес. Они составили список каждой команды pre / post, которая действительно использовалась (естественно, просматривая дерево исходных текстов для клиентов этой службы), а затем превратили его в жестко запрограммированный контрольный список. Программа теперь будет отклонять любые команды pre / post, если они не были ей уже известны.

Это изменение залатало дыру, поэтому было выбрано вишенкой в ​​последнем выпуске и было выпущено довольно быстро, и это был конец того раунда веселья. К сожалению, это было только начало общего паттерна «эй, держу пари, я могу вытащить эту штуку», так как их было гораздо больше.

Можно подумать, что это положило начало новому «золотому веку», когда люди задумываются о том, чтобы не запускать что-либо от имени пользователя root без крайней необходимости, и обычно параноидально относятся к обработке подкоманд, но это не так в целом получилось. Вместо этого, я почти уверен, что это разозлило не тех людей, а остальное в значительной степени соответствует вашим ожиданиям.

Достаточно сказать, что если вы работаете где-то с достаточным количеством машин, вероятно, у вас есть способ получить root на всех из них, если вы можете поразить их несколькими пакетами. Я видел, как это происходило слишком много раз в достаточном количестве компаний, чтобы ожидать, что все останется в безопасности. Я не говорю о переполнении буфера и подобных вещах, хотя они тоже существуют. Я имею в виду, что просто попросите службу запустить команду для вас (как root), и она с радостью выполнит.

Может быть, это наша версия «бесконечных обезьян»: при наличии достаточного количества программистов, компьютеров и времени кто-то в компании в конечном итоге предоставит универсальный удаленный root-доступ любому, кто знает, как прочитать исходный код.