from burp import IBurpExtender, ITab
from java.awt import BorderLayout, Dimension
from javax.swing import JPanel, JTable, JScrollPane, JTextArea, JSplitPane, JButton, JComboBox
from javax.swing.table import DefaultTableModel
from javax.swing.event import ListSelectionListener
from java.util import Date
from java.text import SimpleDateFormat
from java.net import URL
class BurpExtender(IBurpExtender, ITab):
def registerExtenderCallbacks(self, callbacks):
self.callbacks = callbacks
self.helpers = callbacks.getHelpers()
callbacks.setExtensionName("Advanced Dir Index Checker")
# 데이터 저장
self._results = []
# GUI 초기화
self._panel = JPanel(BorderLayout())
# 테이블 설정
self._table_model = DefaultTableModel(["URL", "Status", "Indexed", "Checked Time"], 0)
self._table = JTable(self._table_model)
self._panel.add(JScrollPane(self._table), BorderLayout.CENTER)
# 상세보기 설정
self._request_viewer = JTextArea()
self._response_viewer = JTextArea()
self._request_viewer.setEditable(False)
self._response_viewer.setEditable(False)
viewers = JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
JScrollPane(self._request_viewer),
JScrollPane(self._response_viewer))
viewers.setDividerLocation(500)
viewers.setPreferredSize(Dimension(1000, 250))
self._panel.add(viewers, BorderLayout.SOUTH)
# 선택 리스너 추가
class RowSelectionListener(ListSelectionListener):
def valueChanged(inner_self, event):
if not event.getValueIsAdjusting():
self.updateRequestResponse()
self._table.getSelectionModel().addListSelectionListener(RowSelectionListener())
# 도메인 선택 및 스캔 버튼
self._host_selector = JComboBox()
self._scan_button = JButton("Start Scan", actionPerformed=self.scanHost)
top_panel = JPanel()
top_panel.add(self._host_selector)
top_panel.add(self._scan_button)
self._panel.add(top_panel, BorderLayout.NORTH)
callbacks.addSuiteTab(self)
self.populateHosts()
def getTabCaption(self):
return "Dir Index Checker"
def getUiComponent(self):
return self._panel
def populateHosts(self):
hosts = set()
for item in self.callbacks.getSiteMap(None):
try:
url = self.helpers.analyzeRequest(item).getUrl()
hosts.add(url.getHost())
except:
continue
self._host_selector.removeAllItems()
for host in sorted(hosts):
self._host_selector.addItem(host)
def scanHost(self, event):
host = self._host_selector.getSelectedItem()
if not host:
return
self._table_model.setRowCount(0)
self._results.clear()
scanned_urls = set()
for item in self.callbacks.getSiteMap(None):
url = self.helpers.analyzeRequest(item).getUrl()
if url.getHost() == host:
self.checkDirectoryIndex(url, item.getHttpService(), scanned_urls)
if not url.getPath().endswith("/"):
new_url = URL(url.toString() + "/")
self.checkDirectoryIndex(new_url, item.getHttpService(), scanned_urls)
def checkDirectoryIndex(self, url, service, scanned_urls):
if url.toString() in scanned_urls:
return
scanned_urls.add(url.toString())
request = self.helpers.buildHttpRequest(url)
response = self.callbacks.makeHttpRequest(service, request)
if response and response.getResponse():
analyzed_resp = self.helpers.analyzeResponse(response.getResponse())
body = self.helpers.bytesToString(response.getResponse()[analyzed_resp.getBodyOffset():]).lower()
indexed = "YES" if "index of" in body and "parent directory" in body else "NO"
status_code = analyzed_resp.getStatusCode()
time_checked = SimpleDateFormat("HH:mm:ss").format(Date())
self._table_model.addRow([url.toString(), status_code, indexed, time_checked])
self._results.append((request, response.getResponse()))
def updateRequestResponse(self):
row = self._table.getSelectedRow()
if row >= 0 and row < len(self._results):
request, response = self._results[row]
self._request_viewer.setText(self.helpers.bytesToString(request))
self._response_viewer.setText(self.helpers.bytesToString(response))