Burp Suite Extension Development Guide

2023-09-11 12:03:07

Burp Suite是什麼?

Burp Suite是一款Web應用程式滲透測試工具,可以幫助使用者發現和利用Web應用程式中的漏洞,提高滲透測試的效率和精度。

Web應用程式最常用的傳輸資料的協定就是HTTP/HTTPS,所以我們將從HTTP協定的資料格式開始介紹。

HTTP/HTTPS協定內容簡要劃分

Burp中最為核心的物件就是HTTP封包,我們的所有操作、各種API介面都是圍繞HTTP封包展開的。下圖對HTTP封包進行劃分:

資料對映表:

外掛能對HTTP封包做的操作無非「增刪查改」四種,下面這段程式碼對常用操作均進行了演示。
https://github.com/bit4woo/burp-api-drops/blob/master/src/burp/Lession5.java

請求包:

  • header獲取刪除新增修改

  • body獲取修改

  • parameter獲取刪除新增修改

  • 傳送一個新的請求

響應包:

  • header獲取刪除新增修改

  • body獲取修改

httpService:

  • host獲取修改
  • port獲取修改
  • protocol獲取修改

外掛的呼叫原理介紹

以下全文將以Java語言的視角展開,

  1. 外掛的總入口是BurpExtender類,該類是必須得實現IBurpExtender介面;

  2. 當實現IBurpExtender介面後,會要求重寫registerExtenderCallbacks()方法,而該函數的作用就是註冊回撥,當自己的寫的外掛需要哪些API支援的時候,都需要在該函數中進行註冊,這樣burp在執行的時候,會讀取自己寫的外掛程式碼是否有回撥註冊,如果有就進行執行相應程式碼。

基本邏輯流程如下:
BurpExtender類————> registerExtenderCallbacks()方法 ————> 呼叫Callbacks.registerXxx介面名稱(this) ————> 去執行註冊介面的方法

Burp Suite的API的簡要劃分

Burp Suite 提供了豐富的外掛介面,可以讓開發者編寫自定義外掛,擴充套件 Burp Suite 的功能。 最新版本的APIs還是挺多的,想要高效的編寫出外掛,還是得了解你的需求,根據需求去匹配使用相關介面,下面我列舉一些常用的 Burp Suite 外掛介面類:

  • IBurpExtender 介面:該介面用於定義 Burp Suite 外掛的入口點,即外掛的主類。在該介面的 registerExtenderCallbacks 方法中,開發者可以註冊其他外掛介面類和事件監聽器。

  • IExtensionStateListener 介面:該介面用於定義外掛狀態的變化監聽器。開發者可以通過實現該介面,監視外掛的啟動、停止和解除安裝等事件,並在這些事件發生時執行自定義的操作。

  • IHttpListener 介面:該介面用於定義 HTTP 攔截器。通過實現該介面,開發者可以在 Burp Suite 中攔截 HTTP 請求和響應,並實現自定義的處理邏輯,例如修改請求或響應、分析引數等。

  • IScannerCheck 介面:該介面用於定義漏洞掃描器。通過實現該介面,開發者可以編寫自定義的漏洞檢測邏輯,並將其整合到 Burp Suite 的漏洞掃描器中,從而提高漏洞檢測的效率和精度。

  • IIntruderPayloadGenerator 介面:該介面用於定義 Intruder 負載生成器。通過實現該介面,開發者可以編寫自定義的負載生成邏輯,並將其整合到 Burp Suite 的 Intruder 工具中,用於進行爆破和暴力破解等攻擊。

  • IContextMenuFactory 介面:該介面用於定義右鍵選單工廠。通過實現該介面,開發者可以向 Burp Suite 的右鍵選單中新增自定義的選單項,並實現選單項的點選事件。

  • IMessageEditorTabFactory 介面:該介面用於定義訊息編輯器索引標籤工廠。通過實現該介面,開發者可以向 Burp Suite 的訊息編輯器中新增自定義的索引標籤,並實現索引標籤的內容顯示和編輯功能。

開發流程簡介

大體步驟如下:

  • 建立專案、匯入jar包
    開發外掛有些規定需要記住,目錄名必須設定成burp目錄,類名即檔名必須是BurpExtender。
    匯入burp的介面jar包有多種方式,我下面以maven的方式舉例:
<dependencies>
    <!-- https://mvnrepository.com/artifact/net.portswigger.burp.extender/burp-extender-api -->
    <dependency>
        <groupId>net.portswigger.burp.extender</groupId>
        <artifactId>burp-extender-api</artifactId>
        <version>1.7.22</version>
    </dependency>
</dependencies>
  • 開發功能模組
  • 編譯打包
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
            </configuration>
        </plugin>
    </plugins>
</build>

