На последнем пентесте 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 в цепочке веб-пентеста
Кастомный 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 году
Критический факт, который упускают все русскоязычные гайды по теме: согласно официальной документации 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 предлагает три уровня кастомизации, и не для каждой задачи нужно полноценное расширение:| Критерий | Bambdas | BChecks | Расширения (Java/Kotlin) | Расширения (Python/Jython) |
|---|---|---|---|---|
| Порог входа | Минимальный | Низкий | Средний | Низкий |
| Язык | Java-фрагменты | Собственный DSL | Java 21 / Kotlin | Python 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 всё ещё уместен:
- Одноразовый скрипт - написать пассивный сканер за 20 минут, использовать на одном проекте, выбросить после отчёта.
- Миграция невозможна - команда годами использует Python-расширения, написанные в 2019–2022, и переписывать на Java экономически невыгодно.
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
Расширения генерируют трафик, и на стороне защиты он заметен. Понимание 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: чеклист
- Проверить BApp Store - Param Miner, Turbo Intruder, JWT Editor, Stepper, ActiveScan++ покрывают типовые задачи. Писать своё стоит только если ничего подходящего нет.
- Определить масштаб: фильтр/правило в Proxy -> Bambdas; кастомная scan check -> BChecks; всё остальное -> Extension.
- Выбрать язык: новый проект -> Java 21 + Montoya API. Одноразовый скрипт -> Python/Jython + legacy API.
- Скачать стартовый проект из 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). - Собрать пустой JAR (
./gradlew jar) и загрузить в Burp - убедиться, что инфраструктура сборки работает до написания бизнес-логики. - Реализовать логику в
Extension.java: зарегистрироватьHttpHandlerчерезmontoyaApi.http().registerHttpHandler()или scan check черезmontoyaApi.scanner().registerScanCheck(). - Протестировать на тестовом приложении (PortSwigger Web Security Academy, DVWA, OWASP Juice Shop - не на боевой цели).
- При планах на BApp Store - изучить acceptance criteria до начала разработки: PortSwigger требует конкретных стандартов кода и документации.
Большинство русскоязычных гайдов по 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-категории попадаются задачи, где без кастомного скрипта для подписи запросов не продвинешься - хороший полигон, чтобы обкатать первое расширение перед боевым проектом.
Последнее редактирование модератором: