实现效果

自动修改请求数据包中的header、body和param,并修改响应包结果,以及单独发送新的请求。

涉及接口:

  • IHttpListener

实现代码

创建项目过程省略,直接从代码入手,使用旧版API开发。

package burp;

import java.util.Arrays;
import java.util.List;

public class BurpExtender implements IBurpExtender, IHttpListener {
    // 回调对象
    private IBurpExtenderCallbacks callbacks;
    // 辅助类,一般用于辅助分析数据包结构
    private IExtensionHelpers helpers;

    // 实现 IBurpExtender 接口函数
    @Override
    public void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks) {
        // 设置插件名字
        callbacks.setExtensionName("Demo");

        // callbacks到处都要用,搞成类变量
        this.callbacks = callbacks;

        // 辅助类,一般用于辅助分析数据包结构,类变量方便其他函数调用
        helpers = callbacks.getHelpers();

        // 注册 HttpListener ,必须要注册了burp有新消息才会通知你
        callbacks.registerHttpListener(this);

    }

    // 实现 IHttpListener 接口函数
    @Override
    public void processHttpMessage(int toolFlag, boolean messageIsRequest, IHttpRequestResponse messageInfo) {
        // 判断是哪个地方监听到的请求,此处为 Proxy 监听到的请求
        if (toolFlag == IBurpExtenderCallbacks.TOOL_PROXY) {
            // 判断是请求还是响应,True 就是请求数据包, False就是响应数据包
            if (messageIsRequest) {
                // 使用helper辅助分析请求
                IRequestInfo requestInfo = helpers.analyzeRequest(messageInfo.getRequest());
                // 获取header
                List<String> headers = requestInfo.getHeaders();
                // 获取param(包含了body中的)
                List<IParameter> parameters = requestInfo.getParameters();
                // 获取post raw body
                byte[] raw_body = Arrays.copyOfRange(messageInfo.getRequest(), requestInfo.getBodyOffset(), messageInfo.getRequest().length);

                // 更新header中的UA
                for (String header: headers) {
                    if (header.contains("User-Agent")){
                        int index = headers.indexOf(header);
                        headers.set(index, "User-Agent: TEST UA");
                    }
                }
                // 增加一条header
                headers.add("Add-Header: TEST ADD HEADER");
                // 更新整体header内容到请求体中
                byte[] newReq = helpers.buildHttpMessage(headers, raw_body);

                // 更新param: a=xxx
                IParameter parameter1 = helpers.buildParameter("a", "testUrlParam", IParameter.PARAM_URL);
                // 第一个参数为请求数据包,由于上方更新了请求数据包,所以这里用了更新后的newReq,具体可以下断点分析
                // 如果没有更新请求题,就用原始的 messageInfo.getRequest() 即可
                // helpers.updateParameter(messageInfo.getRequest(), parameter1); // 从原始数据包更新
                newReq = helpers.updateParameter(newReq, parameter1);
                // 增加一个参数到body
                IParameter parameter2 = helpers.buildParameter("testParam", "testValue", IParameter.PARAM_BODY);
                newReq = helpers.addParameter(newReq, parameter2);

                // 在当前请求基础上进行更新
                messageInfo.setRequest(newReq);
                // 单独发送一次篡改后的请求,增加Cookie特征
                newReq = helpers.addParameter(newReq, helpers.buildParameter("make", "request", IParameter.PARAM_COOKIE));
                IHttpRequestResponse response = callbacks.makeHttpRequest(messageInfo.getHttpService(), newReq);
                // callbacks.makeHttpRequest(messageInfo.getHttpService(), messageInfo.getRequest()); // 发送一个原始请求
                callbacks.printOutput(new String(response.getResponse()));
            } else {
                // 响应数据包
                // 使用helper辅助分析请求
                IResponseInfo requestInfo = helpers.analyzeResponse(messageInfo.getResponse());
                byte[] response = helpers.buildHttpMessage(requestInfo.getHeaders(), "modify response".getBytes());
                // 篡改
                messageInfo.setResponse(response);
            }
        }

    }
}

image-20240919上午82915588

实现测试

实际发送请求

curl -x http://127.0.0.1:8080 'http://127.0.0.1/?a=bbbb' -v

*   Trying 127.0.0.1:8080...
* Connected to 127.0.0.1 (127.0.0.1) port 8080
> GET http://127.0.0.1/?a=bbbb HTTP/1.1
> Host: 127.0.0.1
> User-Agent: curl/8.4.0
> Accept: */*
> Proxy-Connection: Keep-Alive
>

nc接收到的请求,可见已经被替换

GET /?a=testUrlParam HTTP/1.1
Host: 127.0.0.1
User-Agent: TEST UA
Accept: */*
Connection: close
Add-Header: TEST ADD HEADER
Content-Type: application/x-www-form-urlencoded
Content-Length: 19

testParam=testValue

得到的被替换响应内容

HTTP/1.0 200 OK
Server: SimpleHTTP/0.6 Python/3.7.9
Date: Wed, 18 Sep 2024 11:03:04 GMT
Content-type: text/html
Content-Length: 15
Last-Modified: Wed, 18 Sep 2024 10:44:55 GMT

modify response

需要注意的是,通过这种方法修改的请求响应,并不会在burp中显示数据包被替换过,如下:

image-20240919上午83120682

不存在如下的显示

image-20240919上午83349960


刚才除了直接篡改原始请求,还有通过makeHttpRequest发起新的请求,可在logger++中查看到该请求。

image-20240919上午84102053

扩展总结

  • 获取的header包括了请求和响应的第一行
  • 可通过callbacks提供的helper来辅助处理数据包,减少工作量
  • messageInfo除了获取、设置请求响应外,还可以控制Comment和高亮显示等。

参考

Copyright © d4m1ts 2023 all right reserved,powered by Gitbook该文章修订时间: 2024-09-28 14:11:01

results matching ""

    No results matching ""