開啟終端,輸入打包jar包命令:

mvn clean install
  • Burp Suite匯入剛編譯好的jar包進行測試、使用。

案例1 —— 對HTTP\HTTPS資料流處理

如果想要實現對HTTP\HTTPS資料的操作,那麼就需要了解IHttpListener介面中的processHttpMessage方法

Burp的IHttpListener介面用於擴充套件Burp Suite的HTTP攔截器,通過實現該介面可以在HTTP請求和響應被攔截時執行一些自定義的操作。

IHttpListener介面中的processHttpMessage方法用於處理攔截到的HTTP請求和響應,其方法簽名如下:

void processHttpMessage(int toolFlag, boolean messageIsRequest, IHttpRequestResponse messageInfo);

其中:

  • toolFlag 引數表示觸發攔截的工具,可以是 Burp Suite 中的 Proxy、Scanner、Spider 等工具;
  • messageIsRequest 引數表示攔截到的訊息是請求還是響應;
    • 當 messageIsRequest 引數為 true 時,表示攔截的是請求內容
    • 當 messageIsRequest 引數為 false 時,表示攔截的是響應內容
  • messageInfo 引數表示攔截到的HTTP請求/響應的詳細資訊,包括請求/響應頭、請求/響應體、請求/響應的地址、協定版本等等。

在實現IHttpListener介面時,通常會在processHttpMessage方法中編寫自定義的處理邏輯,比如對請求/響應進行修改、分析請求/響應的引數等,從而實現自定義的HTTP攔截功能。

總之,通過實現IHttpListener介面,並在其中實現processHttpMessage方法,可以為Burp Suite的HTTP攔截器新增自定義的處理邏輯,從而提高滲透測試的效率和精度。


下面主要講解一個通過對HTTP\HTTPS資料流的攔截、處理,在head新增 X-forwarded-for 一個請求頭,偽造使用者端IP測試的案例。

可以配合線上工具,進行測試:
https://uutool.cn/mock/
主要用來模擬伺服器端收到請求後,檢視請求內容。


code:

package burp;

import burp.IBurpExtender;
import burp.IBurpExtenderCallbacks;
import burp.IExtensionHelpers;

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.List;

public class BurpExtender implements IBurpExtender, IHttpListener, IExtensionStateListener {
    private IExtensionHelpers helpers;
    private IBurpExtenderCallbacks callbacks;
    private PrintWriter stdout;
    private PrintWriter stderr;

    @Override
    public void registerExtenderCallbacks(IBurpExtenderCallbacks iBurpExtenderCallbacks) {
        this.callbacks = iBurpExtenderCallbacks;
        //設定外掛名字
        callbacks.setExtensionName("Demo1");
        this.helpers = callbacks.getHelpers();

        // 一定要註冊監聽器,不然下面的函數無法生效
        callbacks.registerHttpListener(this);
        callbacks.registerExtensionStateListener(this);

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

        // 列印資訊在UI控制檯頁面 Output and Errors
        stdout.println("Hello Demo1 Extender !");
        stderr.println("Error Info Show.");
    }


