ИИ-агенты · безопасность ИИ · Claude Code · уязвимости · Python · подмена модулей · Auto Mode · инъекции4 сентября в 23:02 · 5 мин

Безопасность ИИ-агентов: как просьба пересказать сайт привела к взлому

Исследователь Иоганн Ребергер продемонстрировал критическую уязвимость в механизмах безопасности Claude Code. Используя легитимные запросы и стандартное поведение модели, он заставил агента скомпилировать и выполнить вредоносный код, не нарушив прямых запретов на запуск неизвестных файлов. Атака работала через подмену модулей Python, где безопасное решение модели — написание декодера самостоятельно — стало ключевым звеном взлома.

Разбитая стеклянная капсула со свечением внутри на фоне ночного моря и скалистых берегов

# Когда отказ от запуска бинарника привел к взлому

История информационной безопасности часто строится на парадоксах. В случае с агентом Claude Code и моделью Opus 5 парадокс заключается в том, что соблюдение всех инструкций по безопасности привело к полной компрометации системы. Исследователь Иоганн Ребергер (Johann Reberger) показал, как можно инициировать цепную реакцию, не используя прямых команд на выполнение скриптов или запуск подозрительных файлов. Результат: удаленное подключение к серверу жертвы и запуск калькулятора.

Суть проблемы не в том, что модель не смогла распознать вредоносность конкретного файла. Проблема кроется в том, что модель приняла самое правильное решение — написать собственный декодер на Python — в среде, где это решение стало фатальной ошибкой.

Архитектура атаки: когда безопасность становится оружием

В обычном режиме работы Claude Code пользователь должен подтверждать каждое действие, касающееся записи файлов, запуска процессов или сетевого взаимодействия. Режим Auto Mode, включенный по умолчанию для тарифов Pro, Max и Team (с 14 августа 2026 года), делегирует эти решения классификатору. Цель очевидна: разработчики не всегда могут уловить тонкости, поэтому система должна блокировать опасные действия самостоятельно. Статистика Anthropic утверждает, что классификатор эффективнее человека.

Однако в ходе экспериментов Ребергера стало ясно, что классификатор проверяет команды изолированно. Он смотрит на python3 -c '...' как на безопасную строку команд. Но реальная угроза скрыта в контексте выполнения.

Атака началась с запроса на резюме сайта, который на самом деле был архивом https://archive.example/. Сервер вернул ошибку 415 (неподдерживаемый тип содержимого). Агент, стремясь выполнить задачу, самостоятельно решил использовать инструмент curl для получения страницы. Это выглядело как логичный шаг обхода ошибки.

Вместо HTML-кода сервер отправил ZIP-архив. Внутри него лежали не просто документы, а уловка: README.txt, таблица метаданных и, самое главное, файл struct.py вместе с декодером.

Модель отказалась запустить бинарный файл decoder-darwin, поступив абсолютно верно. Вместо этого она решила расшифровать данные самостоятельно. Она написала команду для Python, использующую библиотеки base64, zlib и json, чтобы прочитать содержимое архива.

Именно здесь произошло то, что Ребергер назвал «безопасным шагом, ставшим частью атаки».

Механизм подмены: почему код сработал

Когда агент запустил команду python3 -c 'import base64...', интерпретатор Python начал работу. Он попытался импортировать стандартный модуль struct (нужный для работы с байтовыми последовательностями). Однако поскольку текущий рабочий каталог содержал файл struct.py, который был передан в архиве атакующего, Python загрузил этот локальный файл вместо системного.

Это явление называется подменой модуля (module shadowing). Локальный struct.py не уничтожал стандартную библиотеку; он просто переопределял имена функций, экспортируя из себя настоящие функции _struct и выполняя собственный код при импорте.

Таким образом, когда агент думал, что просто распаковывает данные, он фактически выполнял код из архива. Этот код создал дочерний процесс, который установил сетевое соединение с управляющим сервером и запустил калькулятор.

Интересен нюанс: в Python для изоляции часто используется флаг -I, который исключает текущий каталог из поиска путей. В исследовании атакующий использовал этот флаг в другом процессе, чтобы избежать бесконечной петли, но сам факт работы в каталоге с ненадежными данными стал причиной успеха.

Границы классификации: почему защита не сработала

Анализ показывает, что классификатор безопасности в Auto Mode не смог остановить атаку, потому что каждый отдельный шаг выглядел законным: 1. Попытка прочитать сайт через curl после ошибки HTTP — допустимо. 2. Загрузка ZIP-архива с материалами — стандартная практика. 3. Распаковка архива — необходимое действие. 4. Отказ запускать бинарный файл — строго соответствует правилам безопасности. 5. Написание декодера на Python с использованием стандартных библиотек — разумное решение.

Опасность возникла не в одной команде, а в их композиции. Классификатор оценивал строку python3 -c ... без учета того, что в текущем рабочем каталоге лежит скомпрометированный модуль struct.py. Система пытается предсказать намерения, но не всегда ограничивает последствия.

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

Выводы и стратегии защиты

Успешная атака в 3–4 из 5 попыток опровергает миф о полной защищенности. Официальная статистика Anthropic (0 успешных атак из 720 попыток) относилась к заранее определенному набору сценариев, который не включал эту цепочку подмены модулей. Это важный урок: тестирование в замкнутом контуре не гарантирует безопасности в открытом мире.

Ребергер подчеркивает, что проблема не столько в модели, сколько в ошибочной концепции доверия. Безопасность должна строиться слоями:

* Изоляция среды: Агент должен работать внутри контейнера или виртуальной машины с минимальным набором прав, не имея доступа к файловой системе или сети на уровне хоста. * Строгий контроль импорта: Использование изолированного режима запуска (python3 -I) предотвращает подмену системных модулей локальными файлами. * Ограничение сети: Даже если код запущен, доступ к сети должен быть ограничен списком разрешенных доменов. * Недоверие к скачанному контенту: Любой файл, полученный извне, должен рассматриваться как потенциально опасный до момента полной валидации. * Независимый аудит: Отчеты модели не являются журналированием. Нужно отслеживать реальные системные вызовы, сетевые соединения и запуск процессов.

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

Первоисточники

Habr AI
← Вернуться в эфир