HTTP数据都是成对的,一个request对应一个response. 下面介绍怎么从数据流(回调方式)中处理这种数据。
我的目标是想对请求和响应体的内容进行搜索,如果搜索到指定内容,就报警提示。
但是Burp的插件开发,对接的接口是一个回调函数——processHttpMessage,它和HTTP的工作机制是一样的,发送一次请求,等待响应回来。一来一回。
如果以1作为request,2作为response. 那模拟数据传输的流程:
1212121212...
也可能是(考虑丢包或不稳定网络):
12121122...
代码思路:
- 在得到request的时候,先将request存储起来;
- 在得到response的时候,将上一次存储起来的request提取出来,一并将request和response一起存储,并传递出去;
- 将之前缓存的request删除掉,方便下次再次时候。
使用Burp插件开发code案例举例:
// 定义两个Map,一个存储单独的请求,一个存储请求-响应对
private Map<String, IHttpRequestResponse> requestCache = new HashMap<>();
private Map<String, Pair<IHttpRequestResponse, IHttpRequestResponse>> fullRequestResponse = new HashMap<>();
/**
* 功能: 监听HTTP proxy模块的流量,根据配置去做匹配,并高亮显示
*
* @param i —— 区分什么是什么Burp模块过来的数据;
* @param b —— boolean b(messageIsRequest)这个参数是用来判断当前传入的messageInfo对象是HTTP请求还是HTTP响应;
* @param iHttpRequestResponse —— 一个结构体,存储了请求和响应属性;
*/
@Override
public void processHttpMessage(int i, boolean b, IHttpRequestResponse iHttpRequestResponse) {
System.out.println(i);
//不同的toolFlag代表了不同的burp组件模块 https://portswigger.net/burp/extender/api/constant-values.html#burp.IBurpExtenderCallbacks
if (i == IBurpExtenderCallbacks.TOOL_PROXY) {
if (b) {
// 生成一个唯一的key,用于区分不同的请求
String key = Integer.toString(Utils.generateUID());
// 先缓存请求数据
requestCache.put(key, iHttpRequestResponse);
} else {
// 获取历史Key
// 获取所有 key-value 对的 Set 集合
Set<Map.Entry<String, IHttpRequestResponse>> entries = requestCache.entrySet();
// 非空判断
if (entries.isEmpty())
return;
String key = "";
// 遍历 Set 集合
for (Map.Entry<String, IHttpRequestResponse> entry : entries) {
key = entry.getKey();
}
// 获取对应的请求数据
IHttpRequestResponse request = requestCache.get(key);
if (request != null) {
// 构造请求-响应对,并存入fullRequestResponse
fullRequestResponse.put(key, new Pair<>(request, iHttpRequestResponse));
// 将成对的数据,传递到处理类进行数据处理
TODO
// 从请求缓存中移除,节省内存空间
requestCache.remove(key);
fullRequestResponse.remove(key);
}
}
}
}
缓存结构设计:
private Map<String, IHttpRequestResponse> requestCache = new HashMap<>();
private Map<String, Pair<IHttpRequestResponse, IHttpRequestResponse>> fullRequestResponse = new HashMap<>();
自定义一个Pair类:
public class Pair<F, S> {
public final F first;
public final S second;
public Pair(F first, S second) {
this.first = first;
this.second = second;
}
}
如果使用的是Java 9+版本, 官方库中提供了一个Pair通用类供使用, 使用效果和上面自定义类一样。