    @Override
    public void processHttpMessage(int i, boolean b, IHttpRequestResponse iHttpRequestResponse) {
        //設定http監聽模組為Burpsuiteproxy模組
        if (i == IBurpExtenderCallbacks.TOOL_PROXY) {

            if (b) { //對請求包進行處理

                //獲取協定 埠 和主機名
                IHttpService service = iHttpRequestResponse.getHttpService();
                stdout.println("=============***============= Protocol host port :" + service.getProtocol() + " " + service.getHost() + " " + service.getPort());

                //對訊息體進行解析,messageInfo是整個HTTP請求和響應訊息體的總和,各種HTTP相關資訊的獲取都來自於它,HTTP流量的修改都是圍繞它進行的。
                IRequestInfo analyzeRequest = helpers.analyzeRequest(iHttpRequestResponse);

                // 獲取引數
                List<IParameter> parameList = analyzeRequest.getParameters();
                //獲取引數 、遍歷引數
                for (IParameter para : parameList) {
                    //獲取引數
                    String key = para.getName();
                    //獲取引數值(value)
                    String value = para.getValue();
                    int type = para.getType();
                    stdout.println("parameters key value type :" + key + " " + value + " " + type);
                }

                // 更新攔截處理後的資料  +
                IRequestInfo analyIRequestInfo = helpers.analyzeRequest(iHttpRequestResponse);
                //獲取整個請求資料內容
                String request = null;
                try {
                    request = new String(iHttpRequestResponse.getRequest(), "UTF-8");
                } catch (UnsupportedEncodingException e) {
                    throw new RuntimeException(e);
                }

                //通過上面的analyIRequestInfo得到請求封包體(body)的起始偏移
                int bodyOffset = analyIRequestInfo.getBodyOffset();

                //通過起始偏移點得到請求封包體(body)的內容
                byte[] body = null;
                try {
                    body = request.substring(bodyOffset).getBytes("UTF-8");
                } catch (UnsupportedEncodingException e) {
                    throw new RuntimeException(e);
                }

                //通過上面的analyIRequestInfo得到請求資料的請求頭列表
                List<String> headers = analyIRequestInfo.getHeaders();//獲取http請求頭的資訊

                //生成X-Forwarded-For請求頭 包括請求頭的key(X-Forwarded-For)及隨機生成的IP
                String xForwardFor = "X-Forwarded-For: " + RandomIP.getRandomIP();

                //新增header頭, 新增x-forwarded-for請求頭,偽造使用者端IP測試
                headers.add(xForwardFor);
                headers.add("Test-Head: I am a test data!!!");

                //遍歷請求頭
                for (String header : headers) {
                    stdout.println("header : " + header);
                }

                //重新構造了請求資料
                byte[] newRequest = helpers.buildHttpMessage(headers, body);

                //列印出重新構造的請求資料測試
                stdout.println(helpers.analyzeRequest(newRequest).getHeaders());

                //重新構造的新請求資料, 因為裡面已經包含有我們新增的X-Forward-For
                iHttpRequestResponse.setRequest(newRequest);

            } else {//對響應包進行處理
                // Response
                IResponseInfo analyzeResponse = helpers.analyzeResponse(iHttpRequestResponse.getResponse());
                //獲取響應碼資訊
                short statusCode = analyzeResponse.getStatusCode();
                stdout.println("status= " + statusCode);

                //獲取響應頭資訊
                List<String> headers = analyzeResponse.getHeaders();
                for (String header : headers) {
                    stdout.println("header:" + header);
                }

                // 獲取響應資訊
                String resp = new String(iHttpRequestResponse.getResponse());
                int bodyOffset = analyzeResponse.getBodyOffset();
                String body = resp.substring(bodyOffset);
                stdout.println("response body=" + body);
            }
        }
    }

    // 用於註冊外掛狀態監聽,在解除安裝外掛時會執行
    public void extensionUnloaded() {
        String fileName = "D:\\testData\\example.txt";
        String fileContent = "The Demo1 extension removed!";

        try {
            FileWriter fileWriter = new FileWriter(fileName);
            fileWriter.write(fileContent);
            fileWriter.close();
            System.out.println("Successfully wrote to the file.");
        } catch (IOException e) {
            System.out.println("An error occurred.");
            e.printStackTrace();
        }
    }
}

案例2 —— 高亮、新標籤介面

高亮非常簡單:

iHttpRequestResponse.setHighlight("red");
iHttpRequestResponse.setHighlight("yellow");
iHttpRequestResponse.setHighlight("blue");
// ...

新標籤介面:
如果想要實現在請求和響應介面加一個新分頁來展示自定義資訊,那麼就需要了解IMessageEditorTab介面setMessage方法
Burp的IMessageEditorTab介面是用於擴充套件 Burp Suite 的請求/響應編輯器的一種方式,通過實現該介面可以向編輯器中新增自定義的分頁,實現自定義的請求/響應內容編輯功能。

IMessageEditorTab 介面中的setMessage方法用於設定當前編輯器中顯示的請求/響應內容。該方法的簽名如下:

void setMessage(byte[] message, boolean isRequest);

其中:

  • message 引數表示要設定的請求/響應內容的位元組陣列;
  • isRequest 引數表示設定的內容是請求還是響應,
    • 當 isRequest 引數為 true 時,表示設定的是請求內容
    • 當 isRequest 引數為 false 時,表示設定的是響應內容

在實現 IMessageEditorTab 介面時,通常會在自定義的分頁中新增一個編輯器元件(如 TextArea),並在 setMessage 方法中將請求/響應內容設定到該元件中,從而在分頁中顯示請求/響應內容。同時,還可以在自定義的分頁中新增一些其他的元件,比如按鈕、核取方塊等,實現一些自定義的功能,如傳送請求、解析響應等。

總之,通過實現 IMessageEditorTab 介面,並在其中實現 setMessage 方法,可以為 Burp Suite 的請求/響應編輯器新增自定義的分頁及編輯功能,從而提高滲透測試的效率和精度。

外掛的斷點偵錯

  1. 通過命令開啟Burp Suite;
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -jar [You path]\burpsuite_community.jar
  1. 在程式碼裡面打上斷點;

  2. 設定一個Remote JVM Debug

  1. 載入上外掛,開始偵錯。

UI介面

感覺UI這塊內容不少,我後期單獨寫一篇新部落格吧。可以點贊支援我加速。

Reference