Nuclei templates: пиши свои, перестань быть скриптокиддером
Хватит юзать чужие темплейты из репы как школьник с чужой домашкой — погнали учиться клепать свои. Держи мини-гайд в формате RedTeam-отчёта.
Почему скрипткидди не пишут темплейты
Community-темплейты из nuclei-templates — это база, но они детектят только то, что уже известно и запатчено. Ты сканишь чужой стек с кастомным API или самописной админкой — стандартные шаблоны молчат, а ты сидишь и думаешь, что цель «чистая». На самом деле ты просто не написал детект под конкретную аномалию. Свой темплейт — это твой личный 0day-радар: нашёл уязвимость руками через Burp — заверни в YAML и гоняй по всей подсети за секунды.
Точка входа: анатомия темплейта
Nuclei-темплейт — это YAML-файл с DSL-надстройкой поверх. Скелет всегда один:
id: my-custom-git-config-leak
info:
name: Exposed .git config
author: твой-ник
severity: medium
description: Утечка конфигурации git через публичный .git/config
tags: exposure,git,misconfig
http:
- method: GET
path:
- "{{BaseURL}}/.git/config"
matchers-condition: and
matchers:
- type: status
status:
- 200
- type: word
part: body
words:
- "[core]"
- "repositoryformatversion"
{{BaseURL}} и {{Hostname}} — динамические переменные, подставляются на каждый таргет автоматически. Это твой юниверсальный payload-шаблон, который летает по листу из тысяч хостов одинаково.
Матчеры — логика срабатывания
Всего 7 типов матчеров, и если ты знаешь только word — ты жжёшь, но недостаточно ярко:
- status — сверка HTTP-кода ответа
- size — длина контента
- word — поиск строк в теле/заголовках
- regex — регулярки для банеров версий
- binary — hex-сигнатуры (магические байты файлов)
- dsl — Go-подобные выражения с хелперами
- xpath — выборка по XML/HTML-дереву
Самый сочный — dsl. Он открывает функции типа contains(), md5(), base64(), compare_versions(), dns_resolve():
matchers:
- type: dsl
dsl:
- 'status_code == 200 && contains(body, "Spring")'
- 'compare_versions(extracted_version, "< 5.3.39")'
condition: and
Лайфхак: matchers-condition: and — требует совпадения всех, or — хотя бы одного. Забыл про это — получишь ливень false positive и админ будет ржать над твоим отчётом.
Экстракторы: тащи данные, а не просто галочку
Матчер говорит «есть» или «нет». Экстрактор — вытаскивает конкретное значение (версию, токен, заголовок) для дальнейшей цепочки атак:
extractors:
- type: regex
part: header
name: server_version
regex:
- "Server: nginx/([0-9.]+)"
Дальше это значение можно прокинуть в DSL-матчер того же темплейта через compare_versions(server_version, "< 1.25.0") — вот тебе автоматизированная проверка на CVE без ручного грепа логов.
Пошаговый разбор: как рожается свой темплейт
- Найди уязвимость руками. Burp Suite, ручной реквест, curl — зафиксируй точный запрос и уникальный индикатор в ответе (не общую фразу типа «error», а что-то специфичное).
- Выбери протокол.
http,dns,tcp,ssl,file,headless— под то, что реально тестируешь. - Опиши info-блок.
id,name,author,severity,tags— без этого темплейт даже не запустится валидацией. - Пропиши request и матчеры так, чтобы они ловили именно твой кейс, а не полсети (иначе получишь FP-эпидемию).
- Валидируй синтаксис:
nuclei -validate -t your-template.yaml
- Тестируй с дебагом на своей уязвимой инстанции:
nuclei -t your-template.yaml -target vulnerable-instance.com -debug
Векторы атак, которые стоит зашить в пентест
- Subdomain takeover / exposed .git, .env, .DS_Store — классика, но кастом под структуру конкретного проекта бьёт точнее community-шаблона.
- CVE-цепочки с версией — DSL +
compare_versions()даёт мгновенный скан парка серверов на конкретный патч. - Кастомные API-эндпоинты — если у цели самописный бэкенд, ни один публичный темплейт его не знает. Только твой.
- SSRF/blind-инъекции через DNS-callback — используй протокол
dnsс интерактивным OOB-сервером (Interactsh) внутри матчера.
Не забывай про обфускацию нагрузки в payload’ах — голый <script>alert(1)</script> в word-матчере палится любым мониторингом за километр, эй, ты серьёзно забыл про это? 😏
Что дальше
Гоняй новый темплейт через -tags для группировки по проекту:
nuclei -t my-templates/ -tags custom -list targets.txt
И да — нашёл рабочий 0day-паттерн через свой темплейт? Молчи, как и положено 😎. Зашивай в приватную репу, а не пуш в публичный nuclei-templates.
Похожие статьи

Как писать RedTeam-отчёт: чтобы не уснул ни CTO, ни разработчик

Автоматизация пентеста в CI/CD: безопасность до деплоя, не после
