Содержание статьи
В обеих программах есть сотни сканеров, причем многие уникальны для одной из них. Acunetix шикарно выполняет массовое сканирование, тогда как Burp хорош при работе с одним таргетом. На мой взгляд, они идеально дополняют друг друга.
Я поставил цель — создать инструмент, который позволит быстро и удобно собирать полную информацию о таргете и уязвимостях в проекте Burp. Цель серьезная, и код расширения вышел объемным. Поэтому я решил подготовить два материала.
Начнем с создания интерфейса для управления ключами доступа к Acunetix API, настроим передачу таргетов из Burp в Acunetix и обратно. Я помогу разобраться, как строится интерфейс вкладки и как выполнять сторонние запросы в Burp. По дороге ты освоишь основы Acunetix API.
Интерфейс расширения
Нам потребуется хранить ключ от Acunetix API и правильный URL. Давай сделаем вкладку с небольшим интерфейсом из двух текстовых полей и кнопок: Check и Save. Кнопка Check проверит доступность API, Save отправит данные в хранилище, чтобы не нужно было вводить креды перед каждым использованием.
www
Исходные коды расширения можешь скачать с моего GitHub.
Расширение разделим на модули, чтобы сохранить читаемость кода и возможность масштабировать без боли. Создай основной файл burp-acunetix.. При добавлении в Burp нужно будет указывать именно этот файл!
# -*- coding: utf-8 -*-# Обязательно указывай кодировку, если используешь кириллицу в комментариях# В интерфейсе не используй кириллицу вообщеfrom burp import IBurpExtender, ITab# Вынесем интерфейс в отдельный класс, чтобы сохранить читаемость кодаfrom ui import AppConfigPanel# Любое расширение должно расширять класс IBurpExtender, ITab нужен, если создаешь собственную вкладкуclass BurpExtender(IBurpExtender, ITab): # Главная функция, в которой определяешь поведение расширения и его возможности def registerExtenderCallbacks(self, callbacks): # Сохрани колбэки Burp Extender, чтобы была возможность управлять Burp self._callbacks = callbacks # То же с функциями-хелперами self._helpers = callbacks.getHelpers() # Установи имя расширения в списке расширений Burp (не название вкладки) callbacks.setExtensionName("Acunetix Sync") # Класс интерфейса реализуем чуть позже self.ui = AppConfigPanel(callbacks) # Добавление собственной вкладки в интерфейс Burp callbacks.addSuiteTab(self) # Функция ITab для установки надписи на вкладке def getTabCaption(self): return "Acunetix Sync" # Функция ITab для привязки интерфейса расширения к твоей вкладке def getUiComponent(self): # Создание интерфейса из класса AppConfigPanel return self.ui.get_component()
info
registerExtenderCallbacks — главная функция, которая выполняет инициализацию любого расширения, написанного для Extender API. В расширение передаются колбэки, через которые можно настроить само расширение и управлять поведением Burp.
Burp написан на Java, поэтому интерфейсы расширения тебе придется писать на компонентах библиотеки Swing. От расширений с интерфейсом Burp ждет стандартный объект JPanel, к которому прикреплены все остальные элементы. Получается панель, на которой расположены другие панели и лейауты (это нужно для правильного позиционирования элементов), а на них — конечные элементы вроде текстовых полей (JTextField) и кнопок (JButton).
www
В статье интерфейс описан кодом. Если хочешь переделать интерфейс для себя, используй Apache NetBeans. IDE полностью бесплатная и кросс‑платформенная. С ее помощью ты сможешь мышкой накидать интерфейс любой сложности. После возьми исходный код интерфейса и по аналогии с кодом расширения перенеси его на Jython для использования в расширениях Burp.
Код интерфейса помести в файл ui..
# -*- coding: utf-8 -*-# Заранее импортирую все элементы, которые потребуются для конечного расширения, а не только нужные сейчасfrom javax.swing import ( JPanel, JLabel, JTextField, JButton, BoxLayout, BorderFactory, Box, JScrollPane, JTable, ListSelectionModel, SwingUtilities, JComboBox, JOptionPane)from javax.swing.table import DefaultTableModelfrom java.awt import GridBagLayout, GridBagConstraints, Insets, Dimension, BorderLayout, Colorfrom java.net import URLclass AppConfigPanel(object): # При инициализации сохрани ссылки на важные части расширения для доступа к ним. Client и store определим позже, пока укажи, что они могут быть None def __init__(self, callbacks, client = None, store = None): # Колбэки API Burp self._callbacks = callbacks # Через client будем передавать объект API Acunetix для прямых вызовов self.client = client # Объект с данными, которые необходимо хранить между запусками 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_panel = JPanel(GridBagLayout()) api_panel.setBorder(BorderFactory.createTitledBorder("API Settings")) gbc = GridBagConstraints() gbc.insets = Insets(6, 6, 6, 6) gbc.anchor = GridBagConstraints.WEST gbc.gridx = 0 gbc.gridy = 0 gbc.weightx = 0 gbc.fill = GridBagConstraints.NONE 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) 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)) # Создаем кнопку, указав функцию, обрабатывающую событие клика. actionPerformed — основное событие для элемента. Для кнопки это клик 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.weightx = 0 gbc.fill = GridBagConstraints.NONE gbc.anchor = GridBagConstraints.EAST 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 при нажатии на Check def on_check_connection(self, event): pass # Функция сохранения кредов при нажатии на Save def on_save(self, event): passПервый запуск расширения
В Burp открой вкладку Extensions → Extensions Settings. Найди Python environment, убедись, что указан путь к Jython. Если Jython не установлен, скачай Jython Standalone последней версии и укажи путь к этому файлу.
Продолжение доступно только участникам
Материалы из последних выпусков становятся доступны по отдельности только через два месяца после публикации. Чтобы продолжить чтение, необходимо стать участником сообщества «Xakep.ru».
Присоединяйся к сообществу «Xakep.ru»!
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
