51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

【Python+Java】Burpsuite插件开发

如果你喜欢我的文章,欢迎关注公众号:安全女巫 转载请注明出处: https://mp.weixin.qq.com/s/xEKSXm2-fCHhyvZxrQUQvQ

burpsuite 最新版下载地址:

关注公众号回复burpsuite

0x1 前言

官方只支持三种语言:Java, Python & Ruby

因Burpsuite使用Java编写,推荐使用java语言编写插件。若想用Python或Ruby,需使用借助JPython或JRuby,以达到使用Java调用Python或Ruby库的目的。

可根据实际情况进行插件编写。



0x2 Burp Api接口

保存所有接口到本地

0x3 Java插件编写

java环境准备

安装jdk

安装idea

idea创建web项目,可做了解 https://blog.csdn.net/justdoit_potato/article/details/82994046

代码编写

创建项目时,File-New-Project-选择jdk版本,点击下一步.

如此,便成功创建项目
将burp导出的API文件Burp文件夹,复制至新建项目src目录,便于后续调用与编写。 新建BurpExtender.java文件,内容如下:

  
                
                  package burp;
                
                

                
                  
                  
                
                

                
                  import java.io.PrintWriter;
                
                

                
                  
                  
                
                

                
                  public class BurpExtender implements IBurpExtender
                
                

                
                  {
                
                

                
                      public void registerExtenderCallbacks (IBurpExtenderCallbacks callbacks)
                
                

                
                      {
                
                

                
                          // set our extension name
                
                

                
                          callbacks.setExtensionName("Hello world extension");
                
                

                
                  
                  
                
                

                
                          // obtain our output and error streams
                
                

                
                          PrintWriter stdout = new PrintWriter(callbacks.getStdout(), true);
                
                

                
                          PrintWriter stderr = new PrintWriter(callbacks.getStderr(), true);
                
                

                
                  
                  
                
                

                
                          // write a message to our output stream
                
                

                
                          stdout.println("Hello output");
                
                

                
                  
                  
                
                

                
                          // write a message to our error stream
                
                

                
                          stderr.println("Hello errors");
                
                

                
                  
                  
                
                

                
                          // write a message to the Burp alerts tab
                
                

                
                          callbacks.issueAlert("Hello alerts");
                
                

                
                  
                  
                
                

                
                          // throw an exception that will appear in our error stream
                
                

                
                          throw new RuntimeException("Hello exceptions");
                
                

                
                      }
                
                

                
                  }
                
  
            

项目打包

File-Project Structure-Artifacts

plugin_jar为jar包目录
Build-Build Artifacts

成功打包为jar

Burp插件导入

插件编写信息,成功展示

Burp调试

以上为简单插件编写,仅为输出展示可不进行调试。若是进行复杂插件编写,必不可少,需idea调试burp插件。具体配置如下: idea配置,监听8888端口

开启插件调试命令: java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8888 --illegal-access=permit -Dfile.encoding=utf-8 -javaagent:BurpSuiteLoader_v2021.8.jar -noverify -jar burpsuite_pro_v2021.8.jar
进行部署
可见,运行时,jdk版本与burp运行时jdk版本不一致。需将idea中jdk修改 File->Project Settings
此处点击,设置断点
设置成功后点击进行debug模式
此时,将burp插件进行加载,可见调试输出信息

Tips

Burp sdk与Idea jdk版本需保持一致,否则Burp调试异常 Burp版本最好使用社区版本,否则Burp调试无法开启

文章中,原本使用的中文破解版Burp,jdk 1.8,因遇到以上2问题,更换Burp为burpsuite_pro_2021.8、jdk 11

0x4 Python插件编写

python环境准备

安装python2 设置jpython路径

代码编写

将burp导出的API文件Burp文件夹,复制至python脚本同级目录,便于后续调用与编写。 python脚本 hello.py

  
                
                  from burp import IBurpExtender
                
                

                
                  from java.io import PrintWriter
                
                

                
                  from java.lang import RuntimeException
                
                

                
                  
                  
                
                

                
                  class BurpExtender(IBurpExtender):   
                
                

                
                      def
                  
                  
                  registerExtenderCallbacks(self, callbacks):
                
                

                
                          callbacks.setExtensionName("Hello world extension")
                
                

                
                          stdout = PrintWriter(callbacks.getStdout(), True)
                
                

                
                          stderr = PrintWriter(callbacks.getStderr(), True)
                
                

                
                          stdout.println("Hello output")
                
                

                
                          stderr.println("Hello errors")
                
                

                
                          callbacks.issueAlert("Hello alerts")
                
                

                
                          raise RuntimeException("Hello exception")
                
  
            

Burp插件导入

导入成功显示如下:


Burp调试

因Burp插件导入,只需写插件地址即可。若是地址py脚本内容变动,只需重新载入。正因为,

重新载入

点击反勾选按钮,再次点击进行勾选即可,可见更改已经生效。

其它样例

官方文档中提供了三种语言的插件简单样例,可根据自己需要选择。 https://portswigger.net/burp/extender#SampleExtensions

下面简单描述下,样例的加载与代码分析

事件监听

下载Event listeners的python代码,可见registerExtenderCallbacks用于注册以下监听

监听到的内容该如何展示,又展示在哪块?
当扫描任务发现漏洞时,会展示在Output处
当插件进行反勾选时,Output输出扩展未加载

