- Регистрация
- 3 Апр 2025
- Сообщения
- 14
- Реакции
- 7
Связываем Burp Suite и Acunetix через Python-расширение
При работе с веб-приложениями часто приходится использовать несколько сканеров.
У каждого инструмента есть свои сильные стороны:
- Acunetix хорошо справляется с массовым автоматическим сканированием;
- Burp Suite удобен для ручного анализа конкретного таргета и подтверждения уязвимостей.
Идея простая — объединить эти инструменты, чтобы:
- передавать таргеты из Burp в Acunetix;
- запускать сканы в один клик;
- в итоге иметь все результаты внутри проекта Burp.
Для этого напишем Burp-расширение на Python (Jython), которое будет работать через Acunetix API.
Проект получается довольно объёмным, поэтому разобьём его на части. В этой статье реализуем:
- базовый каркас расширения;
- собственную вкладку в Burp;
- интерфейс для хранения и проверки API-ключа Acunetix.
Структура проекта
Чтобы код не превратился в кашу, сразу разобьём расширение на модули:
Bash:
burp-acunetix.py # основной файл расширения
ui.py # интерфейс вкладки
В Burp при загрузке расширения нужно указывать именно burp-acunetix.py.
Каркас Burp-расширения
Любое расширение Burp должно реализовывать интерфейс IBurpExtender.
Если мы хотим добавить собственную вкладку — также используем ITab.
burp-acunetix.py
Python:
# -*- coding: utf-8 -*-
# Если используешь кириллицу в комментариях — обязательно указывай кодировку
# В интерфейсе Burp кириллицу лучше не использовать
from burp import IBurpExtender, ITab
from ui import AppConfigPanel
class BurpExtender(IBurpExtender, ITab):
def registerExtenderCallbacks(self, callbacks):
# Сохраняем callbacks, чтобы управлять Burp
self._callbacks = callbacks
self._helpers = callbacks.getHelpers()
# Имя расширения в списке Extensions
callbacks.setExtensionName("Acunetix Sync")
# Инициализируем интерфейс
self.ui = AppConfigPanel(callbacks)
# Добавляем собственную вкладку
callbacks.addSuiteTab(self)
# Название вкладки
def getTabCaption(self):
return "Acunetix Sync"
# Компонент интерфейса вкладки
def getUiComponent(self):
return self.ui.get_component()
Что здесь важно
- registerExtenderCallbacks — точка входа расширения;
- callbacks — основной API Burp;
- addSuiteTab — добавляет вкладку в интерфейс;
- UI вынесен в отдельный класс для читаемости и масштабирования.
Интерфейс расширения (Swing + Jython)
Burp написан на Java, поэтому интерфейс расширений строится на Swing.
Ожидается, что вкладка вернёт объект JPanel.
Наша задача на этом этапе — сделать простой интерфейс:
- поле для API Key;
- поле для API URL;
- кнопка Check — проверка доступности API;
- кнопка Save — сохранение данных.
ui.py
Python:
# -*- coding: utf-8 -*-
from javax.swing import (
JPanel, JLabel, JTextField, JButton,
BoxLayout, BorderFactory, Box, JScrollPane,
JOptionPane
)
from java.awt import (
GridBagLayout, GridBagConstraints,
Insets, Dimension, BorderLayout
)
class AppConfigPanel(object):
def __init__(self, callbacks, client=None, store=None):
self._callbacks = callbacks
self.client = client # объект Acunetix API (позже)
self.store = store # хранилище данных (позже)
self.current_target = None
self._build_ui()
def _build_ui(self):
# Корневая панель
self.panel = JPanel(BorderLayout())
main_container = JPanel()
main_container.setLayout(
BoxLayout(main_container, BoxLayout.Y_AXIS)
)
main_container.add(Box.createVerticalStrut(15))
# Панель API-настроек
api_panel = JPanel(GridBagLayout())
api_panel.setBorder(
BorderFactory.createTitledBorder("API Settings")
)
gbc = GridBagConstraints()
gbc.insets = Insets(6, 6, 6, 6)
gbc.anchor = GridBagConstraints.WEST
# API Key
gbc.gridx = 0
gbc.gridy = 0
api_panel.add(JLabel("API Key:"), gbc)
gbc.gridx = 1
gbc.weightx = 1.0
gbc.fill = GridBagConstraints.HORIZONTAL
self.key_field = JTextField()
self.key_field.setPreferredSize(Dimension(280, 26))
api_panel.add(self.key_field, gbc)
# API URL
gbc.gridx = 0
gbc.gridy = 1
gbc.weightx = 0
gbc.fill = GridBagConstraints.NONE
api_panel.add(JLabel("API URL:"), gbc)
gbc.gridx = 1
gbc.weightx = 1.0
gbc.fill = GridBagConstraints.HORIZONTAL
self.url_field = JTextField()
api_panel.add(self.url_field, gbc)
# Кнопки
btn_panel = JPanel()
btn_panel.setLayout(
BoxLayout(btn_panel, BoxLayout.X_AXIS)
)
self.check_btn = JButton(
"Check",
actionPerformed=self.on_check_connection
)
self.check_btn.setPreferredSize(Dimension(100, 28))
btn_panel.add(self.check_btn)
btn_panel.add(Box.createHorizontalStrut(8))
self.save_btn = JButton(
"Save",
actionPerformed=self.on_save
)
self.save_btn.setPreferredSize(Dimension(100, 28))
btn_panel.add(self.save_btn)
gbc.gridx = 1
gbc.gridy = 2
gbc.anchor = GridBagConstraints.EAST
gbc.fill = GridBagConstraints.NONE
api_panel.add(btn_panel, gbc)
main_container.add(api_panel)
main_container.add(Box.createVerticalStrut(15))
wrapper = JPanel(BorderLayout())
wrapper.add(main_container, BorderLayout.NORTH)
self.panel.add(JScrollPane(wrapper), BorderLayout.CENTER)
def get_component(self):
return self.panel
# Проверка доступности Acunetix API
def on_check_connection(self, event):
JOptionPane.showMessageDialog(
self.panel,
"API check is not implemented yet",
"Info",
JOptionPane.INFORMATION_MESSAGE
)
# Сохранение API-данных
def on_save(self, event):
JOptionPane.showMessageDialog(
self.panel,
"Saving credentials is not implemented yet",
"Info",
JOptionPane.INFORMATION_MESSAGE
)
Пояснения по интерфейсу
- Все элементы (JTextField, JButton) сохраняются в атрибутах класса;
- actionPerformed — основной обработчик событий;
- GridBagLayout позволяет аккуратно выровнять элементы;
- Пока логика кнопок заглушена — позже добавим реальные запросы к Acunetix API и сохранение данных через Burp API.
Первый запуск расширения
- Скачай Jython Standalone (последнюю версию).
- В Burp открой:
Extensions → Extensions Settings - В разделе Python Environment укажи путь к jython-standalone.jar.
- Добавь новое расширение и выбери burp-acunetix.py.
Практическое применение связки Burp и Acunetix
Связывание Burp Suite и Acunetix имеет смысл в тех случаях, когда автоматическое и ручное тестирование идут параллельно, а не по очереди.Пример 1: первичный обзор таргета
Проект добавляется в Scope Burp. По мере ручного изучения структуры приложения (эндпоинты, параметры, авторизация) таргет передаётся в Acunetix напрямую из Burp.
Acunetix запускает автоматический скан и проверяет:
- типовые серверные уязвимости;
- инъекции;
- ошибки конфигурации;
- проблемные параметры, которые легко пропустить при ручной работе.
При этом Burp остаётся центральной точкой: все запросы, сессии и контекст уже находятся в проекте, и нет необходимости дублировать настройки между инструментами.
Пример 2: массовое сканирование + ручная валидация
Если в проекте несколько хостов или поддоменов, их удобно:
- собрать в Burp;
- отправить пачкой в Acunetix;
- запустить сканирование в фоне.
Пока Acunetix работает, в Burp можно:
- анализировать бизнес-логику;
- проверять авторизационные сценарии;
- заниматься теми вещами, которые автоматические сканеры покрывают плохо.
После завершения скана найденные уязвимости сопоставляются с реальными HTTP-запросами в Burp, что упрощает проверку и воспроизведение.
Пример 3: работа с false positive
Автоматические сканеры неизбежно находят спорные или некорректные результаты. Когда уязвимость приходит обратно в Burp:
- виден исходный запрос;
- понятен параметр и точка инъекции;
- можно быстро повторить запрос вручную и проверить поведение сервера.
Это особенно удобно при анализе:
- XSS;
- SQLi;
- SSRF;
- нестандартных параметров в JSON или GraphQL.
Пример 4: долгоживущие проекты
В проектах, которые тестируются не один день, важно сохранять контекст:
- какие таргеты уже проверялись;
- какие уязвимости подтверждены;
- какие требуют повторной проверки после фиксов.
Вывод
Связка Burp и Acunetix — это не попытка заменить ручное тестирование автоматикой и не наоборот.Это способ организовать процесс так, чтобы:
- автоматический сканер работал в фоне;
- ручной анализ не терял контекст;
- результаты были привязаны к реальным HTTP-запросам.
Расширение решает именно эту задачу: сокращает количество ручных действий и удерживает весь процесс в одном рабочем пространстве.