Claude нашёл в OpenSSH около 4 500 строк, открытых до входа

В исследовании Anthropic от 21 октября Claude ищет код, до которого атакующий дотягивается без всякой нужды, и предлагает спрятать его за проверку. В 25 опенсорс-проектах общим объёмом больше пяти миллионов строк нашлось 493 таких места, а исправление в OpenSSH растянулось на три релиза.
Автор текста Крис Рольф объясняет, почему Anthropic вообще пошла этим путём. Поиск и починка отдельных уязвимостей плохо масштабируются: закрытая даже критическая дыра ничего не говорит о тех, что остались. Если же сузить круг кода, до которого можно добраться, неизвестные уязвимости никуда не денутся, но до них станет труднее дотянуться. Их серьёзность падает сразу у всех, включая те, которые, возможно, уже эксплуатируют. По словам Рольфа, защита в итоге становится лучше «без необходимости когда-либо находить или исправлять отдельную уязвимость».
Зачем прятать код
У охоты на отдельные баги есть и узкое место в людях. В посте о запуске OSS Scanner Anthropic рассказывала, что за полгода её модели нашли в важнейших проектах больше 29 000 кандидатов в уязвимости, а вручную разобрать и отсортировать удалось примерно 6 000.
Метод опирается на простое наблюдение. Софт со временем обрастает слоями абстракций, зависимостями и функциями и начинает вести себя не так, как задумывали авторы. Атакующие изучают именно фактическое поведение кода, а не замысел. Когда в коде миллионы строк и он постоянно меняется, лишняя открытость какой-нибудь функции легко проходит незамеченной.
Лечится это переносом кода за подходящий барьер. Варианты Anthropic перечисляет такие: из кода, работающего до аутентификации, в код после неё; из сценария без участия жертвы (0-click) в сценарий, где нужен хотя бы один клик; из включённого по умолчанию в явно включаемое; из первого сообщения протокола глубже в машину состояний сессии. Часть кода действительно должна быть доступна на ранних этапах, но далеко не весь.
Три приёма и 17 000 опций
Из множества способов сузить поверхность атаки Anthropic взяла три:
- настройки по умолчанию: код, доступный в конфигурации «из коробки», хотя ни одна функция по умолчанию им не пользуется;
- взаимодействие настроек: пары опций, каждая из которых по отдельности выглядит разумно, а вместе они молча отключают защиту или оставляют поведение функции неопределённым при живом коде;
- ранняя достижимость: сложный и чувствительный к безопасности код, который выполняется до аутентификации, без действий жертвы или до смены состояния протокола.
Среди языков проверенных проектов C, C++, Java, PHP и Python. Claude составил реестр из более чем 17 000 конфигурационных опций, из них 3 842 относились к настройке защитного механизма или функции, важной для безопасности.
Проекты разделили на три группы. Публичные (10 штук) обслуживают любого, кто до них достучится, или разбирают данные от неизвестных сторон, как DNS-резолвер, разбирающий ответы вышестоящих серверов. Закрытые (11) рассчитаны на аутентифицированных пользователей: запросы принимаются от кого угодно, но до входа никакая функциональность не должна работать. Частные (4) работают в собственной среде оператора, и слой аутентификации для них опционален. От публичного проекта ожидаешь, что заметная часть кода доступна по умолчанию. От закрытого ждёшь обратного.
Где закрытое оказалось открытым
Во всех одиннадцати закрытых проектах нашёлся код, доступный не по замыслу, хотя ни в одном он не составлял заметной доли от общего объёма. В конфигурации по умолчанию Claude насчитал там 93 лишних участка, открытых до аутентификации, ещё 37 мест, где код выполнялся или что-то записывалось в состояние до входа, и 61 сочетание настроек, которое молча ослабляло заданную администратором проверку до аутентификации. Сами по себе эти места не давали немедленной эксплуатации, оговаривается Anthropic, но поверхность атаки из-за них куда шире необходимой.
Самыми интересными во всех трёх группах в Anthropic называют находки про сочетания настроек. Claude нашёл 162 важных для безопасности комбинации, которые программы принимали без ошибки и предупреждения и поведение которых нигде не описано. В 94 случаях комбинация молча выключала защиту. Остальные 68 оказались внутренними несостыковками тех же механизмов: слушающий порт или путь входа оставался доступен, хотя по конфигурации он выключен; из двух конфликтующих настроек побеждала та, что стоит в файле позже; включённая администратором защита ничего не делала, а её код оставался достижимым. Часть таких сочетаний нестандартна, но развернуть проект именно так администратору ничто не мешает.
Один шаблон Claude нашёл независимо в четырёх не связанных между собой проектах. Администратор пишет правило доступа для удалённых клиентов через имя хоста или шаблон с подстановочным знаком вместо IP-адреса. При подключении сервер сравнивает правило с именем хоста клиента, но узнаёт это имя только при включённых обратных DNS-запросах, а в большинстве проектов они выключены. Тогда у сервера есть лишь IP-адрес, и правило сравнивается с ним как с обычным текстом. Шаблон имени хоста с IP-адресом не совпадёт никогда, запрещающее правило не срабатывает, и список запретов пропускает всех. Часть проектов в документации упоминает, что правила с именами хостов зависят от DNS-запросов. Что запрещающий список в таком виде открывается настежь, не пишет ни один.
В другом проекте администратор мог потребовать, чтобы каждый клиент подтверждал личность сертификатом. Вторая опция должна была лишь отложить эту проверку до момента, когда она понадобится, а на деле отключала её совсем. Сервер, настроенный пускать только доверенных клиентов, принимал соединение от кого угодно, и большой объём кода обработки запросов, который должен был стоять за проверкой сертификата, открывался неаутентифицированным клиентам. Программа принимала обе опции вместе без предупреждения, документация о снятой проверке молчала, и эта пара уживалась в коде целых 21 год.
Третий пример касается проекта, где аутентификация по умолчанию выключена и её должен включить администратор. Опция, требующая клиентских TLS-сертификатов, работала на большинстве сетевых эндпоинтов, но тихо игнорировалась на нескольких, которые загружали настройки TLS через путь с другим пространством имён. Клиент без сертификата проходил TLS-рукопожатие и открывал сессию, а в логах об этом ничего не появлялось. Полная форма имени настройки работает везде, а короткая, которой пользуется большинство примеров, на этих эндпоинтах отбрасывается.
Навык в три прохода
Все три приёма Anthropic собрала в один навык для Claude и работает над тем, чтобы встроить его в OSS-Scanner. Сам OSS Scanner бесплатно сканирует подключённые опенсорс-проекты, а его отчёты целиком пишут модели, без проверки людьми. Чтобы подключиться, проект добавляет в репозиторий сканера конфигурацию, Dockerfile для сборки и, по желанию, файл threat_model.md, где владельцы описывают, чего они хотят добиться в плане безопасности.
Навык проходит по кодовой базе трижды, каждый раз с пустым контекстным окном и коротким резюме предыдущего прохода. Первый проход ищет код, доступный в конфигурации по умолчанию, но не нужный ни одной задуманной функции. Второй смотрит на код, который при любой конфигурации выполняется до жёстких барьеров вроде аутентификации или до входа в машину состояний протокола. Третий ищет сочетания настроек, которые молча выключают защиту или ослабляют её. На каждом проходе Claude составляет реестр точек входа в код и подтверждает каждую находку динамической трассировкой программы.
Для находок первого прохода Claude сам проектирует и реализует барьер, а потом проверяет, что поведение по умолчанию не изменилось. Для этого он гоняет собственный набор тестов проекта и регрессионный набор по принципу «чёрного ящика» на исходной и изменённой сборках, и результаты должны совпасть. Барьер, который изменил бы поведение в нестандартной конфигурации, откладывается до решения человека. Для двух других проходов навык предлагает правки: переставить проверку конфигурации, добавить защиту, которая соблюдает порядок состояний, или отвергать опасное сочетание ещё при загрузке конфига. Даже без этого навыка общая методика, по мнению Anthropic, скорее всего, сработает. Компания упоминает и следующий шаг: Claude умеет сравнивать журналы работы с конфигурацией и отключать неиспользуемые парсеры, устаревшие протоколы и дашборды.
OpenSSH и ML-DSA
По доле от общего объёма кода сильнее всего поверхность атаки удалось сократить в OpenSSH, и в Anthropic этого сами не ожидали. Claude проследил пути входных данных демона sshd в релизе 10.4 и нашёл около 4 500 строк нового экспериментального кода для ML-DSA-44, постквантового алгоритма подписи. До этого кода в конфигурации по умолчанию мог добраться клиент, не прошедший аутентификацию. ML-DSA по умолчанию не включён, но код оставался достижимым, даже когда администратор явно исключал алгоритм. Демон разбирал ключ любого типа, присланного клиентом, для сертификатов ещё и проверял вложенную подпись удостоверяющего центра, и только потом смотрел, разрешён ли такой тип ключа. Эти 4 500 строк составляют около 16% собственного кода OpenSSH, который в стандартном sshd работает до аутентификации.
«Нет никаких веских причин, чтобы этот сложный код без защиты памяти был достижим, когда конфигурация его не включила», говорится в исследовании. Разработчикам OpenSSH отправили отчёт вместе с патчами, и в 10.5 проверку перенесли до разбора.
Но в новой проверке Claude нашёл две бреши. Первая: проверка смотрела на название алгоритма, которое объявлял клиент, а парсер выбирался по строке типа внутри самого ключа. Клиент мог объявить ssh-ed25519, пройти проверку и всё равно прислать ключ ML-DSA, который демон разберёт.
Вторая брешь была в сертификатах. Типы ключей с сертификатами включены по умолчанию, и, получив сертификат от атакующего, sshd десериализовал вложенный открытый ключ удостоверяющего центра и проводил полную проверку подписи для любого поддерживаемого алгоритма, ещё не заглянув в конфигурацию. Путь подписи пользовательского ключа был закрыт списком ключей, которым разрешено подключаться, а путь подписи центра нет. В итоге любой клиент, завершивший обмен ключами, мог дотянуться до каждого верификатора подписей в бинарнике.
Anthropic собрала proof of concept и прошла с мейнтейнерами несколько итераций исправления. Проверки переехали внутрь парсера: закодированный тип ключа и алгоритм подписи центра в сертификате сверяются с разрешёнными списками до соответствующей десериализации или проверки подписи. Сертификаты, подписанные разрешённым алгоритмом, по-прежнему разбираются и проверяются, просто проверка идёт раньше. Исправление убрало примерно пятую часть кода OpenSSH, до которой раньше дотягивался неаутентифицированный клиент в стандартной сборке, почти целиком это новый код ML-DSA. Теперь он недостижим, даже если клиент врёт о типе ключа или прячет ключ центра ML-DSA внутри в остальном допустимого сертификата. Изменения вошли в OpenSSH 10.6.
«Если лишняя достижимость выживает там, она может выжить где угодно», пишет Anthropic, напоминая, что OpenSSH входит в число самых тщательно проверяемых кодовых баз в мире.
Дальше
Авторежим Claude обходит настройку «Всегда спрашивать»
Claude в авторежиме прочитал почту через коннектор Fastmail, хотя все его действия стояли на «Всегда спрашивать». Anthropic на жалобу ответила, что так и задумано, и автор удалил коннектор. Вы бы оставили почту подключённой к Claude или отключили бы коннектор?
Читайте также
- OSS Scanner отправил мейнтейнерам 77 критических находок
- Anthropic шлёт опенсорсу находки моделей без ручной проверки
- Claude нашёл в сидах кривых NIST обычные метки времени
- Anthropic запустила модель на 15 дешёвых ТВ-приставках
- Claude Haiku 4.5 оставил полиции выдуманную наводку
- Anthropic спрятала рассуждения Claude от дистилляторов
Комментарии
Пока никто не написал. Будьте первым.
Присоединяйтесь к разговору
Войдите, чтобы оставить комментарий. Он появится после модерации.

