# -*- coding: utf-8 -*-
from burp import IBurpExtender, IHttpListener, ITab
from javax.swing import (JPanel, JButton, JTextField, JLabel, JComboBox,
JTable, JScrollPane, JTextArea, JSplitPane,
KeyStroke, AbstractAction, DefaultCellEditor)
from javax.swing.table import DefaultTableModel
from java.awt import BorderLayout, FlowLayout, Dimension
from java.awt.event import ActionListener
class DeleteAction(AbstractAction):
def __init__(self, outer):
self.outer = outer
def actionPerformed(self, event):
self.outer.delete_keyword(None)
class BurpExtender(IBurpExtender, IHttpListener, ITab):
def registerExtenderCallbacks(self, callbacks):
self.callbacks = callbacks
self.helpers = callbacks.getHelpers()
callbacks.setExtensionName("Keyword Highlighter Advanced")
callbacks.registerHttpListener(self)
self.init_gui()
callbacks.addSuiteTab(self)
print("[+] Keyword Highlighter Advanced loaded.")
def init_gui(self):
self.panel = JPanel(BorderLayout())
# 입력 패널 (Scope / Color / Keyword / Add / Delete)
self.input_panel = JPanel(FlowLayout())
self.scope_selector = JComboBox(["Both", "Request", "Response"])
self.color_selector = JComboBox(["red", "orange", "yellow", "green", "cyan", "blue", "pink", "magenta", "gray"])
self.keyword_field = JTextField(15)
self.add_button = JButton("Add", actionPerformed=self.add_keyword)
self.delete_button = JButton("Delete Selected", actionPerformed=self.delete_keyword)
self.input_panel.add(JLabel("Scope:"))
self.input_panel.add(self.scope_selector)
self.input_panel.add(JLabel("Color:"))
self.input_panel.add(self.color_selector)
self.input_panel.add(JLabel("Keyword:"))
self.input_panel.add(self.keyword_field)
self.input_panel.add(self.add_button)
self.input_panel.add(self.delete_button)
# 테이블 (Scope / Color / Keyword)
self.table_model = DefaultTableModel(["Scope", "Color", "Keyword"], 0)
self.table = JTable(self.table_model)
self.table.getColumnModel().getColumn(0).setCellEditor(DefaultCellEditor(JComboBox(["Both", "Request", "Response"])))
self.table.getColumnModel().getColumn(1).setCellEditor(DefaultCellEditor(JComboBox(["red", "orange", "yellow", "green", "cyan", "blue", "pink", "magenta", "gray"])))
# Delete 키 설정
self.table.getInputMap().put(KeyStroke.getKeyStroke("DELETE"), "delete")
self.table.getActionMap().put("delete", DeleteAction(self))
table_scroll = JScrollPane(self.table)
table_scroll.setPreferredSize(Dimension(500, 300))
# 왼쪽 패널 = 입력 + 테이블
self.left_panel = JPanel(BorderLayout())
self.left_panel.add(self.input_panel, BorderLayout.NORTH)
self.left_panel.add(table_scroll, BorderLayout.CENTER)
# 오른쪽 = Info + Clear 버튼
self.info_area = JTextArea(15, 40)
self.info_area.setEditable(False)
info_scroll = JScrollPane(self.info_area)
self.clear_button = JButton("Clear Info", actionPerformed=self.clear_info_area)
self.right_panel = JPanel(BorderLayout())
self.right_panel.add(info_scroll, BorderLayout.CENTER)
button_panel = JPanel(FlowLayout())
button_panel.add(self.clear_button)
self.right_panel.add(button_panel, BorderLayout.SOUTH)
# 좌우 화면 분할
self.split_pane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT, self.left_panel, self.right_panel)
self.split_pane.setResizeWeight(0.5) # 50:50 비율 유지
self.panel.add(self.split_pane, BorderLayout.CENTER)
def getTabCaption(self):
return "Keyword Highlighter"
def getUiComponent(self):
return self.panel
def add_keyword(self, event):
scope = self.scope_selector.getSelectedItem()
color = self.color_selector.getSelectedItem()
keyword = self.keyword_field.getText().strip()
if keyword:
self.table_model.addRow([scope, color, keyword])
def delete_keyword(self, event):
selected_row = self.table.getSelectedRow()
if selected_row != -1:
self.table_model.removeRow(selected_row)
def clear_info_area(self, event):
self.info_area.setText("")
def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo):
if toolFlag != self.callbacks.TOOL_PROXY:
return
try:
request_bytes = messageInfo.getRequest()
request_info = self.helpers.analyzeRequest(messageInfo)
request_url = str(request_info.getUrl())
request_body = request_bytes[request_info.getBodyOffset():].tostring()
request_str = request_url + " " + request_body.decode("utf-8", "ignore")
response_str = ""
headers = []
if messageInfo.getResponse() is not None:
response_bytes = messageInfo.getResponse()
response_info = self.helpers.analyzeResponse(response_bytes)
headers = response_info.getHeaders()
response_body = response_bytes[response_info.getBodyOffset():].tostring()
response_str = response_body.decode("utf-8", "ignore")
request_str = request_str.lower()
response_str = response_str.lower()
for row in range(self.table_model.getRowCount()):
scope = self.table_model.getValueAt(row, 0)
color = self.table_model.getValueAt(row, 1).lower()
keyword = self.table_model.getValueAt(row, 2).lower()
matched = False
if scope == "Request" and keyword in request_str:
matched = True
elif scope == "Response" and keyword in response_str:
matched = True
elif scope == "Both" and (keyword in request_str or keyword in response_str):
matched = True
if matched:
messageInfo.setHighlight(color)
print("[+] Highlight applied: '{}' in {} -> {}".format(keyword, scope, color))
break
# 헤더 출력 (Host 포함) – 매칭된 헤더가 있을 때만
if headers:
summary = []
for h in headers:
h_lower = h.lower()
if h_lower.startswith("server") or \
h_lower.startswith("set-cookie") or \
h_lower.startswith("authorization") or \
h_lower.startswith("cookie"):
summary.append(h)
if summary:
info = "[+] Info from response: {}\n".format(request_info.getUrl().toString())
info += "\n".join(summary) + "\n\n"
self.info_area.append(info)
except Exception as e:
print("[!] Error: {}".format(str(e)))