<span id="7ztzv"></span>
<sub id="7ztzv"></sub>

<span id="7ztzv"></span><form id="7ztzv"></form>

<span id="7ztzv"></span>

        <address id="7ztzv"></address>

            原文地址:http://drops.wooyun.org/tools/16261

            此文接著 《BurpSuite插件開發指南之 Java 篇》 。在此篇中將會介紹如何使用 Python編程語言 開發 BurpSuite 的插件。

            《BurpSuite 插件開發指南》系列文章如下:

            注:此系列文章是筆者利用業余時間所寫,如有錯誤,望讀者們及時指正,另外此系列文章屬于入門級別的科普文,目的是普及Burp插件的編寫技術。

            0x00 Jython 簡介


            BurpSuite 是使用 Java 編程語言編寫的,所以想要使用 Python 編程語言開發其插件,就必須借助于 Jython。Jython 本質上是一個 Java 應用程序,它允許 coder 們使用 Java 代碼調用 Python 庫反之,也可以使用 Python 調用 Java 的庫。

            有關 Jython 的詳細使用,請讀者參閱 Jython 官網的用戶手冊 和 相關 doc。

            類似于 Jython 的 Project 還有 JRuby ,并且 Burp 也支持 ruby 編寫插件,但是無論是用 Python 還是 Ruby 編寫的插件,在執行效率方面遠遠不如原生的 Java 高,所以筆者還是建議使用 Java 編寫插件。

            0x01 Python 編寫 Burp 插件


            Python 編寫 Burp 插件輔助工具

            Jython Burp API

            使用 Python 編寫 Burp 插件的時候會遇到各種瑣碎的麻煩。最主要的原因在于,Java 與 Python 編程語言特性上的差異,如:強弱類型,數據類型等以及 Jython 本身與 CPython 的一些不同(具體請看 Jython 官網文檔)。不過在熟悉了 Burp 接口和基本的編寫套路后,一切都會變得很簡單。

            國外有牛人編寫了一個 Jython Burp API,封裝了一些功能,可以很方便的獲取 Burp 數據并且可以調試 Jython 代碼。具體使用說明請看 Git 文檔。

            Jython Burp API Git 地址

            注:

            加載 Jython Burp API 時會出現 sys 模塊 PS1 PS2 未定義的錯誤。后來 Google 后發現這個是 Jython 本身的一個 Bug,不過官方已有 Issue 會在后續的版本中進行修復。

            解決此錯誤的方法如下:

            編輯 jython-burp-api/Lib/gds/burp/console/console.py 文件,將 25 26 行直接改為如下代碼即可:

            Python 編寫 Burp 插件 注意事項

            Python 導入相關庫

            Python 實現接口的方式與 Python 中類的繼承寫法一樣。只是讀者要注意的是:在 Java 中,類是單繼承的,一個子類直接繼承的父類只能有一個,可以通過間接的方式實現多繼承,但 Python 中是可以直接繼承多個類。

            Python 編寫 Burp 插件的示例代碼如下:

            #!python
            #!/usr/bin/env python
            # -*- coding:utf-8 -*-
            
            '''
                BurpSuite插件開發指南之 Python 篇
            '''
            
            # 導入 burp 接口
            from burp import IBurpExtender, IProxyListener
            
            # 導入 Java 庫
            from java.net import URL
            
            # 按照 Python 類繼承的方式實現相關接口
            
            class BurpExtender(IBurpExtender, IProxyListener):
            
                def registerExtenderCallbacks(self, callbacks):
                    # code here
                    pass
            
                def processProxyMessage(self, messageIsRequest, message):
                    pass
            

            PermGen space 錯誤

            在 Burp 加載 Python 編寫的插件時,會經常遇到如下圖所示的錯誤:

            Burp 官網也給出了解決 java.lang.OutOfMemoryError: PermGen space 錯誤的辦法。
            在啟動 Burp 時設置 JVM 的 XX 參數即可,如: java -XX:MaxPermSize=1G -jar burp.jar

            不過即使是使用上述參數啟動 Burp,在多次加載 Python 編寫的插件后,還是會出現 Burp 卡死的現象。

            Burp 加載 Python 編寫的插件的方法

            Python 編寫的插件文件后綴為 py 文件,不能由 Burp 直接加載,所以在加載前需要先設置 Jython 的路徑。

            在 Jython 官方下載頁面選擇 Jython 獨立 jar 包。下載好后,按照下圖所示設置:

            加載 Python 插件的方式如下圖:

            Python 編寫 Burp GUI 插件實例

            本實例使用 Python 調用 Java 的 swing 圖形控件庫并綁定相關事件。最終結果如下圖:

            示例代碼如下:

            #!python
            #!/usr/bin/env python
            # -*- coding:utf-8 -*-
            
            '''
                BurpSuite插件開發指南之 Python 篇
            '''
            
            # 導入 burp 接口
            from burp import IBurpExtender, ITab
            
            # 導入 Java 庫
            
            from javax.swing import JPanel
            from javax.swing import JButton
            
            class BurpExtender(IBurpExtender, ITab):
            
                def registerExtenderCallbacks(self, callbacks):
            
                    self._cb = callbacks
                    self._hp = callbacks.getHelpers()
            
                    self._cb.setExtensionName('BurpPython')
                    print 'hello burp!'
            
                    self.mainPanel = JPanel()
            
                    # 初始化一個 JButton 并綁定單擊事件
                    self.testBtn = JButton('Click Me!', actionPerformed=self.testBtn_onClick)
            
                    self.mainPanel.add(self.testBtn)
            
                    self._cb.customizeUiComponent(self.mainPanel)
                    self._cb.addSuiteTab(self)
            
                def testBtn_onClick(self, event):
                    print 'testBtn clicked!'
            
                # 實現 ITab 接口的 getTabCaption() 方法
                def getTabCaption(self):
                    return 'BurpPython'
            
                def getUiComponent(self):
                    return self.mainPanel
            

            相比較 Java 編寫 GUI 插件,如果要實現比較復雜的 GUI,使用 Python 編寫還是比較輕松的事情,不用關心太多的參數及參數類型,綁定事件也更加簡單。

            0x02 Python 編寫 Burp 插件實例之 工具集成菜單


            本小節會使用一個工具集成右鍵菜單的 Burp 插件舉例說明 Python 編寫 Burp 插件的套路。

            注:
            讀者可以在此插件的基礎上修改為任何你想要執行的命令或程序 并指定不同的參數,如:使用 請求原始數據配合 SQLMap 進行SQLi 測試。另外在使用該插件過程時,可以將輸出設置為系統控制臺輸出,如下圖所示:

            代碼和配置文件內容如下:

            #!python
            #!/usr/bin/env python
            # -*- coding:utf-8 -*-
            
            '''
                BurpSuite插件開發指南之 Python 篇
            '''
            
            import os
            import sys
            import json
            import thread
            import traceback
            
            # 導入 burp 相關接口
            from burp import IBurpExtender
            from burp import IContextMenuFactory
            
            # 導入 Java 相關庫
            from javax.swing import JMenu
            from javax.swing import JMenuItem
            
            reload(sys)
            sys.setdefaultencoding('utf-8')
            
            
            class BurpExtender(IBurpExtender, IContextMenuFactory):
            
                def registerExtenderCallbacks(self, callbacks):
            
                    self.messages = []
                    self.menusConf = {}
            
                    self.callbacks = callbacks
                    self.helpers = callbacks.getHelpers()
            
                    self.callbacks.issueAlert('toolKits is ready ...')
                    self.callbacks.setExtensionName('toolKits')
                    self.callbacks.registerContextMenuFactory(self)
            
                def loadMenus(self):
                    self.menus = []
                    self.mainMenu = JMenu("toolKits")
                    self.menus.append(self.mainMenu)
            
                    try:
                        with open('toolKits/toolKits.conf') as fp:
                            self.menusConf = json.loads(fp.read())
                    except:
                        self.mainMenu.add(JMenuItem(u'加載配置出錯!'))
                    else:
                        for tool in self.menusConf:
                            # 遍歷配置,創建子菜單項,并添加事件綁定
                            menu = JMenuItem(tool['name'],
                                             None,
                                             actionPerformed=lambda x: self.eventHandler(x))
                            self.mainMenu.add(menu)
            
                def createMenuItems(self, invocation):
            
                    # 將加載的過程放在 createMenuItems 接口方法中
                    # 可以在不重新加載該插件的情況下,動態加載配置
                    self.loadMenus()
            
                    self.messages = invocation.getSelectedMessages()
            
                    # 只在指定的 Burp 標簽的右鍵菜單顯示
                    # ctx = invocation.getInvocationContext()
                    # if not ctx in [0, 1, 2, 3, 4, 5, 6]:
                    #     return None
            
                    return self.menus if self.menus else None
            
                def eventHandler(self, x):
                    '''
                        通過獲取當前點擊的子菜單的 text 屬性,確定當前需要執行的 command
                        啟動線程執行命令
                    '''
            
                    try:
                        menuName = x.getSource().text
                        for tool in self.menusConf:
                            if tool['name'] == menuName:
                                commands = [tool['command'].replace(
                                    '{#}', val) for val in self.getValue(tool['param'])]
                                [thread.start_new_thread(self.execCommand, (command,))
                                 for command in commands]
                    except:
                        print traceback.print_exc()
            
                def getHost(self, message):
                    return message.getHttpService().getHost()
            
                # 獲取 Url 注意此處若通過 meesage.getRequest() 是獲取不到的
                def getUrl(self, meesage):
                    return str(self.helpers.analyzeRequest(meesage).getUrl())
            
                # 通過配置中的 參數值 分別獲取不同值
                def getValue(self, paramType):
                    if paramType == 'host':
                        return set([self.getHost(message) for message in self.messages])
                    elif paramType == 'url':
                        return set([self.getUrl(message) for message in self.messages])
            
                # 執行命令處理方法
                def execCommand(self, command):
                    try:
                        print '[I] 正在執行命令: {command}, 請稍后...'.format(command=command)
                        res = '---------- 命令 {command} 執行結果: ---------- {res}'.format(
                            command=command, res=os.popen(command).read())
                        print res
                    except:
                        print traceback.print_exc()
            

            該插件有一個配置文件,格式為 JSON 格式(Jython 2.7.0 不支持 yaml):

            #!javascript
            [{
              "name": "Nmap 掃描端口",
              "param": "host",
              "command": "nmap -T4 {#}"
            },
            {
              "name": "SQLMap 檢查注入",
              "param": "url",
              "command": "python /opt/sqlmap/sqlmap.py -u {#} --dbs"
            }]
            

            <span id="7ztzv"></span>
            <sub id="7ztzv"></sub>

            <span id="7ztzv"></span><form id="7ztzv"></form>

            <span id="7ztzv"></span>

                  <address id="7ztzv"></address>

                      亚洲欧美在线