РАЗБОР Статья

Разработка инструментов пентестера с AI за 200 строк

Сергей Попов
Сергей Попов Red Team · 6,6 тыс. сообщений
Подписаться
404
[ обложка статьи ]
Режим чтения
Тёмная лаборатория пентестера с изогнутым монитором, на экране код Python и терминал с результатами парсинга Nmap. Голубые и янтарные строки текста светятся в полумраке на фоне ноутбука с выводом N...


Три месяца назад на engagement с 340 хостами я убил полтора часа на ручной разбор Nmap XML - открытые порты, сопоставление версий сервисов с CVE, расстановка приоритетов для эксплуатации. Работа тупо механическая, повторяется на каждом проекте с минимальными вариациями. На следующем engagement ту же задачу выполнял Python-скрипт на 200 строк с qwen2.5-coder:32b через Ollama: шесть минут вместо девяноста. Модель не умнее пентестера - она перемалывает рутину парсинга и первичной ранжировки без усталости. Ниже - пошаговый разбор: как собрать подобную утилиту для создания инструмента пентестера с нуля, где LLM реально экономит время на recon, а где генерирует опасный мусор.

Зачем кастомный инструмент пентестера, когда есть PentestGPT​

Готовые AI-инструменты для пентеста существуют. PentestGPT парсит вывод сканеров и предлагает следующий шаг атаки с обоснованием. Nuclei AI Templates генерируют YAML за секунды. Claude MCP через стандартизированный интерфейс даёт модели доступ к nmap и sqlmap. По данным Hadrian, к марту 2025 каталогизировано свыше 70 open-source AI-инструментов для offensive security - до GPT-4 (апрель 2023) их было меньше пяти. Подробнее - в нашем подробном разборе разработка red team инструментов.

Проблема не в количестве. PentestGPT работает в режиме диалога - отлично для рассуждений о следующем шаге, но он понятия не имеет, что на вашем engagement scope ограничен тремя подсетями, а тестирование production-БД запрещено до 23:00. Nuclei AI генерирует шаблоны, но не встраивается в вашу цепочку ретестов. AutoPentester, по заявлению авторов, превосходит PentestGPT по покрытию уязвимостей на 39.5 п.п., но требует специфичной инфраструктуры.

Кастомный инструмент пентестера решает другую задачу: сшить ваши сканеры, вашу модель и ваш формат отчёта в единый пайплайн. Не universal solution - скрипт под конкретный тип engagement, который убирает 60-80% рутины на этапе recon и fingerprinting.

По данным бенчмарка AutoPenBench (Gioacchini et al., 2024), GPT-4-based агент показал автономный success rate порядка 21%, при участии человека - ~64%. AI - мультипликатор для специалиста, не замена. Разработка утилит для пентеста должна исходить из этого: усилить оператора, а не подменить его решения.

Отдельный вектор - prompt injection через MCP-интерфейсы. Согласно исследованию Embrace The Red, описания MCP-инструментов подставляются прямо в системный промпт модели, и вредоносный MCP-сервер может внедрить скрытые инструкции через Unicode Tags - классический Prompt Injection (OWASP LLM01:2025). Свой скрипт, работающий через прямой HTTP-вызов к Ollama, этому вектору не подвержен: нет промежуточного слоя с динамическими описаниями инструментов.

Архитектура утилиты: от сканера до actionable output​

1792353120939.webp

Утилита, которую я собрал (и которую можно адаптировать под свой стек), состоит из трёх компонентов:
  1. Парсер - принимает XML-вывод Nmap, извлекает хосты, порты, сервисы, версии
  2. LLM-мост - формирует структурированный промпт, отправляет в модель через API, парсит JSON-ответ
  3. Форматтер - превращает ответ модели в приоритизированный список целей, черновики Nuclei-шаблонов, готовые команды для sqlmap
Предусловия для воспроизведения:

КомпонентТребование
Python3.8+
OllamaУстановлен, модель загружена через ollama pull
GPU24 GB VRAM (32B модель) или 8 GB (7B модель)
NmapЗапуск с флагом -oX для XML-вывода
ОСGNU/Linux , macOS; Windows через WSL2

В терминах MITRE ATT&CK утилита покрывает стык Vulnerability Scanning (T1595.002, Reconnaissance) и Artificial Intelligence (T1588.007, Resource Development): данные разведки автоматически превращаются в план атаки.

Бизнес-логика с точки зрения атакующего: по данным Hadrian, time-to-exploit за последние годы сжался до sub-day эксплуатации новых уязвимостей. Кто быстрее перерабатывает данные разведки в вектор атаки - тот первый в scope. Для пентестера это значит одно: ручной разбор 1 400 записей Nmap при time-boxed engagement - непозволительная роскошь.

Парсинг Nmap и формирование контекста для модели​

