
Python PoC и Docker-лаборатория для CVE-2026-61500: восстанавливает состояние PRNG Rejetto HFS V8 для подделки cookie административной сессии и достижения RCE через server_code.
CVE-2026-61500 — это уязвимость подделки сессии без аутентификации в Rejetto
HFS 3.0.0–3.2.0. HFS генерировал ключ подписи сессионных cookie Koa с помощью
JavaScript Math.random() и раскрывал выходные значения того же V8 PRNG в
неаутентифицированном рукопожатии входа SRP. Злоумышленник может восстановить
состояние PRNG, получить ключ подписи, подделать сессию администратора и
использовать документированную функцию конфигурации server_code для выполнения
серверного JavaScript.
Этот репозиторий содержит proof of concept на Python и одноразовое сравнение в Docker с использованием официальных образов HFS 3.2.0 и 3.2.1. Публичная сборка намеренно ограничена HTTP-целями на локальном интерфейсе loopback.
| Утверждение | Статус |
|---|---|
| Восстановление состояния V8 xorshift128+ из неаутентифицированных ответов входа | Подтверждено |
| Восстановление активного ключа подписи cookie HFS | Подтверждено |
| Подделка сессии, принимаемой как сессия администратора HFS | Подтверждено |
Выполнение безвредного маркера server_code в официальном HFS 3.2.0 | Подтверждено |
| Получение root reverse shell внутри изолированной сети Compose | Подтверждено |
| Остановка до подделки сессии в официальном HFS 3.2.1 | Подтверждено |
| Целевые атаки через интернет или закрепление | Не предоставлено и не заявлено |
loginSrp1 для известной
учётной записи admin. Каждый уязвимый ответ помещает числовой loggingIn.sid
и его подписанный сессионный cookie в заголовки Set-Cookie.randomId(30). PoC
учитывает округление кратчайшей строки V8 и проверяет кандидатов по
наблюдаемому HMAC hfs_http.sig, что также определяет смещение запуска.username: admin, затем вызовите
get_config, чтобы доказать, что подделанный cookie имеет доступ
администратора.set_config с небольшим модулем server_code. Полезная нагрузка по
умолчанию записывает безвредный маркер в /data; доступен только
для лаборатории Docker на loopback.Это цепочка HTTP типа «чёрный ящик»: PoC не читает файлы, память, переменные окружения или состояние процессов на цели. Знание исходного кода используется для моделирования уязвимого алгоритма.
59472e534bf7e056d708382d02935c2eaf956927.Исправление заменяет ключ подписи на 32 байта из Node.js randomBytes() и
заменяет раскрытый числовой идентификатор входа на randomUUID(). Явное указание
надёжного значения COOKIE_SIGN_KEYS снижает риск предсказания ключа подписи,
но обновление остаётся рекомендуемой мерой устранения.
rejetto/hfs:v3.2.0, дайджест
sha256:d6765e93b68de222583be7788afad699695fd08aa2f56377337f5139779e0746.rejetto/hfs:v3.2.1, дайджест
sha256:61db4da1f494df254aa7f48889c676b424b413e45b7b92cf4276f4b8e632aaec.python:3.13-alpine, дайджест
sha256:1a63a53928ce53d2b0baf08092a703f4840ac5dfbd61fd48802dbf48e08c801e.Оба сервиса HFS привязываются только к loopback хоста; обратный вызов не
публикует порт. Лаборатория создаёт синтетического администратора, поскольку
loginSrp1 должен вызываться для существующего имени пользователя; пароль не
известен и не используется эксплойтом.
Требования: Docker с Compose, Python 3.10 или новее и curl.
./verify.sh
Верификатор удаляет только lab/runtime/vulnerable и lab/runtime/fixed,
запускает оба образа, закреплённых по дайджесту, выполняет положительный и
отрицательный контроли и по умолчанию останавливает контейнеры. Используйте
KEEP_LAB=1 ./verify.sh, чтобы оставить лабораторию запущенной для проверки.
Если лаборатория сохранена, прямой вызов безвредного маркера выглядит так:
python3 cve-2026-61500-poc.py \
--target http://127.0.0.1:28182 \
--marker cve-2026-61500-rce-marker.txt
Чтобы продемонстрировать выполнение команды внутри принадлежащего вам лабораторного контейнера:
python3 cve-2026-61500-poc.py \
--target http://127.0.0.1:28182 \
--command 'id > /data/cve-command-output.txt'
Любое имя хоста, не являющееся loopback, HTTPS-цель или удалённый IP
отклоняются при проверке аргументов. Эксплойт изменяет HFS server_code;
используйте только одноразовую лабораторию или систему, на которую у вас есть
явное разрешение.
Записанная демонстрация идёт на шаг дальше: demo.sh запускает непубликуемый
сервис callback в сети Compose и использует --command для подключения
Bash reverse shell к нему. Обратный вызов отправляет только id, uname -a,
pwd и exit, записывает расшифровку в игнорируемый lab/runtime/ и
закрывается. Ни один порт обратного вызова не привязывается к хосту.
Реальный запуск 2026-09-26 восстановил одно состояние PRNG и его ключ подписи,
получил HTTP 200 для подделанного административного get_config, установил
полезную нагрузку с маркером и обнаружил CVE_2026_61500_RCE_CONFIRMED в
уязвимом контейнере. Отдельный контроль --command 'id > /data/cve-command-output.txt'
выдал uid=0(root) gid=0(root) groups=0(root) внутри этого официального
контейнера. Записанный reverse shell только в Docker независимо вернул ту же
root-идентичность и рабочий каталог /data. Против
3.2.1 первый ответ входа содержал непрозрачный UUID, и PoC завершился со
статусом 3 до попытки подделки сессии. См.
docs/example-output.txt и
docs/e2e-results.json.
26 сентября 2026 года были выполнены точные поиски по CVE и эксплойтам/PoC в SearchSploit (локальный индекс Exploit-DB), веб-результатах с индексацией GitHub, Packet Storm, Exploit-DB и общем вебе. На тот момент работающий публичный эксплойт не был обнаружен; результаты содержали только метаданные CVE/рекомендаций и страницы отслеживания эксплойтов. Это датированный результат, полученный по мере возможности, а не утверждение, что эксплойт не может существовать в другом месте или появиться позже.
<[email protected]>
(Twitter: @aramosf).Только для авторизованных исследований безопасности, защитной проверки и обучения. Вы несёте ответственность за получение разрешения и соблюдение применимого законодательства.
--command