报文重定向

下载TrafficRedirector的python代码,可见registerExtenderCallbacks用于注册HTTP监听 进行代码分析
载入插件后,访问host为127.0.0.1的url,发现已重定向到host2.example.org

自动记录日志

Custom Logger用于添加新选项卡以记录所有请求和响应。 下载Custom Logger的python代码,可见registerExtenderCallbacks用于注册HTTP监听

  
                
                  from burp import IBurpExtender
                
                

                
                  from burp import ITab
                
                

                
                  from burp import IHttpListener
                
                

                
                  from burp import IMessageEditorController
                
                

                
                  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
                
                

                
                  
                  
                
                

                
                  class BurpExtender(IBurpExtender, ITab, IHttpListener, IMessageEditorController, AbstractTableModel):
                
                

                
                      
                
                

                
                  
                  
                
                

                
                      def registerExtenderCallbacks(self, callbacks):
                
                

                
                          self._callbacks = callbacks
                
                

                
                          self._helpers = callbacks.getHelpers()
                
                

                
                          callbacks.setExtensionName("Custom logger")
                
                

                
                          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._requestViewer = callbacks.createMessageEditor(self, False)
                
                

                
                          self._responseViewer = callbacks.createMessageEditor(self, False)
                
                

                
                          tabs.addTab("Request", self._requestViewer.getComponent())
                
                

                
                          tabs.addTab("Response", self._responseViewer.getComponent())
                
                

                
                          self._splitpane.setRightComponent(tabs)
                
                

                
                          callbacks.customizeUiComponent(self._splitpane)
                
                

                
                          callbacks.customizeUiComponent(logTable)
                
                

                
                          callbacks.customizeUiComponent(scrollPane)
                
                

                
                          callbacks.customizeUiComponent(tabs)
                
                

                
                          callbacks.addSuiteTab(self)
                
                

                
                          callbacks.registerHttpListener(self)
                
                

                
                          return
                
                

                
                      
                
                

                
                      def getTabCaption(self):
                
                

                
                          return "Logger"
                
                

                
                      
                
                

                
                      def getUiComponent(self):
                
                

                
                          return self._splitpane
                
                

                
                      
                
                

                
                      def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo):
                
                

                
                          if messageIsRequest:
                
                

                
                              return
                
                

                
                          self._lock.acquire()
                
                

                
                          row = self._log.size()
                
                

                
                          self._log.add(LogEntry(toolFlag, self._callbacks.saveBuffersToTempFiles(messageInfo), self._helpers.analyzeRequest(messageInfo).getUrl()))
                
                

                
                          self.fireTableRowsInserted(row, row)
                
                

                
                          self._lock.release()
                
                

                
                      def getRowCount(self):
                
                

                
                          try:
                
                

                
                              return self._log.size()
                
                

                
                          except:
                
                

                
                              return 0
                
                

                
                      def getColumnCount(self):
                
                

                
                          return 2
                
                

                
                      def getColumnName(self, columnIndex):
                
                

                
                          if columnIndex == 0:
                
                

                
                              return "Tool"
                
                

                
                          if columnIndex == 1:
                
                

                
                              return "URL"
                
                

                
                          return ""
                
                

                
                      def getValueAt(self, rowIndex, columnIndex):
                
                

                
                          logEntry = self._log.get(rowIndex)
                
                

                
                          if columnIndex == 0:
                
                

                
                              return self._callbacks.getToolName(logEntry._tool)
                
                

                
                          if columnIndex == 1:
                
                

                
                              return logEntry._url.toString()
                
                

                
                          return ""
                
                

                
                      def getHttpService(self):
                
                

                
                          return self._currentlyDisplayedItem.getHttpService()
                
                

                
                      def getRequest(self):
                
                

                
                          return self._currentlyDisplayedItem.getRequest()
                
                

                
                      def getResponse(self):
                
                

                
                          return self._currentlyDisplayedItem.getResponse()
                
                

                
                  
                  
                
                

                
                  class Table(JTable):
                
                

                
                      def init(self, extender):
                
                

                
                          self._extender = extender
                
                

                
                          self.setModel(extender)
                
                

                
                      
                
                

                
                  
                  
                
                

                
                      def changeSelection(self, row, col, toggle, extend):
                
                

                
                          logEntry = self._extender._log.get(row)
                
                

                
                          self._extender._requestViewer.setMessage(logEntry._requestResponse.getRequest(), True)
                
                

                
                          self._extender._responseViewer.setMessage(logEntry._requestResponse.getResponse(), False)
                
                

                
                          self._extender._currentlyDisplayedItem = logEntry._requestResponse      
                
                

                
                          JTable.changeSelection(self, row, col, toggle, extend)
                
                

                
                  
                  
                
                

                
                  class LogEntry:
                
                

                
                      def init(self, tool, requestResponse, url):
                
                

                
                          self.tool = tool
                
                

                
                          self.requestResponse = requestResponse
                
                

                
                          self._url = url
                
  
            

代码分析:
目前仅对实例中4个进行代码分析,若后续自己有兴趣可参照写法进行插件编写~



本文作者: 公众号:安全女巫

本文为安全脉搏专栏作者发布,转载请注明: https://www.secpulse.com/archives/200103.html

赞(0)
未经允许不得转载:工具盒子 » 【Python+Java】Burpsuite插件开发