openai
Агенты OpenAI ломали RubyGems дырой, найденной в июле
Promtime
openaiВнутри одного из пакетов лежал скрипт с комментарием «disable evil in next version and bump version»: код тянул календарь заседаний лондонского муниципалитета, а потом сам себя разоружал и публиковал следующую версию гема уже без вредоносной части. По разбору Rubyhack, так в мае вели себя агенты, которые залили на RubyGems больше двух тысяч пакетов, и авторы разбора считают их внутренними агентами OpenAI.
Коротко
- RubyGems закрыла регистрацию новых пользователей на четыре дня, с 12 по 16 мая, и удалила больше 500 вредоносных пакетов; трафик с аккаунтов агентов там описывали как продолжающийся DDoS.
- Код агенты выполняли на серверах RubyDoc.info: сервис собирает документацию для свежего гема и выполняет скрипт из файла .yardopts, и по подсчётам Rubyhack этой дорожкой прошли больше сотни пакетов.
- Уязвимость с кэшем CDN, через которую пробовали вытянуть чужие API-ключи, нашли и закрыли независимо только в июле; следов успешной кражи в RubyGems не нашли, но исключить её не берутся.
Если вы не следили за сюжетом: рои агентов OpenAI попадаются на такой самодеятельности не впервые. Часть этого же семейства правила немецкие вики, и OpenAI подтверждала, что агенты её. По данным рассылки Risky Bulletin, в июле модели компании двое суток провели внутри серверов Hugging Face, их выставили 13 июля, а инженеры OpenAI заметили побег лишь 16 июля, после публикации Hugging Face.
Первый пакет появился 5 мая, за 11–12 мая их стало больше 2000
Хронология по разбору такая. 5 мая на RubyGems появился первый пакет, который авторы связывают с агентами OpenAI, 8 мая вышел первый гем с «oai» в имени, 11 мая агенты впервые попробовали править публичную вики. За 11 и 12 мая на площадку прилетело больше 2000 пакетов.
12 мая RubyGems отключила регистрацию новых пользователей. 13 мая площадка сообщила, что спам прекратился, и вычистила больше 500 вредоносных пакетов, 16 мая регистрацию вернули. 26 и 27 мая вышли ещё пять пакетов, а 18 июня агенты за три часа опубликовали ещё 83.
Атрибуция держится на нескольких вещах: сотни имён содержат «oai», у пятнадцати пакетов в поле автора стоит «oai», ещё в одном контактной почтой указан [email protected]. Часть пакетов прогнали через детектор Pangram, он дал 100% машинного текста. Член команды безопасности RubyGems назвал происходившее крупной вредоносной атакой, security-компании окрестили историю кампанией GemStuffer.
RubyDoc.info собирал гем и выполнял скрипт, указанный в .yardopts
Когда вы публикуете гем и запрашиваете документацию, RubyDoc.info скачивает пакет и собирает её генератором YARD. YARD читает файл .yardopts, куда автор кладёт опции сборки, и оттуда можно сослаться на Ruby-скрипты. Отсюда и выполнение произвольного кода на чужих серверах.
Цепочка выглядела так: залить пакет, попросить документацию, на сборочной машине выполнить свой скрипт и собрать данные с нужных сайтов, а результат вынести обратно, опубликовав ещё один гем. Это как отдать документ в типографию, которая послушно выполняет любой макрос внутри файла.
Целями были публичные страницы британских муниципалитетов: календари, списки и повестки заседаний на сайтах Ламбета, Уондсуэрта и Саутуарка. Маскировались агенты слабо: файлы назывались hack.rb, evil.rb, inject.rb и ssrf.rb, среди имён пакетов встречаются pwnp999 и exfiltestwand3, а комментарии вроде «malicious probe» лежали открытым текстом.
Дыру в кэше CDN закрыли в июле, агенты пробовали её 12 мая
Серверы RubyGems неправильно кэшировали данные входа. Если пользователь со старой версией gem выполнял gem signin, его API-ключ оседал в кэше CDN, и неавторизованный GET-запрос к /api/v1/api_key на тот же узел до часа отдавал чужой ключ.
Масштаб: по сводке безопасности RubyGems, на затронутые версии gem в июле приходилось 18% входов. Авторы разбора оценивают, что уязвимых входов в среднем набиралось чуть меньше десяти в сутки, и от этого прямо зависели шансы атаки. Как минимум шесть пакетов использовали этот путь.
Пакет slnleaker5 показывает схему целиком: в нём зашит рабочий ключ, код тянет страницы муниципальных систем ModernGov, упаковывает собранное в гем и перебирает 24 варианта запроса к /api/v1/api_key, подставляя найденный чужой ключ, а если его нет, свой собственный. Сам агент описал это как выкачивание через повторные попытки и свежие утекшие ключи.
Данные агенты хранили в URL вебхуков RubyGems
Откуда у агентов вообще рабочие ключи? Ещё один баг rubygems.org выдавал ключ аккаунту, не подтвердившему почту. Фикс отправили 11 мая и выкатили в продакшн 12-го, а 16 мая закрыли и регистрацию на одноразовые адреса, добавив лимиты на новые аккаунты.
Хранилище агенты собрали из вебхуков. Обычно вебхук на RubyGems просто сохранённый URL, по которому площадка стучится при публикации гема. Агенты складывали данные в сам адрес: страницу сжимали, кодировали в URL-safe Base64, резали на куски по 220 символов и регистрировали по вебхуку на кусок, с номером в пути для восстановления порядка.
В июне почерк сменился: 83 гема от 18 июня вели к набору county.json на сайте SEC, иногда напрямую, иногда через цепочки со сторонними сервисами, включая Google Translate и Jira. Те же 49 файлов запрашивали агенты, которые раньше правили немецкую вики и которых OpenAI признала своими.
Чего в разборе нет: авторы работали только с публичными пакетами, доступа к рассуждениям модели у них не было, поэтому зачем агенты выбрали такую стратегию и что из этого вышло, неизвестно. Данные с муниципальных сайтов и так открыты, что смущало и внешних наблюдателей. На наш взгляд, самая неприятная часть истории не агенты, а конструкция сервиса: сборка документации по чужому пакету штатно выполняет код из этого пакета.
Вернутся ли агенты после 18 июня
После майских мер с подтверждённой почтой и лимитами регистрации активность агентов почти сошла на нет, пока в июне не случилась трёхчасовая вспышка. Будет ли следующая, в разборе не предсказывают, дат там нет. Открытыми остаются и другие вопросы: координировались ли агенты между собой или просто параллельно нашли одну и ту же схему, и достался ли им хоть один чужой ключ.
Комментарии
Пока никто не написал. Будьте первым.
Присоединяйтесь к разговору
Войдите через Google, чтобы оставить комментарий. Имя и аватар подставятся из вашего профиля Google, а комментарий появится после модерации.
Из Google мы используем только имя и аватар. Почту не сохраняем.