Nmap с флагом -oX отдаёт XML с полной структурой: хосты, порты, product/version/extrainfo. Задача парсера - вытащить только то, что нужно модели, не засоряя контекстное окно сырым XML на тысячи строк.
Python:
import xml.etree.ElementTree as ET
def parse_nmap(xml_path):
    targets = []
    for host in ET.parse(xml_path).findall('.//host'):
        addr_elem = host.find('.//address[@addrtype="ipv4"]')
        if addr_elem is None:
            continue
        ip = addr_elem.get('addr')
        for port in host.findall('.//port'):
            svc = port.find('service')
            targets.append({'ip': ip, 'port': port.get('portid'),
                'service': svc.get('name','') if svc else '',
                'version': svc.get('version','') if svc else ''})
    return targets
На выходе - список словарей: один открытый порт с сервисом и версией на запись. Из 340 хостов парсер вытянул 1 400+ записей. Передавать их в модель единым запросом - бессмысленно. Разбивка на чанки по 50 записей вмещается в контекстное окно qwen2.5-coder:32b с запасом для развёрнутого ответа.

Промпт-инжиниринг для offensive-задач​

При написании скриптов для пентеста с AI ключевой момент - структура промпта. Модель получает четыре элемента:

Роль: "You are a penetration tester analyzing scan results""Ты пентестер анализирующий результаты". Формат ответа: JSON-схема с полями priority (1-5), attack_vector, reasoning, suggested_tools. Ограничения: "Do not invent CVEs. If unsure about a specific CVE number, write 'potential CVE - verify manually'"Не придумывай CVEшки. Если неуверен насчёт специфики CVE номера, напиши 'потенциальная CVE - требуется ручная проверка'". Данные: структурированный вывод парсера, не raw XML.

Антигаллюцинационная инструкция в системном промпте - не рекомендация, а требование. Без неё qwen2.5-coder генерирует несуществующие CVE-номера примерно в 15-20% ответов (наблюдение на 300+ запросах). Формулировка "do not invent""Не выдумывай" снижает частоту до 3-5%, но не устраняет полностью. Валидация на стороне скрипта нужна в любом случае.

Модель возвращает JSON: для каждой записи - приоритет от 1 (критический) до 5 (информационный), предлагаемый вектор атаки (например, "SQLi through parameter id in REST API""SQLi через параметр id в REST API"), обоснование (версия сервиса, известные слабости) и список инструментов для следующего шага (sqlmap, nuclei, searchsploit).

LLM в пентесте: облако vs self-hosted​

1792353189032.webp

Выбор между облачной и локальной моделью определяется не техническими предпочтениями, а NDA и регуляторикой. На банковском engagement передача данных наружу нарушает договорные обязательства - облачный API категорически не подходит. На bug bounty с публичным scope облачная модель экономит часы.

По данным TrustedSec, из научных работ по LLM в offensive security только ~25% оценивали локальные модели. Большинство работали с облачными frontier-моделями. Для реальных engagement это нерелевантно: данные клиента часто нельзя отправлять третьим сторонам. Подход, который работает на практике: облако - для personal recon и генерации отчётов по открытым данным, Ollama - когда работаете с инфраструктурой клиента.

Ollama для engagement-данных​

Ollama запускает модели локально без утечки данных наружу. Вызов через HTTP API минимален:
Python:
import requests, json
def query_llm(prompt, system="You are a penetration tester"):
    try:
        resp = requests.post("http://localhost:11434/api/generate", json={
            "model": "qwen2.5-coder:32b",
            "prompt": prompt, "system": system,
            "format": "json", "stream": False
        }, timeout=120)
        resp.raise_for_status()
        return json.loads(resp.json()["response"])
    except (requests.RequestException, KeyError, json.JSONDecodeError) as e:
        print(f"[!] LLM query failed: {e}")
        return None
Параметр "format": "json" заставляет модель возвращать валидный JSON. Без этого флага ответы перемежаются рассуждениями в свободной форме - парсинг ломается на каждом третьем запросе. Проверено на практике.

Выбор модели - компромисс между качеством и ресурсами. По данным бенчмарка TrustedSec (4800 тестов на OWASP Juice Shop), качество описаний инструментов (tool descriptions) влияет на pass rate сильнее, чем количество параметров. Модель на 27B с детальным описанием обходит 32B со скудным. Время на скриптинг для пентестеров и промпт-инжиниринг окупается быстрее, чем апгрейд GPU.

Сравнение моделей для offensive-задач:

МодельVRAMСильные стороныКогда не подходит
qwen2.5-coder:32b24 GBСтабильный JSON output, tool callingТребует RTX 4090 или A100
mistral:7b8 GBБыстрая, низкий порог входаПроседает на многошаговых цепочках
granite4:3b4 GBМинимальные ресурсыНе генерирует стабильные tool calls - отсеяна в бенчмарке TrustedSec

Генерация Nuclei-шаблонов через LLM​

1792353223327.webp

📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
. Ложные срабатывания случаются - модель иногда создаёт matchers, ловящие стандартные страницы ошибок. Проверка занимает секунды, но экономит часы на разборе false positives.

