Связываем Burp Suite и Acunetix через Python-расширение

Mur404

Bit
Пользователь
Регистрация
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.
⚠️ В интерфейсе не используем кириллицу — Burp может вести себя нестабильно.




Первый запуск расширения​

  1. Скачай Jython Standalone (последнюю версию).
  2. В Burp открой:
    Extensions → Extensions Settings
  3. В разделе Python Environment укажи путь к jython-standalone.jar.
  4. Добавь новое расширение и выбери burp-acunetix.py.
Если всё сделано правильно — появится вкладка Acunetix Sync с нашим интерфейсом.

Практическое применение связки 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 позволяют использовать Burp-проект как центральное хранилище состояния тестирования, а не просто как прокси.




Вывод​

Связка Burp и Acunetix — это не попытка заменить ручное тестирование автоматикой и не наоборот.
Это способ организовать процесс так, чтобы:
  • автоматический сканер работал в фоне;
  • ручной анализ не терял контекст;
  • результаты были привязаны к реальным HTTP-запросам.

Расширение решает именно эту задачу: сокращает количество ручных действий и удерживает весь процесс в одном рабочем пространстве.
 
Сверху