![](https://habrastorage.org/getpro/habr/upload_files/47e/97d/3ad/47e97d3ad1068f4cc5063a31346bf6d8.png)
Представьте себе: обнаружен бэкдор в OpenSSH, мейнтейнеры спешат выпустить релиз с исправлениями, исследователи безопасности обмениваются техническими деталями, чтобы проанализировать вредоносный код. Разгораются обсуждения по поводу причастности и мотивов злоумышленника, а технические СМИ бросаются освещать историю. Почти что эпическое происшествие, удар по доверию, лежащему в основе разработки с открытым исходным кодом, яркое напоминание о рисках атак на цепочки поставок. В равной мере блестяще и коварно.
Если вы следите за новостями безопасности, то, возможно, сразу вспомните атаку на репозиторий liblzma/xz‑utils в начале этого года, конечной целью которой был бэкдор в OpenSSH. Однако ниже мы обсудим не случай с xz‑utils, ведь мало кто помнит, что бэкдор в xz‑utils на самом деле второй широко известной попыткой внедрения бэкдора в OpenSSH. Впервые это произошло более 22 лет назад, в 2002 году. Эта статья рассказывает историю того бэкдора и тому, чему можно научиться из атаки, произошедшей более двух десятилетий назад.
Предыстория
Атака 2002 года была довольно простой. Оригинальный анонс: OpenSSH Security Advisory: Trojaned Distribution Files.
В те времена, исходный код OpenSSH размещался на ftp.openbsd.org, и каким‑то образом он был заменён на версию с бэкдором. Точно неизвестно, как это произошло, но злоумышленнику удалось подменить файлы.tar.gz для нескольких версий. В то время в хакерской среде активно распространялись эффективные эксплойты для серверов, так что в этом нет ничего особо удивительного. К счастью, благодаря разнице в контрольных суммах файлов, бэкдору не удалось долго просуществовать. Например, при попытке собрать версию OpenSSH с бэкдором на FreeBSD система «портов» автоматически проверяла контрольные суммы пакетов, и так как в ней уже была информация о контрольных суммах этих версий до внедрения бэкдора, она сообщала о расхождении. Если бы атакующие дождались выхода новой версии и сразу заменили бы файлы.tar.gz и файлы с контрольными суммами, они могли бы добиться гораздо большего успеха.
Как не посмотри, это был простой бэкдор, возможно, самый простой, который можно себе представить. Шаг первый: в сборку пакета были внесены изменения, благодаря которым при запуске configure компилировались и выполнялись файлы добавленные злоумышленником. Шаг второй: вредоносный код подключался к захардкоженному IP‑адресу в Австралии каждый час и получал список команд для выполнения на скомпрометированном устройстве.
Мы до сих пор не знаем, кто именно стоял за этим бэкдором, но распространённое мнение (по крайней мере среди разработчиков OpenBSD, с которыми я общался) заключается в том, что это были просто мелкие проделки, которые были вполне обычным делом для 2002 года. Это, конечно, был не первый подобный случай. Например, Wu‑FTPd, самый популярный ftpd 90-х годов, столкнулся с чем‑то подобным еще в 1993 году. Однако это было хорошим предзнаменованием того, что последует дальше. Случай 2002 года представляет собой интересное историческое событие, поскольку он демонстрирует как сходства, так и различия по сравнению с современной попыткой внедрения бэкдора xz‑utils в OpenSSH. Исследуя эти различия мы можем извлечь полезные уроки на будущее.
Сходства
Очевидное сходство между этими двумя событиями заключается в том, что оба они были нацелены на OpenSSH. И на это есть веские причины. OpenSSH — один из основных объектов исследования уязвимостей, потому что если у вас есть уязвимость в OpenSSH для удаленного доступа без авторизации, то у вас, по сути, есть «универсальный ключ» от Интернета. Однако, действительно серьёзных уязвимостей в OpenSSH почти не осталось — прошло около 20 лет с момента последней крупной находки. Поэтому, если не удаётся найти уязвимость, следующий вариант — внедрить её.
Внедрение бага,который можно использовать для уязвимости («bugdoor»), и который при этом не смогут заметить разработчики во время код‑ревью, вероятно, является лучшим вариантом. Примечательно, что и в 2002, и в 2024 году мы столкнулись не с багдором, а с бэкдором. Вероятнее всего, это потому, что разработка эксплойтов сложна, а серверных эксплойтов в особенности. Учитывая, сколько усилий требуется для того, чтобы в принципе получить возможность изменять исходный код, не удивительно, что злоумышленники хотят выбрать более надежный способ. Контраргумент заключается в том, что мы, возможно, никогда не видим багдоры, потому что они редко попадаются (а если и попадаются, то не рассматриваются как умышленное вмешательство).
Есть и другие сходства. Например, в событиях 2002 и 2024 годов обе атаки были нацелены на системы сборки. Это также имеет смысл, поскольку системы сборки являются идеальным сочетанием сложности и гибкости. По сути, в большинстве систем сборки практически нет ограничений на то, что можно сделать. Это необходимо для того, чтобы обеспечивать совместимость на разных платформах, таких как Linux, MacOS и Windows. Добавьте сюда поддержку нескольких архитектур и старых версий, и… понимаете, о чём речь. Основным принципом проектирования систем сборки является «просто заставить это работать», поэтому они превращаются в сложный набор директив, правил, переменных и команд. Пока они работают корректно, можно предположить, что очень немногие внимательно следят за содержимым своих скриптов сборки, включая самих разработчиков и мейнтейнеров. Это идеальное место для вставки первого крючка для бэкдора, скрывающегося у всех на виду.
Однако то, что делает OpenSSH привлекательной целью, делают его еще и сложной целью. Им пользуются все, поэтому вероятность того, что кто‑то заметит что‑то неладное, достаточно высока. Обе атаки были довольно быстро обнаружены. Атака 2002 года была обнаружена разработчиком, заметившим, что контрольные суммы загруженных исходников не совпадают, а атака 2024 года была найдена разработчиком после тщательного исследования проблемы с производительностью. Теория «многих глаз» в безопасности open source сейчас не слишком популярна, но действительно складывается впечатления, что чем крупнее проект, тем меньше он подвержен уязвимостям.
Последнее сходство заключается в том, что в обоих случаях нападавшие остались неизвестными. Это может показаться незначительным, но важно заметить, что наши обычные подходы к установлению источника уязвимости плохо работают для атак на цепочки распространения. Размер выборки таких событий невелик, цели злоумышленников непрозрачны, и в каждом случае наблюдается высокая степень индивидуализации атаки. Это работает на пользу атакующим: атака либо оказывается успешной, либо проваливается так, что невозможно определить ответственного.
Различия
Несмотря на сходства, эти две атаки существенно отличаются по своему намерению и исполнению. Интересно наблюдать, как сильно изменилась экосистема за это время — сейчас для того, чтобы подобная атака увенчалась успехом, всё должно пройти идеально. Внедрение бэкдора в xz‑utils прошло не без изъянов, но многие шаги были сделаны правильно, и атакующие были намного ближе к успеху по сравнению с атакой 2002 года. Основное различие заключается в мотивации и намерениях нападавших.
Считается, что в 2002 году все, чего хотели атакующие — повеселиться и посеять хаос, и вполне вероятно, что их не особо беспокоило, будут ли они пойманы. На самом деле, если целью злоумышленников было похвастаться своей проделкой впоследствии, то их поимка играла бы скорее на пользу.. В то же время в 2024 году злоумышленники, судя по всему, выполняли конкретную задачу и явно намеревались впоследствии использовать бэкдор для достижения своих целей. Иными словами, атака на xz‑utils был задуман как инструмент разведки, тогда как атака 2002 года была скорее «перформансом», чем «постоянной угрозой».
Одно из ключевых различий с технической точки зрения состоит в том, что бэкдор xz‑utils был нацелен на артефакты сборки, а не на саму систему сборки. В худшем случае атака 2002 года могла скомпрометировать только те системы, которые компилировали OpenSSH самостоятельно. Если бы атака на xz увенчалась успехом, со временем каждая машина, работающая на Linux с systemd и использующая OpenSSH, могла бы быть скомпрометирована в любой момент на усмотрение злоумышленников.
В данном случае «на усмотрение» здесь ключевая деталь. Бэкдор xz‑utils давал злоумышленникам вариативность: они могли использовать скрытые функции бэкдора выборочно. По сравнению с автоматическим запуском обратного шелла (reverse shell) это значительно снижает риск обнаружения бэкдора и позволяет использовать его точечно. Это было осознанное решение нападавших, так как они могли выбрать и другой вариант — компрометировать все системы, на которых выполнялся их код.
Также стоит отметить, насколько косвенной была атака 2024 года. Вместо того чтобы пытаться внедрить бэкдор в сам OpenSSH, злоумышленники заметили, что современные дистрибутивы Linux неожиданно добавили зависимость от liblzma в OpenSSH. Это и был ключ к победе: вместо того чтобы атаковать зрелый и хорошо финансируемый проект, поддерживаемый всемирно известными специалистами по безопасности, они нацелились на малоизвестную библиотеку без существенного финансирования, которую никто и не считал критически важной. Defenders think in lists, attackers think in graphs
Помимо этого, мое внимание привлекла еще одна небольшая инновация. Вместо того чтобы вставлять запутанные скрипты, прятаться в C‑файлах (как в атаке 2002 года) или загружать payload по сети, бэкдор xz имел заранее подготовленный payload внутри бинарного тестового файла. Это оказалось эффективным подходом, поскольку никто не заметил payload в репозитории исходного кода xz‑utils до тех пор, пока бэкдор не был обнаружен во время анализа производительности. Если бы не было снижения производительности и злоумышленники вели себя менее агрессивно в своих социальных манипуляциях, я предполагаю, что и «крючок», и payload могли бы оставаться незамеченными долгое время.
Последнее большое различие заключается в методологии нападавших. В атаке 2002 года злоумышленники напрямую атаковали инфраструктуру, на которой размещался OpenSSH. С другой стороны, бэкдор xz был кульминацией длительной кампании социальной инженерии, в ходе которой злоумышленник стал полноправным членом основной команды разработчиков. Как ни посмотри, это впечатляющее достижение.
Анализ
В контексте этих событий, есть много вещей, которые стоит разобрать. Атаки на цепочку поставок определенно эволюционировали, но... не настолько, насколько ожидалось? Давайте отложим подход «вредоносного инсайдера», используемого нападавшими из xz‑utils, и сосредоточимся на подходе «атака на инфраструктуру». Если детально рассмотреть атаку 2002 года, то на самом фундаментальном уровне ничего не мешает реализовать эту атаку и сегодня. С небольшой долей ловкости и терпения атака, направленная на инфраструктуру распространения исходного кода, все еще вполне возможна.
Мой любимый пример — zlib. Так же, как и xz‑utils, это библиотека сжатия. Можно сказать, что это библиотека сжатия с большой буквы, потому что zlib встречается повсеместно — в том числе в OpenSSH. Новые версии их исходного кода распределяются через zlib.net, а сервер, на котором размещен zlib.net, обслуживается небольшой компанией из Мичигана под названием a2hosting.com, у которых стоимость managed VPS начинается с $26,95 в месяц. Эта хостинговая компания особенно любит использовать CPanel и exim, которые включены в том числе на zlib.net.
Это означает, что целостность цепочки распространения для практически всего зависит от порядочности a2hosting.com и отсутствия удаленных уязвимостей в CPanel или exim. И ситуация не особо обнадеживающая, при этом я даже не упомянул Pure‑FTPD, Apache httpd или Dovecot (а это только то, что прямо используется на zlib.net, не учитывая то, как может быть атакован сам a2hosting.com). Найдите уязвимость в любом из этих проектов или способ для внедрения бэкдора, и шансы внедрить бэкдор в цепочку распространения zlib будут весьма высоки.
В последние годы, в случае zlib, ситуация улучшилась, потому что теперь они используют выделенный сервер. Долгое время zlib.net располагался на виртуальном хростинге (т. е. любой человек мог купить хостинг на том же сервере). Это стало шуткой среди исследователей уязвимостей: поскольку найти ошибку в zlib чрезвычайно сложно, преднамеренно добавить баг в код, когда разработчик объявляет о новом релизе, было бы, вероятно, наиболее простым вариантом.
Смысл всего этого не в критике zlib. Их поддержка — мирового уровня (мне посчастливилось читать их код таблицы Хаффмана в ходе этого анализа), и они отлично работают. Проблема не уникальна для zlib, xz‑utils или OpenSSH. Все подвержены подобным рискам. Суть в том, что когда смотришь на суммарные риски, можно сделать вывод, что мы находимся в действительно печальном положении. Я обычно не склонен к преувеличениям, но наша текущая уязвимость к атакам на цепочку распространения весьма тревожна.
Давайте рассмотрим ситуацию. Если вы компилируете OpenSSH из исходного кода, у вас в адресном пространстве окажется код (библиотеки и исполняемые файлы) примерно из 5 различных пакетов дистрибутива. Не так плохо. Но на практике большинство использует Linux‑системы на базе systemd — в этом случае в адресном пространстве OpenSSH окажется код из около 30 разных пакетов (включая наших друзей xz и zlib). Это уже начинает настораживать..
Но на это еще не все. Хотя и атака 2002 года, и атака на xz‑utils были нацелены прямо на OpenSSH, это вовсе не обязательно. Если вы можете запустить бэкдор под root где‑то в системе, вы можете внедриться в процесс sshd. Это один дополнительный шаг, но не очень сложный. На стандартной системе Ubuntu Server 22.04 после загрузки 97 пакетов работает из под root (это 16% всех пакетов, установленных по умолчанию). На моем рабочем Linux‑десктопе (где я почти каждый день использую удаленный доступ через OpenSSH) код из целых 384 пакетов работает из под root.
Но действительно ли возможно все это защитить? Сотни проектов от команд с различной культурой, мотивацией, финансированием, опытом и ресурсами? Неважно, идет ли речь о атаке, сосредоточенной на инфраструктуре, как в 2002 году, или о социальной инженерии, как в 2024 году. В любом случае, я не уверен, что мы можем защититься от этого с текущим подходом к проектированию операционных систем.
Подводя итоги
Атаки на цепочки распространения все также актуальны, как и 20 лет назад, и мы отстаем в защите от них сильнее чем нам хотелось бы. Честно говоря, в основном мы закрывали на это глаза из‑за нескончаемого потока других уязвимостей, которые позволяли нападающим достигать своих целей. Однако в мире, где уязвимостей, которые можно эксплуатировать, становится все меньше и меньше, неразумно думать, что нападающие не начнут использовать атаки на цепочку распространения все чаще. И мы еще к этому не готовы.
Решение будет неизбежно включать в себя уменьшение площади атаки. Это потребует осознанное сокращение количества кода, работающего в удаленно доступных процессах или на высоких уровнях привилегий, таких как root, а также ускоренного внедрения песочниц. Ранее мы рассматривали применение песочниц только в контексте работы с частями кода, обрабатывающими ненадежные данные — например, парсеры изображений, декодеры видео, движки JavaScript и так далее. В мире, где ненадежным является сам код, а не данные, цель должна заключаться в том, чтобы переориентироваться на проектирование систем, где весь код ограничен минимальными привилегиями и имеются технические средства, обеспечивающие это.
К счастью, есть некоторые подвижки в этом направлении, по крайней мере для Linux. В Ubuntu 24.04 больше нельзя найти liblzma в адресном пространстве OpenSSH, в Android почти каждый процесс ограничен сочетанием SELinux и seccomp‑bpf, а в последних ядрах Linux теперь поддерживается многообещающая технология под названием landlock, которая позволит даже непривилегированным приложениям работать в песочнице. Написание песочницы landlock для «make», которая предотвратит атаку 2002 года, занимает около 250 строк кода.
Благодаря бэкдору в xz‑utils мы узнали, что существует большая готовность инвестировать время, деньги и другие ресурсы в атаки на цепочки распространения. Теперь это ощущается иначе — ставки значительно выросли. Нам предстоит много работы, и нам, возможно, придется внести радикальные изменения в то, как мы думаем о проектировании операционных систем и разработке приложений.
Хорошая новость в том, что появляется все больше заинтересованных тем, чтобы посоревноваться с энтузиазмом атакующих на стороне защиты от атак на цепочки распространения. Это может показаться незначительным, но интерес и энтузиазм — отличный старт, и это уже больше чем то, что у нас было 20 лет назад.
Sleuthhound
Все это интересно и поучительно. Но неужели никто не допускает мысли, что реальные бэкдоры, маскируемые под баги, делают сами разработчики? Именно специально по чьей то указке. Звучит странно, но допустив намерено ряд мелких ошибок в коде это может привести к багу открывающему заднюю дверь. Это довольно сложно в реализации, но реально и найти такое, а тем более доказать что цепочка ошибок привела к багу, очень проблематично.
randomsimplenumber
Примера не хватает
Доказать как раз реально. git bisect. Если баг локализован, найти кто это сделал значительно проще чем сделать.
KivApple
Ещё надо умысел доказать. Потому что баги добавляющие уязвимости находят регулярно. Вопрос тут как отличить ошибку от умысла.