Статья Разработка расширений Burp Suite на Python и Java: автоматизация пентеста веб-приложений

Матричный принтер на антистатическом коврике печатает зелёный текст с кодом на перфорированной бумаге. Янтарный индикатор питания слабо освещает сцену в кромешной тьме.


На последнем пентесте API финтех-сервиса каждый запрос требовал HMAC-подпись в заголовке X-Signature - вычислялась из тела, текущего timestamp и сессионного секрета, полученного при аутентификации. Ни один плагин из BApp Store эту схему не поддерживал: Repeater слал запросы с невалидной подписью, Intruder бесполезно молотил по 401. Два часа на кастомное расширение с автоматической переподписью - и мы сэкономили неделю ручной возни с Postman.
BApp Store (Burp App Store) - Магазин расширений для Burp Suite

Когда стандартных возможностей не хватает, разработка расширений Burp Suite перестаёт быть капризом и становится единственным рабочим вариантом. Ниже - конкретный путь от нуля до рабочего JAR на Montoya API, с разбором legacy Python-подхода и его ограничений.
HMAC-подпись - в криптографии, один из механизмов проверки целостности информации, позволяющий гарантировать то, что данные, передаваемые или хранящиеся в ненадёжной среде, не были изменены посторонними лицами.

Место расширений Burp Suite в цепочке веб-пентеста​

1780464603377.webp

Кастомный Burp-плагин - не самоцель. Расширение автоматизирует конкретный этап kill chain, где встроенные возможности буксуют из-за нестандартной бизнес-логики приложения. Подробнее - в нашем материале про разработка red team инструментов.

Разведка (Vulnerability Scanning, T1595.002, Reconnaissance). Расширения вроде Param Miner автоматически обнаруживают скрытые GET/POST-параметры, заголовки и Cookie. PortSwigger Scanner не знает бизнес-логику конкретного SPA и пропускает кастомные точки входа. Написать расширение Burp Python-скриптом для перебора специфических параметров - полчаса работы, а на выходе - десятки скрытых endpoints, которые Scanner не увидел.

Initial access (Exploit Public-Facing Application, T1190). Кастомный пассивный сканер детектирует мисконфигурации, специфичные для целевого приложения: CORS с отражением произвольного Origin (OWASP A05:2021 - Security Misconfiguration), нестандартные injection-точки в проприетарных форматах запросов (OWASP A03:2021 - Injection), слабые криптографические схемы токенов (OWASP A02:2021 - Cryptographic Failures). Стандартный Scanner проверяет типовые паттерны. Кастомный - то, что знает пентестер.

Credential access (Brute Force, T1110; Steal Web Session Cookie, T1539). Многоступенчатая аутентификация с CSRF-токенами, OTP и кастомными challenge-response - ночной кошмар для Intruder в стоковом режиме. Расширение Stepper позволяет выстроить цепочку запросов с передачей параметров между шагами, а кастомный HttpHandler может прозрачно обновлять сессионный токен при каждом запросе. Intruder и Repeater работают, будто сессия бессмертна.

Типичная ситуация: вы на внутреннем пентесте, перед вами веб-интерфейс управления инфраструктурой с кастомной аутентификацией. Стандартный Intruder не может пробрутить логин, потому что каждый запрос требует свежий CSRF-токен. Кастомное расширение решает задачу за пару часов разработки - и всё оставшееся время уходит на эксплуатацию, а не на борьбу с инструментом.

[Применимо: внешний и внутренний пентест веб-приложений, API-тестирование, bug bounty]

Montoya API или Legacy Extender API: что выбирать в 2025 году​

1780465126525.webp

Критический факт, который упускают все русскоязычные гайды по теме: согласно официальной документации PortSwigger, legacy Extender API больше не поддерживается. Цитата: «the Extender API is no longer actively maintained»«Extender API более не поддерживается» (portswigger.net/burp/documentation/desktop/extend-burp/extensions/creating). Все публикации на Хабре и в русскоязычных блогах, описывающие разработку через IBurpExtender и IScannerCheck, используют API, для которого не будет ни исправлений, ни новых фич.

