Skip to content

Instantly share code, notes, and snippets.

@ncoblentz
Last active February 21, 2024 20:24
Show Gist options
  • Save ncoblentz/c212aadee8176ebc1af2ffb6018c2647 to your computer and use it in GitHub Desktop.
Save ncoblentz/c212aadee8176ebc1af2ffb6018c2647 to your computer and use it in GitHub Desktop.
Integer mySelection = new Integer(0);
boolean mustBeInScope=true;
ZonedDateTime requestsAfterThisDate = ZonedDateTime.of(LocalDateTime.of(2024, 1, 19, 10, 0,0,0), ZoneId.of("America/Chicago")); // or null
ZonedDateTime requestsBeforeThisDate = ZonedDateTime.of(LocalDateTime.of(2024, 1, 19, 10, 10,0,0), ZoneId.of("America/Chicago")); // or null
//Most of these come from: https://github.com/PortSwigger/bambdas/tree/main/Proxy/HTTP
/*
-1: No Filter
0: Normal filter
1: Large redirect responses
2: Responses with multiple </html> tags
3: Incorrect content-length
4: Malformed HTTP header
5: Find all JSON endpoints with no or text/html mime type
6: Find JSONP for CSP bypass
7: Filter on Specific Color
8: Non-Standard HTTP Methods
9: Unencrypted HTTP
10: Response Bodies with no Content-Length
11: Filter By Response Code
12: Find WebSocket Connnection Attempts
13: Show All Highlighted
14: Show Requests between specific dates/times
15: Look for responses with more than one closing html, head, or body tag
*/
Predicate<Integer> filterSelection = (selection) ->
{
if(mustBeInScope)
{
if(!requestResponse.request().isInScope())
{
return false;
}
}
switch(selection.intValue())
{
case 0:
var path = requestResponse.request().pathWithoutQuery().toLowerCase();
return !path.endsWith(".js")
&& !requestResponse.request().method().equals("OPTIONS")
&& !path.endsWith(".gif")
&& !path.endsWith(".jpg")
&& !path.endsWith(".png")
&& !path.endsWith(".css")
&& !path.endsWith(".woff")
&& !path.endsWith(".woff2")
&& !path.endsWith(".ico")
&& !path.endsWith(".svg")
&& !path.endsWith(".ttf")
&& !path.endsWith(".map");
case 1:
return requestResponse.hasResponse() &&
requestResponse.response().statusCode() <= 399 &&
requestResponse.response().statusCode() >= 300 &&
requestResponse.response().body().length() > 1000;
case 2:
return requestResponse.hasResponse() && requestResponse.response().statedMimeType() == MimeType.HTML &&
utilities().byteUtils().countMatches(
requestResponse.response().body().getBytes(), "</html>".getBytes()) > 1;
case 3:
if(!requestResponse.hasResponse() || requestResponse.response().body()==null || !requestResponse.response().hasHeader("Content-Length") )
{
return false;
}
int realContentLength = requestResponse.response().body().length();
int declaredContentLength = Integer.parseInt(
requestResponse.response().headerValue("Content-Length"));
return declaredContentLength != realContentLength;
case 4:
return requestResponse.hasResponse() && requestResponse.response().headers()!=null && requestResponse.response().headers().stream().anyMatch(
e -> e.name().contains(" "));
case 5:
if(!requestResponse.hasResponse()) {
return false;
}
var response = requestResponse.response();
if (response.hasHeader("Content-Type")) {
if (!response.headerValue("Content-Type").contains("text/html")) {
return false;
}
}
String body = response.bodyToString().trim();
boolean looksLikeJson = body.startsWith("{") || body.startsWith("[");
if(!looksLikeJson) {
return false;
}
return true;
case 6:
var req = requestResponse.request();
var res = requestResponse.response();
var paramRegex = Pattern.compile("^[a-zA-Z][.\\w]{4,}$");
if(res == null || res.body().length() == 0) return false;
if(!req.hasParameters()) return false;
var body2 = res.bodyToString().trim();
var params = req.parameters();
for(var param: params) {
var value = param.value();
if(param.type() != HttpParameterType.URL)continue;
if(paramRegex.matcher(value).find()) {
var start = "(?:^|[^\\w'\".])";
var end = "\\s*[(]";
var callbackRegex = Pattern.compile(start+Pattern.quote(value)+end);
if(callbackRegex.matcher(body2).find())return true;
}
}
return false;
case 7:
/*
* Options:
* - HighlightColor.BLUE;
* - HighlightColor.CYAN;
* - HighlightColor.GRAY;
* - HighlightColor.GREEN;
* - HighlightColor.MAGENTA;
* - HighlightColor.NONE;
* - HighlightColor.ORANGE;
* - HighlightColor.PINK;
* - HighlightColor.RED;
* - HighlightColor.YELLOW;
**/
return requestResponse.annotations().highlightColor().equals(HighlightColor.CYAN);
case 8:
return !Set.of("PUT","DELETE","OPTIONS","POST", "GET").contains(requestResponse.request().method());
case 9:
return !requestResponse.request().url().startsWith("https://");
case 10:
return requestResponse.hasResponse() && requestResponse.response().body()!=null && !requestResponse.response().hasHeader("Content-Length");
case 11:
return requestResponse.hasResponse() && !Set.of((short)200,(short)404,(short)304).contains(requestResponse.response().statusCode());
case 12:
return requestResponse.request().hasHeader("Upgrade") && requestResponse.request().headerValue("Upgrade").equalsIgnoreCase("websocket");
case 13:
return !requestResponse.annotations().highlightColor().equals(HighlightColor.NONE);
case 14:
boolean afterCheck=true;
boolean beforeCheck=true;
if(requestsAfterThisDate!=null)
{
afterCheck = requestResponse.time().isAfter(requestsAfterThisDate);
}
if(requestsBeforeThisDate!=null)
{
beforeCheck = requestResponse.time().isBefore(requestsBeforeThisDate);
}
return afterCheck&&beforeCheck;
case 15:
if(requestResponse.hasResponse() && requestResponse.response().statedMimeType() == MimeType.HTML)
{
String[] tags = new String[] {"html","body","head"};
byte[] bodyBytes = requestResponse.response().body().getBytes();
for(int i=0;i<tags.length;i++) {
if(utilities().byteUtils().countMatches(bodyBytes, String.format("</%s>",tags[i]).getBytes()) > 1)
{
return true;
}
};
}
return false;
default:
return true;
}
};
return filterSelection.test(mySelection);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment