portswigger.
開發「屬於你本身」的Burp Suite插件html
環境問題
教程一大把,下載 jython
,而後 BURP
內選擇該環境便可java
抄一篇文章上的示例代碼,測試測試,看能不能跑通
好傢伙,直接來一個報錯,ImportError: cannot import name IBurpExtender
,導包錯誤。第一步就把我搞糊塗了,卒😭
解決辦法:
在插件入口 xxx.py
文件所在的同層級文件夾下新建一個 burp
文件夾,並在 Burp Suite
裏導出 API
文件到這個文件夾裏
python
沒學 java,連抄代碼頭都是大的github
所需文件已上傳至 Githubjson
#!/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)
#!/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 ""