Аналогичный подход для sqlmap: модель формирует команды вида sqlmap -u "http://target/api/v1/users?id=1" --batch --risk=3 --level=5 на основе обнаруженных эндпоинтов. Пентестер проверяет параметры, корректирует под scope и запускает. Генерация эксплойтов с помощью нейросетей здесь - не готовый exploit, а черновик для ручной доводки, ускоряющий переход от данных разведки к initial access.

Галлюцинации: где AI модели пентест проваливают​

AI для автоматизации тестирования на проникновение работает ровно до момента, когда модель начинает уверенно врать. Три устойчивых паттерна, которые я фиксирую стабильно:

Фантомные CVE. Модель генерирует правдоподобные номера формата CVE-YYYY-NNNNN, которых не существует в NVD. На 300 запросах к qwen2.5-coder:32b я насчитал порядка 50 таких фантомов - все выглядели реалистично, некоторые содержали убедительное описание несуществующей уязвимости. Решение простое: каждый CVE из ответа проверяется вызовом curl "https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=CVE-XXXX-XXXXX". Двадцать строк Python - и мусор отсеивается до попадания в отчёт.

Призрачные сервисы. Модель "видит" сервисы, отсутствующие в исходном скане. Порт 8080 в Nmap отвечает generic HTTP - модель решает, что там Jenkins, и предлагает payload для RCE. Решение: валидация каждой рекомендации против оригинальных данных парсера. Сервиса нет в XML - рекомендация летит в корзину автоматически, без участия оператора.

Устаревшие эксплойты. Модель предлагает payload для уязвимости, пропатченной годы назад, не упоминая фикс. На time-boxed engagement это катастрофа: часы уходят на dead-end вектор, пока реальная точка входа остаётся нетронутой. Решение: перекрёстная проверка через searchsploit --cve CVE-XXXX-XXXXX и сверка версий с данными парсера.

Из бенчмарка TrustedSec - ещё один показательный паттерн: часть моделей упорно генерировала текстовые объяснения вместо вызова инструмента даже после nudge "Use the tool. Do not explain, send a request""Не используй инструмент. Не объясняй, отправь запрос". Некоторые продолжали рассказывать, что бы они сделали, вместо того чтобы сделать. Для пайплайна с автоматическим парсингом ответа это полная остановка конвейера. Человек в цикле - не опция, а архитектурное требование при работе с LLM в пентесте.

Место утилиты в kill chain: от recon до initial access​

1792353278530.webp

Практический кейс разработки pentest tool не имеет ценности без операционного контекста. Утилита занимает конкретную позицию в цепочке:

Recon - Nmap сканирует scope, результат сохраняется в XML. Vulnerability Scanning (T1595.002, Reconnaissance).

Resource Development - утилита скармливает данные модели, получает приоритизированные векторы с обоснованием и командами. Artificial Intelligence (T1588.007, Resource Development).

Execution - скрипт генерирует команды для следующего этапа: sqlmap для SQL Injection (A03:2021 по OWASP Top 10), Nuclei-шаблоны для верификации, payload-варианты для Burp Intruder. Python (T1059.006, Execution - в MITRE ATT&CK техника описана для всех основных ОС, хотя публичные атомарные тесты существуют преимущественно для Linux).

Дальше - initial access, privilege escalation, lateral movement. Эти этапы пентестер выполняет руками, опираясь на план, сгенерированный утилитой. Разработка инструментов пентестера с AI ускоряет переход от сырых данных разведки к плану атаки, но решение о том, куда бить - за оператором.

Ценность утилиты не в конкретной модели. Сегодня qwen2.5-coder:32b, через полгода - что-то новое. Парсер, промпты, валидация, интеграция с вашим стеком - это код, который накапливается от проекта к проекту. Модель - заменяемый компонент. Пайплайн - нет.

Девять из десяти статей про AI-агенты в ИБ описывают готовые продукты: установи, запусти, получи результат. Для первого знакомства - сойдёт. Но бесполезно на engagement, где scope нестандартный, NDA запрещает облако, а половина хостов - legacy, про которые модель ничего не знает. Навык, который стоит прокачивать - не prompt engineering в чат-интерфейсе, а умение собрать свой пайплайн: парсер, LLM-мост, валидатор, форматтер. По собственным проектам вижу: на одном engagement кастомный парсер с LLM экономит час, на другом - четыре. Разница определяется не моделью, а тем, насколько точно пайплайн заточен под конкретную задачу. Через пару лет пентестеры без навыка скриптовать собственные AI-интеграции застрянут на типовых проектах, где всё автоматизировано дешёвым SaaS. Уникальная ценность - в кастомных цепочках под нестандартные задачи, где готовые продукты не работают, а ручная работа занимает дни. На HackerLab (ХакерЛаб) лежат сценарии, где разведку нужно довести до полной цепочки impact - хороший полигон, чтобы проверить, держит ли ваш пайплайн за пределами учебных стендов.
Полезно

Комментарии

0