用Bambdas优化HTTP视角
当你打开HTTP请求或响应时,会本能地寻找什么?可疑的参数名?CORS头部?还是请求来源或底层目的的线索?
每个HTTP消息对不同观察者可能讲述不同故事,但现代网站发送数千条请求,很容易忽略关键内容。为此,Burp Suite最近增加了自定义列功能,让你可以个性化设置在表格中显示HTTP请求的哪些元素。以下是一个简单示例,它从请求体中解析GraphQL操作并显示在列中:
这些功能背后使用的是称为bambdas的代码片段。该功能强大到几乎令人不知所措,因此我们想分享研究团队创建的一些列。这些示例从简单实用到相对复杂都有。熟悉Java的读者可能会注意到我们没有特意避免空指针异常——这是因为它们在行级别已得到处理,通常不会造成问题。
请求源自哪个页面?
理解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?
此自定义列Bamda允许你优先测试部署了不安全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命令
也许下次