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 ""