使用Bambda提升HTTP视角:Burp Suite自定义列实战指南
当你打开一个HTTP请求或响应时,本能地会寻找什么?可疑的参数名?CORS头部?还是请求来源或底层目的的线索?单个HTTP消息对每个查看者可能讲述不同的故事,但现代网站发送成千上万的请求,很容易忽略关键内容。为此,Burp Suite最近添加了对自定义列的支持,允许你个性化HTTP请求中哪些元素显示在表格中。
幕后,这些功能是通过称为"bambda"的代码片段实现的。这个功能强大到几乎令人不知所措,因此我们想分享研究团队创建的一些列示例,从简单实用到复杂不等。熟悉Java的读者可能会注意到我们没有刻意避免空指针异常——这是因为它们在行级别被处理,因此不会导致问题。
实用Bambda示例
请求来源页面
理解HTTP请求序列的流程对发现许多高级漏洞至关重要,这个示例使其稍微容易一些。
1
|
return requestResponse.request().headerValue("Referer");
|
响应来自哪个Web服务器?
也许我有一个针对特定代理的WAF绕过或缓存投毒攻击。
1
|
return requestResponse.response().headerValue("Server");
|
HTTP版本是什么?
我应该优先考虑请求走私还是竞争条件?我的10,000字目录暴力破解需要多长时间?
1
|
return requestResponse.request().httpVersion();
|
该请求指向的IP地址属于谁?
也许我应该改为攻击他们的基础设施。反向DNS是个美妙的东西。
1
2
|
String ipAddress = requestResponse.httpService().ipAddress();
return java.net.InetAddress.getByName(ipAddress).getCanonicalHostName();
|
这在范围内吗?
你不会想意外攻击范围之外的目标。
1
|
return requestResponse.request().isInScope();
|
该请求的GraphQL操作名是什么?
通常可以通过URL一眼看出请求的操作,但GraphQL是个不方便的例外。这个脚本解决了这个问题。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
String paramName = "operationName";
if(requestResponse.request().hasParameter(paramName, HttpParameterType.JSON)) {
return requestResponse.request().parameterValue(paramName, HttpParameterType.JSON);
}
String query = requestResponse.request().parameterValue("query", HttpParameterType.JSON);
if(query.contains("{") || query.contains("(")) {
var queryParts = query.split("\\{|\\(");
return queryParts[0];
}
return "";
|
Base64解码后的会话Cookie是什么样的?
像JWT这样的编码签名令牌无处不在,总是值得仔细查看。这个脚本需要根据你的目标进行定制。
1
2
3
4
5
6
7
8
9
10
11
12
|
if (!requestResponse.hasResponse()) {
return "";
}
var extract = "session";
var response = requestResponse.response();
var optionalCookie = response.cookies().stream().filter(cookie -> cookie.name().equals(extract)).findFirst();
if(optionalCookie.isEmpty()) return "";
var value = optionalCookie.get().value();
var parts = value.split("\\.");
if(parts.length != 3) return "";
var payload = parts[1];
return utilities().base64Utils().decode(payload, Base64DecodingOptions.URL);
|
哪些Cookie禁用了SameSite?
在策划CSRF或XSS攻击时,了解是否有Cookie禁用了SameSite很有用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
if(requestResponse.response() == null) {
return "";
}
if(!requestResponse.response().hasHeader("Set-Cookie")){
return "";
}
ArrayList<String> cookieNames = new ArrayList<>();
Pattern pattern = Pattern.compile("^ ([^=]+).+; SameSite=None", Pattern.CASE_INSENSITIVE);
List<HttpHeader> headers = requestResponse.response().headers();
for(HttpHeader header : headers) {
Matcher matcher = pattern.matcher(header.value());
while(matcher.find()) {
cookieNames.add(matcher.group(1));
}
}
return String.join(", ", cookieNames);
|
该响应是否有不良CSP?
这个自定义列Bambda允许你优先测试部署了不安全CSP指令(如unsafe-inline或unsafe-eval)的易受攻击端点。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
if(requestResponse.response() == null) {
return "";
}
if(!requestResponse.response().hasHeader("Content-Security-Policy")) {
return "No CSP";
}
String csp = requestResponse.response().headerValue("Content-Security-Policy");
ArrayList<String> vulnerableDirectives = new ArrayList<>();
String[] directivesToCheck = new String[]{"unsafe-inline", "unsafe-eval"};
for(int i=0;i<directivesToCheck.length;i++) {
if(csp.contains(directivesToCheck[i])) {
vulnerableDirectives.add(directivesToCheck[i]);
}
}
return String.join(", ", vulnerableDirectives);
|
通过排序自定义列进行优先级排序
你可以通过自定义列对整个表格进行排序,这有助于确定要优先处理哪些请求。随着时间的推移,我个人可能会编写一个巨大的bambda,从0-100分评分请求的可攻击性,但目前这里有两个简单示例:
该请求有多少个参数?
有时,你只是想尽快找到最大的攻击面。
1
|
return requestResponse.request().parameters().size();
|
响应中有多少次’HTTP_‘出现?
这可能表明环境变量泄漏,或者可以调整以查找各种其他有趣的字符串。
1
2
3
4
5
|
if (!requestResponse.hasResponse()) {
return 0;
}
String lookFor = "HTTP_";
return utilities().byteUtils().countMatches(requestResponse.response().body().getBytes(), lookFor.getBytes());
|
执行shell命令
也许下次吧
通过这些Bambda示例,你可以显著提升对HTTP流量的分析能力,更有效地识别潜在的安全问题和攻击向量。