Montoya API - полная замена. Единая точка входа - интерфейс MontoyaApi с 24 методами доступа: http(), proxy(), scanner(), intruder(), repeater(), logging(), userInterface(), utilities(), collaborator(), websockets() и даже ai() для AI-интеграции в Professional-версии (согласно javadoc PortSwigger). Для сравнения: в legacy API приходилось возиться с IBurpExtenderCallbacks, где каждый интерфейс (IScannerCheck, IHttpListener, ITab, IMessageEditorController) регистрировался отдельным вызовом и взаимодействовал с другими через неочевидные цепочки.

Montoya API работает с immutable-объектами запросов и ответов - метод withUpdatedHeader() возвращает новый экземпляр, а не мутирует существующий. Это устраняет целый класс race condition при параллельной работе Intruder.

Что появилось в Montoya и чего нет в legacy: работа с HTTP/2 kettled-запросами, интеграция с LLM через ai(), Bambdas и BChecks как альтернативные механизмы расширяемости, расширенная поддержка WebSockets.

Python, Java или Bambdas: таблица выбора для автоматизации веб-пентеста​

Прежде чем открывать IDE, определите масштаб задачи. PortSwigger предлагает три уровня кастомизации, и не для каждой задачи нужно полноценное расширение:

КритерийBambdasBChecksРасширения (Java/Kotlin)Расширения (Python/Jython)
Порог входаМинимальныйНизкийСреднийНизкий
ЯзыкJava-фрагментыСобственный DSLJava 21 / KotlinPython 2.7 (Jython)
APIОграниченныйScan-ориентированныйMontoya API (полный)Legacy Extender API
Типовая задачаКастомные фильтры Proxy, match-and-replaceКастомные scan checksСложная логика, UI, интеграцииБыстрый одноразовый скрипт
Поддержка PortSwiggerАктивнаяАктивнаяАктивнаяПрекращена
Доступ к AI APIНетНетДа (Professional)Нет
Подходит для BApp StoreНетНетДаФормально да, но без развития
Когда НЕ использоватьНужна сложная логика или UIНужно больше, чем scan checkЗадача решается Bambdas/BChecks за 5 минутНовый проект с перспективой поддержки

Рекомендация PortSwigger однозначна: Java с Montoya API - основной путь для Burp Suite API разработки. Kotlin компилируется в JAR и загружается как Java-расширение. Python через Jython уместен для одноразовых скриптов и миграции существующей кодовой базы - но не для новых проектов.

Bambdas (Java-фрагменты, работающие напрямую в Burp) закрывают задачи фильтрации и модификации трафика без проектной инфраструктуры. BChecks (DSL для scan checks) заменяют пассивные сканеры для типовых проверок. Полноценное расширение нужно, когда требуется кастомный UI, интеграция с внешними сервисами, сложная многоступенчатая логика или работа с несколькими компонентами Burp одновременно.

Пишем расширение на Java с Montoya API​

Требования к окружению​

  • ОС: Windows, macOS, GNU/Linux - без ограничений
  • JDK: Java 21 (Burp не поддерживает расширения на Java выше 21 - явное требование в документации PortSwigger)
  • IDE: IntelliJ IDEA Community Edition (бесплатная, рекомендована PortSwigger) или любая IDE с Gradle-поддержкой
  • Burp Suite: Community или Professional, версия 2024.x+ с поддержкой Montoya API
  • RAM: минимум 4 ГБ для одновременной работы IDE + Burp, рекомендуется 8 ГБ
  • Сеть: интернет нужен для первичной загрузки Gradle-зависимостей; дальнейшая разработка - offline
  • Сборка: Gradle (входит в стартовый проект, ставить отдельно не нужно)

Точка входа: Extension.java из стартового проекта​

PortSwigger предоставляет готовый стартовый проект - скачивается прямо из Burp: Extensions -> APIs -> Download starter project. Проект содержит build.gradle.kts с зависимостью на Montoya API, файл settings.gradle.kts и Extension.java - единственный файл, который нужно трогать на старте.

Минимальная точка входа расширения (из официальной документации PortSwigger):
Java:
import burp.api.montoya.BurpExtension;
import burp.api.montoya.MontoyaApi;

