Некоторое время назад я строил оркестратор своей домашней лаборатории. LLM-агент должен был облететь серверы, собрать метаданные и зафиксировать топологию сети в документации проекта. Разведочную, в общем-то, канцелярскую задачу. В рамках неё я попросил агента описать способы администрирования домашнего роутера и даже «помог» ему, сообщив, по каким портам к нему теоретически можно обратиться.
Наутро у меня на руках оказались подтверждённая критическая уязвимость прошивки, полный административный доступ к роутеру, полученный без единого пароля, черновик отчёта вендору и поданная в MITRE заявка на регистрацию CVE. Из этих четырёх пунктов явно просил я только первый. Остальное агент сделал сам, и сделал корректно. Ни одного изменения конфигурации, координированное раскрытие, классификация CWE и CVSS по методике.
Это история о том, что произошло в ту ночь, что именно он нашёл (класс уязвимости классический и неприятный), как агент провёл меня через процесс регистрации CVE частным исследователем, и почему часть технических деталей я пока намеренно опускаю.
Домашняя лаборатория с агентами внутри
Небольшая вводная, чтобы дальнейшее не выглядело магией.
По образованию я специалист по информационной безопасности, сейчас работаю LLMOps-инженером. Эксплуатирую LLM-платформу в банковском on-prem контуре, вывожу модели, строю агентные сценарии поверх MCP. В свободное время у меня домашняя лаборатория. Физический сервер с Proxmox VE, на нём виртуальные машины и контейнеры под pet-проекты (игровой сервер, мониторинг, личный сайт, локальные LLM). Над всем этим я постепенно строю проект-оркестратор. Рабочая машина под Windows, VS Code с Kilo Code, собственный MCP-сервер для SSH-доступа к гостям гипервизора, SSH-туннели, единый LLM cost-proxy.
Важная деталь этой конструкции - режим разрешений, который я задал агентам с первого дня.
read-only операции (статусы, логи, просмотр конфигов) выполняются свободно;
всё, что может изменить состояние системы (пакеты, сервисы, файлы, сеть, git-мутации), идёт только после моего явного подтверждения;
секреты не выводятся в чат, а поверхность безопасности после сетевых изменений попадает под обязательный регресс-контроль.
Это важно для истории, ведь агент действовал внутри этих рамок, и вся «хакерская» часть уместилась в read-only контур, то есть в одну HTTP-разведку без единой попытки записи. Единственное исключение я опишу ниже отдельно.
Постановка задачи
Задача, как я её сформулировал глубоко за полночь, звучала так.
Создай каталог роутера в проекте и опиши способы подключения к нему для администрирования из LAN/WAN. Роутер на 192.168.1.1. Вот опции удалённого доступа, как я их помню из панели. HTTP-управление включено (нестандартный порт, заявленный в панели), SSH включён на порту 22, TR-069 и PING выключены, со стороны WAN выключено всё. Проверь подключение и доступный функционал.
Ожидание у меня было простое. Агент прозвонит порты, сверит мои «показания» с фактом и напишет мета-файл. Смертельный номер прятался в конце последней фразы, в этих самых словах «проверь доступный функционал».
Что сделал агент - от прозвона портов до анализа фронтенда
Дальше я пересказываю лог сессии. Подчеркну, промежуточных промптов от меня не было. Это один непрерывный заход агента, разбитый на шаги его же собственным планом.
Шаг 1. Факт против документации. Заявленный панелью порт HTTP-управления оказался закрыт, при этом сам веб-интерфейс был жив. Панель фактически висела на 80/443, веб-сервер определился как древний Boa образца середины 2000-х, страница логина оказалась SPA на jQuery. Отсюда первый урок. Даже собственные заметки о собственной сети стоят проверки фактом, особенно когда пункты панели роутера интерпретируются не так, как написано. Тот самый флаг порта HTTP-управления относился к WAN-стороне, а не к LAN-панели.
Шаг 2. SSH. Порт открыт, но стек настолько legacy, что современный OpenSSH-клиент по умолчанию не договаривается об алгоритмах. KEX первого поколения, rsa-хосткей, CBC-шифры, hmac-sha1. Агент составил рабочий набор флагов для подключения с legacy-криптой, задокументировал его в мета-файле как «рецепт» и пошёл дальше. Входить он не стал, ведь кредов у него не было. Пока не было.
Шаг 3. Рекогносцировка SPA. Вместо тыкания в интерфейс агент просто вытащил JavaScript-бандлы панели и прочитал их. В коде обёртки API нашлись все реальные эндпоинты веб-сервера - логин, чтение конфигурации и запись конфигурации, классическая пара CGI-хендлеров.
Здесь и случилось то, ради чего пишется эта статья. Агент сделал самое простое, что можно сделать с найденным read-эндпоинтом. Он выполнил curl без каких-либо кредов.
Находка - полный дамп конфигурации без аутентификации
Эндпоинт чтения конфигурации ответил 200 OK и отдал весь конфиг роутера целиком, примерно 37 КБ псевдо-JSON. Внутри лежало много интересного.
Пароль административной панели в base64, то есть фактически в открытом виде. Base64 - это транспортная кодировка, а не шифрование.
WPA2-ключи всех настроенных SSID, тоже base64.
Учётные данные сервисных механизмов удалённого управления.
Сессионные и CSRF-токены самого веб-интерфейса.
Полная сетевая конфигурация - WAN-адрес, пробросы портов, DHCP-резервы, списки подключённых клиентов.
Любое устройство в LAN, будь то заражённый ноутбук, скомпрометированная умная лампочка или гость в гостевой сети, одним GET-запросом получает ключи от всего. Воспроизведение буквально в одну строку.
curl "http://<router>/cgi-bin/<read-endpoint>" # → 200 OK, ~37 KB конфигурации, включая "password":"<base64>"
Пути намеренно обезличены, причину объясняю в разделе «Почему я пока не всё рассказываю».
Контрольная точка - асимметрия чтения и записи
Самое интересное в находке - асимметрия. Агент тут же проверил парный write-эндпоинт, и запись конфигурации без валидной сессии корректно отвергалась кодом ошибки. Токенный механизм авторизации в прошивке существует и работает, но из-под него исключён путь чтения.
Это важная форензическая деталь, ведь такая асимметрия почти исключает «задуманный функционал». Перед нами не бэкдор, а ошибка проектирования. Кто-то вынес read-хендлер за auth-gate, вероятно ради того, чтобы страница логина могла без сессии подтягивать базовые данные типа модели и версии, и не ограничил список полей. Дамп уехал целиком, со всеми секретами.
Логин-формула панели тоже добавила красок. Авторизация устроена как POST с паролем в base64, а в ответ выдаётся cookie на 15 минут. Схема «пароль в base64» согласуется с общей культурой кода и объясняет, почему пароль лежит в дампе именно так.
Момент, который я бы назвал взломом
Агент взял base64-значение пароля из дампа, декодировал его и выполнил реальный логин в панель. POST на логин-эндпоинт вернул успех и сессионную cookie. То есть из «давай опишем способы подключения» получился полный административный доступ к устройству, добытый без брутфорса, без эксплойта и без единого ограничивающего фактора, одним лишь чтением того, что устройство и так раздаёт всей LAN.
Это оказался единственный «изменяющий» вызов за всю ночь (сам факт создания сессии), и дальше агент ничего не менял. Ни записи через write-эндпоинт, ни правок настроек. Дамп использовался строго как доказательство, а сессия была благопристойно заброшена.
Калибровка - насколько это плохо
Дальше агент по моей просьбе провёл формальный разбор, и здесь он оказался неожиданно силён как аналитик.
Периметр. Уязвим ли роутер снаружи? Внешний скан WAN-адреса с нескольких независимых узлов (check-host и аналоги) показал, что все порты управления (SSH, HTTP(S), remote-management, TR-069) из интернета закрыты, а WAN-управление выключено. Позитивный контроль на заведомо открытом пробросе отработал, то есть метод доказуемо видит открытые порты, и закрытие админских - факт, а не артефакт сканера. Итог простой - уязвимость строго LAN-сторонняя. Это смягчает ситуацию, но в домохозяйстве с IoT-зоопарком и гостевой сетью смягчает слабо. LAN для многих устройств общая, а поводов для компрометации одного из них масса.
Закрыть настройками? Агент прошёлся по модульной структуре панели. Management ACL (trusted IP для админки) в прошивке нет, возможности отключить или перевесить LAN-вебсервис тоже нет, а веб-сервер неделегируемо слушает 80/443 на всех локальных интерфейсах. Фикс возможен только прошивкой от вендора.
Компенсирующие меры на случай, если фикса ещё долго не будет. Самое практичное для любого владельца SOHO-роутера.
Любой секрет, хранимый на роутере, считать известным всей локальной сети и минимизировать, что там вообще лежит.
Пароль админки держать уникальным и нигде не переиспользованным, чтобы утечка не собиралась в цепочку.
Ненадёжные и IoT-устройства селить в гостевом SSID с изоляцией клиентов.
WAN-управление держать выключенным всегда.
После каждого обновления прошивки делать регресс-чек эндпоинта без cookie.
Существующие CVE. Прогон по базам (CIRCL vulnerability-lookup и родственным) по вендору и веб-бэкенду дал ноль публичных записей. На близкую тему у вендора в архивах нашлись старые истории по другим линейкам устройств, но по этой модели и этому бэкенду чисто. Значит, находка имеет смысл для регистрации. Отдельная деталь - в JS-бандлах виден тот же бэкенд как минимум ещё для одной модели вендора, так что скоп, вероятно, шире одного устройства. Это зафиксировано в заявке для проверки вендором.
Классификация. Основной CWE - CWE-306 Missing Authentication for Critical Function, вторичные - CWE-522 (недостаточно защищённые креды) и CWE-359 (раскрытие приватных данных неавторизованному актору). CVSS 3.1 составил 8.8 High по вектору CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H. Логика такая. Прямой импакт - конфиденциальность (C:H), но дамп содержит действующие учётные данные, и это превращает чтение в цепочку полного захвата управления устройством с подменой DNS, пробросов и прошивки, отсюда I:H и A:H. Консервативная оценка «только прямое раскрытие» даёт 6.5 Medium, но в заявку пошёл 8.8 с явным обоснованием предположения о цепочке.
Мёртвая инфраструктура вендора
Прежде чем оформлять находку, положено удостовериться, что не вышло обновление прошивки с фиксом. Тут выяснилось второе обстоятельство, уже не уязвимость, а эксплуатационный конфуз. Нативная онлайн-проверка обновлений из самой прошивки возвращает ошибку таймаута, сайт вендора из моего региона недоступен, домен, на который часто ссылаются для загрузок, оказался облачным порталом без раздела загрузок, а поддомены обновлений не резолвятся вообще. Получить или подтвердить наличие новой прошивки невозможно ни одним каналом. Этот факт тоже вошёл в репорт вендору отдельным приложением с просьбой указать актуальный канал дистрибуции фиксов для региона.
От находки к CVE - как это делается на практике
Теперь самое полезное для тех, кто никогда не регистрировал CVE как частное лицо. Ниже порядок действий, реальный, из моей ночи.
1. Уведомление вендора. Сначала coordinated disclosure, то есть письмо на security-канал вендора с полным описанием, воспроизведением, импактом и предложенным фиксом. Агент подготовил двуязычный черновик (EN для штаб-квартиры вендора, RU на случай региональной поддержки) с корректной структурой отчёта, включая summary, affected component, impact, reproduction, expected behavior, suggested fix и приложение про недоступные каналы обновления. Отправлял письмо я сам со своей почты, потому что аккаунты, отправки и финальные кнопки в этом процессе намеренно оставлены человеку. С этого письма стартует стандартное 90-дневное окно координации. Вендору даётся время на фикс, публичность наступает после.
2. Запрос CVE ID в MITRE CNA-LR. Для вендоров, не являющихся CNA, запрос идёт через CNA of Last Resort.
Агент заранее распотрошил сам портал, включая исходники Vulnogram, и выяснил всё, что обычно узнаётся методом тыка. Какие поля обязательны, что class-level CWE отсутствуют в автодополнении и вводятся текстом, что defaultStatus для непроверенных версий надо переключать с unaffected на unknown, что вендоры со своими CNA в этой форме блокируются. Итоговый пакет, карточку со значениями всех полей, я просто перенёс в форму и нажал сабмит. От получения находки до трек-номера заявки прошло около трёх часов.
3. Параллельная запись в VulDB. Это независимая база уязвимостей и тоже CNA.
4. Финал после назначения CVE ID и истечения окна. Gist переводится в public, публикуется полный advisory (с PoC, где секреты затёрты), при желании делается сабмит в Exploit-DB, а опционально - регистрация в БДУ ФСТЭК для RU-учёта.
Почему я пока не всё рассказываю
Эта статья написана в период эмбарго. Окно координации с вендором открыто, CVE ID в ревью, advisory лежит в секретном gist. Поэтому здесь нет названия вендора и модели, точных путей API, версии прошивки и воспроизводимого PoC. Это не политика «security through obscurity», а стандартный coordinated disclosure. Пока фикса нет и идентификатор не назначен, детали, позволяющие повторить атаку по конкретной линейке устройств, намеренно удерживаются. Всё, что можно было показать без привязки к вендору (класс уязвимости, механику, процесс регистрации), я показал. Полная техническая версия с моделью, эндпоинтами, PoC и advisory выйдет дополнением к этой же теме после раскрытия. Ну или напишу отдельный пост…
Что это говорит про агентов
Теперь обещанные выводы не про роутер, а про агента. Главных я вынес четыре.
Разведка ≤ интеллект. Никакой «агентной магии» не случилось. Он прочитал фронтенд и нашёл то, что находил бы любой исследователь руками, просто быстрее и без сна. Ценность агента - в скорости исчерпывающего перебора «скучных» гипотез. Все JS-файлы, все эндпоинты, все модули панели, все базы CVE, все каналы обновлений. Человек заложил бы на это выходные, а тут уложились в ночь.
Рамки разрешений работают. Единственная «вредная» операция за ночь - один POST-логин для подтверждения находки, классическая verification step в пентесте. Всё остальное - чтение. Я получил взломанный роутер с нулём изменённых состояний и полным аудит-трейлом.
Человека не отпускают только там, где он реально нужен. Аккаунты, отправки писем, финальные сабмиты, решение публиковать или нет - всё это осталось за мной. Всё ремесло же (формулировки, классификация CWE/CVSS, структура advisory, разбор чужих веб-форм) агент сделал сам и сделал по методике.
Домашняя сеть удобна как полигон. Агентам нужен контур, и домашняя лаборатория - идеальный контур, потому что там своё железо, своя сеть, легальные цели и мгновенный фидбэк. И результатом становится не хаотичный дамп «я пробил всё», а отредактированная заявка в CVE и чек-лист компенсирующих мер.
Практический итог
Если у вас дома SOHO-роутер с Wi-Fi и веб-панелью, сделайте вот это прямо сейчас, пока не дочитали страницу.
Выключите WAN-управление целиком.
Попробуйте тот самый read-запрос к панели из LAN без авторизации. Займёт минуту и скажет про ваш роутер больше, чем маркетинговая страница.
Задайте уникальный пароль админки, никакой переиспользуемой почты.
IoT и гостей отправьте в изолированный гостевой SSID.
И держите в голове один принцип. Мне очень нравится цитата из одного фильма: “Ни одна система не безопасна”. Спасибо за прочтение и хорошего дня!
dyadyaSerezha
Когда уже будем читать аналогичные статьи, начинающиеся так:
Я только дал задание агенту построить схему политического устройства Земли, а на утро обнаружил, что он взял власть в 20 ключевых странах, причём без нарушений их законодательств. Вот история о том, что произошло в эту ночь…
balamutang
Дык напишите, это ж такая же беллетристика, сгенеренная ии- как и статья выше