參考文章
portswigger.
開發“屬於你自己”的Burp Suite插件
碰到的問題
-
環境問題
教程一大把,下載jython
,然后BURP
內選擇該環境即可 -
抄一篇文章上的示例代碼,測試測試,看能不能跑通
好家伙,直接來一個報錯,ImportError: cannot import name IBurpExtender
,導包錯誤。第一步就把我搞糊塗了,卒😭
解決辦法:
在插件入口xxx.py
文件所在的同層級文件夾下新建一個burp
文件夾,並在Burp Suite
里導出API
文件到這個文件夾里
-
沒學 java,連抄代碼頭都是大的
具體代碼
所需文件已上傳至 Github
- 1.0 版本:參數存到具體文件中
#!/usr/bin/env python
#coding=utf8
from burp import IBurpExtender
from burp import IHttpListener
from burp import IHttpRequestResponse
from burp import IResponseInfo
from burp import IProxyListener
#從burp中導入這幾個api模塊
import os
import re
import json
print("""
_____ _____ _ _ _
| __ \ / ____| | | | | |
| |__) __ _ _ __ __ _ ___| | ___ | | | ___ ___| |_ ___ _ __
| ___/ _` | '__/ _` / __| | / _ \| | |/ _ \/ __| __/ _ \| '__|
| | | (_| | | | (_| \__ | |___| (_) | | | __| (__| || (_) | |
|_| \__,_|_| \__,_|___/\_____\___/|_|_|\___|\___|\__\___/|_|
----- Contact me to improve it.A good idea is also important -----
_________________________ QQ:2309896932 __________________________
*************** https://www.cnblogs.com/wjrblogs/ ****************
""")
print "Files will be saved at " + os.getcwd()
def ReadFile(file):
with open(file,"a+") as f:
f.seek(0)
paras = f.read().split("\n")
return paras
def WriteToFile(file, paras):
for para in paras:
while '' in paras:
paras.remove('')
if paras == []:
os.remove(file) # 因為之前創建了一個文件,沒有參數時便刪除
else:
paras.sort()
with open(file,"w") as f:
for para in paras:
f.write(para+"\n")
class BurpExtender(IBurpExtender, IHttpListener, IHttpRequestResponse, IProxyListener):
'''
定義一個類,這個類繼承了IBurpExtender 使其成為一個插件模塊
繼承IHttpListener, 使其可以接受流經的request和response
繼承IHttpRequestResponse,使其可以獲得HTTP的詳細信息
繼承IProxyListener ,注冊成一個代理服務器!
'''
def registerExtenderCallbacks(self,callbacks):
self._callbacks = callbacks
self._helpers = callbacks.getHelpers()
self._callbacks.setExtensionName('ParasCollector') # 設定插件名字
callbacks.registerHttpListener(self) # 必須得注冊才具有功能
callbacks.registerProxyListener(self)
def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo):
if toolFlag == 4 or toolFlag == 64: # flag值代表着不同的組隊,此時是 proxy 和 repeater,表示被攔截的消息
if messageIsRequest: # 如果是一個請求
request = messageInfo.getRequest() # 獲得請求信息
analyzedRequest = self._helpers.analyzeRequest(request) # 解析
host = messageInfo.getHttpService().getHost() # 獲取域名
file = host+".txt"
lines = ReadFile(file)
paras1 = analyzedRequest.getParameters() # 獲取參數,包括 json 格式的數據
for para in paras1:
if para.getType() == para.PARAM_COOKIE:
temp = str(para.getName())
if temp not in lines: # 去重
lines.append(temp)
else:
temp = para.getName()
if temp not in lines:
lines.append(temp)
WriteToFile(file,lines)
if not messageIsRequest: # 如果是個響應
host = messageInfo.getHttpService().getHost() # 獲取域名
file = host+".txt"
lines = ReadFile(file)
response = messageInfo.getResponse() # 獲得響應信息
analyzedResponse = self._helpers.analyzeResponse(response) # 解析
# print analyzedResponse.getStatedMimeType()
if analyzedResponse.getInferredMimeType() == "JSON":
body = response[analyzedResponse.getBodyOffset():].tostring() # 獲取返回包
paras2 = json.loads(body).keys()
for para in paras2:
if para not in lines: # 去重
print str(para)
lines.append(str(para))
WriteToFile(file,lines)
- 2.0 版本:UI 可視化界面,所有參數存到 json 文件中
#!/usr/bin/env python
#coding=utf8
from burp import IBurpExtender
from burp import ITab
from burp import IHttpListener
from burp import IMessageEditorController
from burp import IHttpRequestResponse
from java.awt import Component;
from java.io import PrintWriter;
from java.util import ArrayList;
from java.util import List;
from javax.swing import JScrollPane;
from javax.swing import JSplitPane;
from javax.swing import JTabbedPane;
from javax.swing import JTable;
from javax.swing import SwingUtilities;
from javax.swing.table import AbstractTableModel;
from threading import Lock
import os
import json
print("""
_____ _____ _ _ _
| __ \ / ____| | | | | |
| |__) __ _ _ __ __ _ ___| | ___ | | | ___ ___| |_ ___ _ __
| ___/ _` | '__/ _` / __| | / _ \| | |/ _ \/ __| __/ _ \| '__|
| | | (_| | | | (_| \__ | |___| (_) | | | __| (__| || (_) | |
|_| \__,_|_| \__,_|___/\_____\___/|_|_|\___|\___|\__\___/|_|
----- Contact me to improve it.A good idea is also important -----
_________________________ QQ:2309896932 __________________________
*************** https://www.cnblogs.com/wjrblogs/ ****************
""")
print "Files will be saved at " + os.getcwd()
# 定義保存域名,參數,URL 的類
class LogEntry:
def __init__(self, host, paras):
self._host = host
self._count = len(paras)
self._paras = paras
class Table(JTable):
def __init__(self, extender):
self._extender = extender
self.setModel(extender)
def changeSelection(self, row, col, toggle, extend):
# show the log entry for the selected row
logEntry = self._extender._log.get(row)
self._extender._parasViewer.setText(logEntry._paras)
# self._extender._currentlyDisplayedItem = logEntry._requestResponse
JTable.changeSelection(self, row, col, toggle, extend)
class BurpExtender(IBurpExtender, IHttpListener, IHttpRequestResponse, ITab, IMessageEditorController, AbstractTableModel):
def registerExtenderCallbacks(self,callbacks):
self._callbacks = callbacks
self._helpers = callbacks.getHelpers()
self._callbacks.setExtensionName('ParasCollector')
self._log = ArrayList()
self._lock = Lock()
# 主窗口
self._splitpane = JSplitPane(JSplitPane.VERTICAL_SPLIT)
logTable = Table(self)
scrollPane = JScrollPane(logTable)
self._splitpane.setLeftComponent(scrollPane)
# 詳情
tabs = JTabbedPane()
self._parasViewer = callbacks.createTextEditor()
tabs.addTab("Paras",self._parasViewer.getComponent())
self._splitpane.setRightComponent(tabs)
# 定義 UI 組件
callbacks.customizeUiComponent(self._splitpane)
callbacks.customizeUiComponent(logTable)
callbacks.customizeUiComponent(scrollPane)
callbacks.customizeUiComponent(tabs)
# 將 UI 組件添加到 BURP 的 UI
callbacks.addSuiteTab(self)
# 注冊功能
callbacks.registerHttpListener(self)
return
def getTabCaption(self):
return "ParasCollector"
def getUiComponent(self):
return self._splitpane
def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo):
if toolFlag == 4:
# 讀 json 文件取得數據
self._lock.acquire() # 加鎖,反應會慢一點
try:
with open("allparas.json","r") as f:
allparas = json.loads(f.read())
except Exception as ex:
allparas = {}
print("shit!!\n")
print("%s"%ex)
host = messageInfo.getHttpService().getHost().encode('utf-8')
paras = allparas.get(host)
if paras == None:
paras = []
# print(type(paras))
if messageIsRequest: # 如果是一個請求
request = messageInfo.getRequest() # 獲得請求信息
analyzedRequest = self._helpers.analyzeRequest(request)
paras1 = analyzedRequest.getParameters()
for para in paras1:
temp = str(para.getName())
if temp not in paras: # 去重
paras.append(temp)
if paras !=[]:
paras.sort()
allparas[host] = paras
if not messageIsRequest: # 如果是個響應
response = messageInfo.getResponse() # 獲得響應信息
analyzedResponse = self._helpers.analyzeResponse(response)
if analyzedResponse.getInferredMimeType() == "JSON":
body = response[analyzedResponse.getBodyOffset():].tostring() # 獲取返回包
paras2 = json.loads(body).keys()
for para in paras2:
if para not in paras: # 去重
paras.append(str(para))
if paras !=[]:
paras.sort()
allparas[host] = paras
if allparas != {}:
with open("allparas.json","w+") as f:
json.dump(allparas, f, ensure_ascii=False)
row = self._log.size()
self._log.clear()
for host in allparas.keys():
self._log.add(LogEntry(host, '\n'.join(allparas.get(host))))
self.fireTableRowsInserted(row, row)
self._lock.release()
def getRowCount(self):
try:
return self._log.size()
except:
return 0
def getColumnCount(self):
return 1
def getColumnName(self, columnIndex):
if columnIndex == 0:
return "HOST"
return ""
def getValueAt(self, rowIndex, columnIndex):
logEntry = self._log.get(rowIndex)
if columnIndex == 0:
return logEntry._host
return ""