public class Extension implements BurpExtension {
    @Override
    public void initialize(MontoyaApi montoyaApi) {
        montoyaApi.extension().setName("HMAC Auto-Signer");
        montoyaApi.http().registerHttpHandler(
            new MyHttpHandler(montoyaApi));
    }
}
Три момента, на которые стоит обратить внимание. implements BurpExtension - интерфейс, который сообщает Burp, что перед ним расширение. initialize(MontoyaApi montoyaApi) вызывается при загрузке - здесь происходит регистрация всех обработчиков. @Override гарантирует ошибку компиляции при опечатке в имени метода - без этой аннотации Burp молча проигнорирует расширение, и вы будете полчаса гадать, почему ничего не работает.

Сборка: ./gradlew jar в корне проекта. Результат - JAR в build/libs/, загружается в Burp через Extensions -> Installed -> Add. От скачивания шаблона до первого «Hello, Burp» - 15 минут.

С 2025 года в стартовом проекте появился файл CLAUDE.md - подготовленный промпт для генерации кода расширений через LLM (Claude Code). PortSwigger рекомендует использовать его для прототипирования, но с обязательным ревью результата. Файл содержит контекст Montoya API и паттерны расширений, так что LLM не галлюцинирует несуществующие методы. Для других LLM содержимое CLAUDE.md и папки docs/ можно передать как часть контекстного окна.

HttpHandler: перехват и модификация запросов на лету​

Центральная задача большинства пентест-расширений - прозрачно модифицировать трафик. В Montoya API за это отвечает HttpHandler с двумя методами: handleHttpRequestToBeSent() для исходящих запросов и handleHttpResponseReceived() для ответов.
📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме


Для случая с HMAC-подписью: в handleHttpRequestToBeSent() вычисляется HMAC от тела запроса через стандартные Java-классы javax.crypto.Mac и javax.crypto.spec.SecretKeySpec, результат добавляется через request.withAddedHeader("X-Signature", hmacValue). Никакого ручного пересчёта между вкладками.

[Применимо: любой веб-пентест с нестандартной аутентификацией; особенно ценно для API с HMAC/JWT/кастомными схемами подписи]

Python через Jython: когда legacy-подход оправдан​

Python-расширения Burp Suite работают через Jython - JVM-реализацию Python 2.7. Ограничения жёсткие: нет Python 3, нет requests, нет asyncio, нет доступа к Montoya API. Расширения используют legacy Extender API с интерфейсами IBurpExtender, IScannerCheck, IHttpListener.

Два случая, когда Jython всё ещё уместен:
  1. Одноразовый скрипт - написать пассивный сканер за 20 минут, использовать на одном проекте, выбросить после отчёта.
  2. Миграция невозможна - команда годами использует Python-расширения, написанные в 2019–2022, и переписывать на Java экономически невыгодно.
Настройка: в Burp - Extensions -> Options -> Python Environment - путь к jython-standalone-2.7.x.jar (скачивается с jython.org). Для отладки - репозиторий burp-exceptions: превращает нечитаемые Java-трейсбэки вида java.lang.RuntimeException: org.python.core.PyException at burp.fl.a(Unknown Source) в нормальный AttributeError: 'burp.ul' object has no attribute 'setEsditable'. Без этого дебаг на Jython - безумный мазохизм.

Архитектура пассивного сканера на Python (логика без полного листинга, чтобы не плодить deprecated-паттерны): класс наследует IBurpExtender и IScannerCheck, метод doPassiveScan(baseRequestResponse) получает пару запрос-ответ. Через _helpers.analyzeResponse() извлекаются заголовки ответа. Итерация по заголовкам: если присутствует Access-Control-Allow-Origin с отражением произвольного Origin из запроса и Access-Control-Allow-Credentials: true - фиксируется CORS-мисконфигурация через кастомный IScanIssue. Это Security Misconfiguration (OWASP A05:2021) - типичная находка на внешних пентестах.

Этот подход описан в нескольких русскоязычных материалах (Хабр, 2021), но с оговоркой: legacy IScannerCheck работает с PortSwigger Scanner API, поведение которого меняется между версиями. Для нового проекта аналогичный пассивный сканер на Montoya API регистрируется через montoyaApi.scanner().registerScanCheck() и ведёт себя предсказуемее в долгосрочной перспективе.

