Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions src/main/java/burp/BurpExtender.java
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,8 @@ public void run() {

updateStatus("Initializing...");
long initStart = System.currentTimeMillis();
if (!RequestSender.initialTest(reqRes)) {
String initialRandomSegment = RequestSender.initialTest(reqRes);
if (initialRandomSegment == null) {
logWarning("Scan aborted: Initial path mapping tests failed");
return;
}
Expand All @@ -172,9 +173,11 @@ public void run() {
}
}

String randomSegment = reqRes.getComment();
String randomSegment = initialRandomSegment;
if (randomSegment == null || randomSegment.isEmpty()) {
randomSegment = "test";
// Should not happen, but fall back to a fresh random value if the initial test
// completed without producing a usable segment
randomSegment = RequestSender.generateRandomString(5);
}

Map<String, Set<String>> vulnerableDelimiterCombinations = new HashMap<>();
Expand Down
19 changes: 9 additions & 10 deletions src/main/java/burp/RequestSender.java
Original file line number Diff line number Diff line change
Expand Up @@ -137,15 +137,15 @@ private static Pattern[] compilePatterns(String... rawPatterns) {
* 1. Authenticated and unauthenticated responses are DIFFERENT (confirms auth is required)
* 2. Authenticated response with appended segment is SIMILAR to original (confirms backend ignores trailing segments)
*/
protected static boolean initialTest(IHttpRequestResponse message) {
protected static String initialTest(IHttpRequestResponse message) {
byte[] orgRequest = buildHttpRequest(message, null, null, true);
Map<String, Object> orgDetails = retrieveResponseDetails(message.getHttpService(), orgRequest);
if (orgDetails == null) {
return false;
return null;
}
int orgStatusCode = (int) orgDetails.get("statusCode");
if (orgStatusCode < 200 || orgStatusCode >= 300) {
return false; // Original request must succeed
return null; // Original request must succeed
}
byte[] originalAuthBody = (byte[]) orgDetails.get("body");

Expand All @@ -154,7 +154,7 @@ protected static boolean initialTest(IHttpRequestResponse message) {
byte[] unAuthedRequest = buildHttpRequest(message, null, null, false);
Map<String, Object> unauthDetails = retrieveResponseDetails(message.getHttpService(), unAuthedRequest);
if (unauthDetails == null) {
return false;
return null;
}
int unauthStatusCode = (int) unauthDetails.get("statusCode");
byte[] unauthBody = (byte[]) unauthDetails.get("body");
Expand All @@ -165,7 +165,7 @@ protected static boolean initialTest(IHttpRequestResponse message) {
// If unauthenticated response is similar, this endpoint doesn't require auth - skip it
if (unauthedIsSimilar) {
BurpExtender.logDebug("Initial test failed: Unauthenticated response similar to authenticated");
return false;
return null;
}

// Step 2: Verify that appending a random segment returns SIMILAR content
Expand All @@ -174,11 +174,11 @@ protected static boolean initialTest(IHttpRequestResponse message) {
byte[] testRequest = buildHttpRequestWithSegment(message, randomSegment, null, true, "/");
Map<String, Object> appendedDetails = retrieveResponseDetails(message.getHttpService(), testRequest);
if (appendedDetails == null) {
return false;
return null;
}
int appendedStatusCode = (int) appendedDetails.get("statusCode");
if (appendedStatusCode < 200 || appendedStatusCode >= 300) {
return false; // Appended request must also succeed
return null; // Appended request must also succeed
}
byte[] appendedBody = (byte[]) appendedDetails.get("body");

Expand All @@ -187,12 +187,11 @@ protected static boolean initialTest(IHttpRequestResponse message) {

if (!appendIsSimilar) {
BurpExtender.logDebug("Initial test failed: Appended segment response not similar to original");
return false;
return null;
}

// Both conditions met: auth required AND backend ignores trailing segments
message.setComment(randomSegment);
return true;
return randomSegment;
}

/**
Expand Down