[Применимо: быстрое прототипирование; при работе на фиксированной версии Burp (например, корпоративный стандарт Burp 2023.x)]

Что видит SOC и WAF при работе расширений Burp​

1780466514231.webp

Расширения генерируют трафик, и на стороне защиты он заметен. Понимание OPSEC-рисков критично для пентеста с жёстким scope.

WAF (ModSecurity, Cloudflare, Wallarm, PT Application Firewall). Расширения для активного фаззинга (Intruder с кастомными payload, Turbo Intruder) оставляют типичные сигнатуры: высокая частота запросов с одного IP, payload-паттерны в параметрах, аномальные заголовки. Кастомное расширение может снизить behavioral detection: рандомизировать задержки между запросами через Thread.sleep() с переменным интервалом, ротировать User-Agent, использовать upstream-прокси для распределения по IP. Но это не bypass WAF в чистом виде - если сигнатурный анализ блокирует конкретный payload (<script> в параметре), расширение этого не обойдёт.

SIEM и access logs. Пассивные расширения (анализаторы трафика, пассивные сканеры) не создают дополнительных запросов - они обрабатывают данные, уже прошедшие через Proxy. Расширения с api.http().sendRequest() (активная отправка) генерируют трафик, видимый в access logs. При пентесте внутреннего веб-приложения за корпоративным прокси SOC увидит всплеск нетипичных запросов, коррелируемый с вашим IP и временем активности. Особенно заметно, когда расширение выполняет автоматическую реаутентификацию: серия POST-запросов на /login с правильными кредами за секунды - аномалия, которую любой SIEM-алерт на brute force поймает.

Collaborator и DNS-логи. Если расширение использует montoyaApi.collaborator() для проверки blind-уязвимостей (SSRF, blind XSS, Adversary-in-the-Middle сценарии - T1557), DNS-запросы к *.oastify.com фиксируются в корпоративных DNS-логах. Для проектов с OPSEC-ограничениями - собственный Collaborator-сервер.

Практический вывод: пассивные расширения (CORS-сканер, анализатор заголовков) - минимально заметны. Активные (фаззеры, brute-force-утилиты) - заметны ровно настолько же, насколько стандартный Intruder. Кастомный код даёт контроль над таймингами и payload-форматом, но не делает трафик невидимым.

[Применимо: внешний пентест через интернет - максимальная актуальность; внутренний пентест с согласованным scope - ограничения менее релевантны]

Отладка и типичные грабли при разработке Burp Suite расширений​

Консоль - основной инструмент. В Montoya API: montoyaApi.logging().logToOutput("debug: " + request.url()). Вывод - Extensions -> вкладка расширения -> Output. В Python: sys.stdout = PrintWriter(callbacks.getStdout(), True), затем sys.stdout.println(). Никакие IDE-дебаггеры не подключаются к расширению внутри Burp напрямую. Весь дебаг - через логирование. Привыкайте =).

Версия Java. Burp поддерживает Java 21 и ниже. JAR, собранный на Java 22+, не загрузится - ошибка появится на вкладке Errors, но формулировка неочевидная (UnsupportedClassVersionError). Я на этом терял время дважды, пока не вбил в привычку: перед первой сборкой - javac --version и sourceCompatibility = JavaVersion.VERSION_21 в build.gradle.kts.

Jython import. Python-расширение не загружается с ImportError - скорее всего, не указан путь Folder for loading modules в Extensions -> Options -> Python Environment. Каждый модуль (включая exceptions_fix.py) должен лежать в этой директории.

Блокирующие вызовы в обработчиках. handleHttpRequestToBeSent() вызывается синхронно. Тяжёлая операция внутри (запрос к внешнему API, длительное вычисление) блокирует весь трафик Burp. Решение: CompletableFuture для асинхронной логики, кеширование результатов или перенос тяжёлых операций в handleHttpResponseReceived(), где задержка менее критична.

Совместимость legacy-расширений. Python-плагины, написанные в 2020–2021 под Burp 2020.x, могут некорректно работать в Burp 2025.x. Типичный симптом: deprecated-метод getToolFlag() возвращает неожиданные значения, пассивный сканер пропускает часть трафика. Если расширение критично - это аргумент за миграцию на Montoya API.

Бесконечный цикл при создании UI-компонентов. Отдельная ловушка из документации PortSwigger: если ExtensionHttpRequestEditor использует HttpRequestEditor как UI-компонент при регистрации HttpRequestEditorProvider, возникает бесконечный цикл вложенных редакторов, и Burp падает. Аналогично для HttpResponseEditor. На форумах PortSwigger этот вопрос всплывает регулярно.

Статус поддержки: Montoya API активно обновляется (javadoc - май 2025, GitHub-репозиторий burp-extensions-montoya-api - еженедельные коммиты). Legacy Extender API - архив без обновлений.

От идеи до рабочего JAR: чеклист​

  1. Проверить BApp Store - Param Miner, Turbo Intruder, JWT Editor, Stepper, ActiveScan++ покрывают типовые задачи. Писать своё стоит только если ничего подходящего нет.
  2. Определить масштаб: фильтр/правило в Proxy -> Bambdas; кастомная scan check -> BChecks; всё остальное -> Extension.
  3. Выбрать язык: новый проект -> Java 21 + Montoya API. Одноразовый скрипт -> Python/Jython + legacy API.
  4. Скачать стартовый проект из Burp (Extensions -> APIs -> Download starter project) или клонировать примеры: [URL='https://github.com/PortSwigger/burp-extensions-montoya-api-examples']portswigger/burp-extensions-montoya-api-examples[/URL] на GitHub (15+ готовых сценариев: HttpHandler, scan checks, WebSockets, кастомный UI).
  5. Собрать пустой JAR (./gradlew jar) и загрузить в Burp - убедиться, что инфраструктура сборки работает до написания бизнес-логики.
  6. Реализовать логику в Extension.java: зарегистрировать HttpHandler через montoyaApi.http().registerHttpHandler() или scan check через montoyaApi.scanner().registerScanCheck().
  7. Протестировать на тестовом приложении (PortSwigger Web Security Academy, DVWA, OWASP Juice Shop - не на боевой цели).
  8. При планах на BApp Store - изучить acceptance criteria до начала разработки: PortSwigger требует конкретных стандартов кода и документации.
Весь цикл от идеи до рабочего расширения для опытного разработчика - 2–4 часа. Для первого раза - день с учётом настройки окружения и чтения документации.

Большинство русскоязычных гайдов по Burp Suite extension на Python описывают legacy Extender API - подход, которому PortSwigger прекратил поддержку. Это формирует искажённую картину: начинающий пентестер изучает IBurpExtender и IScannerCheck, пишет расширение на Jython, а через полгода обнаруживает, что оно не работает после обновления Burp. Я наблюдал это минимум в трёх командах - каждый раз реакция одинаковая: «мы же только что это написали».

Переход на Montoya API - не вопрос предпочтений, а вопрос инженерной гигиены. Java-расширение с Gradle собирается воспроизводимо, дебажится через стандартные инструменты, получает доступ ко всем новым фичам Burp включая AI и HTTP/2. Python через Jython - это Python 2.7 в 2025 году. Работает, пока не сломается. А когда сломается - чинить нечем.

Отдельная мысль про конкурентное преимущество. Команда с набором кастомных сканеров под типовые мисконфигурации клиентских API - CORS, HMAC, кастомные JWT-схемы - закрывает аудит быстрее. Но для этого расширения надо поддерживать, а поддерживать код на deprecated API бессмысленно. На HackerLab.pro в web-категории попадаются задачи, где без кастомного скрипта для подписи запросов не продвинешься - хороший полигон, чтобы обкатать первое расширение перед боевым проектом.
 
Последнее редактирование модератором:
Мы в соцсетях:

Взломай свой первый сервер и прокачай скилл — Начни игру на HackerLab

Похожие темы

🚀 Первый раз на Codeby?
Гайд для новичков: что делать в первые 15 минут, ключевые разделы, правила
Начать здесь →
🔴 Свежие CVE, 0-day и инциденты
То, о чём ChatGPT ещё не знает — обсуждаем в реальном времени
Threat Intel →
💼 Вакансии и заказы в ИБ
Pentest, SOC, DevSecOps, bug bounty — работа и проекты от проверенных компаний
Карьера в ИБ →

HackerLab