The Burp Suite User Forum was discontinued on the 1st November 2024.

Burp Suite User Forum

For support requests, go to the Support Center. To discuss with other Burp users, head to our Discord page.

SUPPORT CENTER DISCORD

Extensions Development: Burp hanging when modifying request in an extension

Eric | Last updated: Mar 14, 2023 09:01PM UTC

Greetings, I am using the HttpHandler example for the Montoya API located here: https://github.com/PortSwigger/burp-extensions-montoya-api-examples/blob/main/httphandler/src/main/java/example/httphandler/MyHttpHandler.java I have modified the request with a regex to do a search and replace and then attempt to send that modified request, but the request is never sent from repeater, well it doesn't show up in logger and the send button remains greyed out. For what it's worth, the match and replace seems to work just fine. I dump the string to the console for review and I can't see anything obvious it wouldn't like. Note that I noticed there are separate methods for HttpRequest.httpRequest() and HttpRequest.http2Request() but neither of these seem to work. The reason I am using toString is that it seems the easiest way to parse the entire request with a reqex versus parsing every header, url parameter, and body. Am I missing something? The code is roughly below: import burp.api.montoya.MontoyaApi; import burp.api.montoya.core.Annotations; import burp.api.montoya.core.HighlightColor; import burp.api.montoya.http.HttpService; import burp.api.montoya.http.handler.*; import burp.api.montoya.http.message.HttpHeader; import burp.api.montoya.http.message.requests.HttpRequest; import burp.api.montoya.logging.Logging; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; import java.util.List; import java.util.Arrays; import java.util.regex.Matcher; import java.util.regex.Pattern; import static burp.api.montoya.http.handler.RequestToBeSentAction.continueWith; import static burp.api.montoya.http.handler.ResponseReceivedAction.continueWith; import static burp.api.montoya.http.message.params.HttpParameter.urlParameter; public class MyHttpHandler implements HttpHandler { private final MontoyaApi api; private final Logging logging; private final ReplacerTab tab; public MyHttpHandler(MontoyaApi api, ReplacerTab mainTab) { this.api = api; this.logging = api.logging(); this.tab = mainTab; } @Override public RequestToBeSentAction handleHttpRequestToBeSent(HttpRequestToBeSent requestToBeSent) { HttpRequest modifiedRequest = requestToBeSent; Annotations annotations = requestToBeSent.annotations(); try { String[] options = {"requests", "requests and responses"}; Boolean enabled = this.tab.getEnabledValue(); String intercept = this.tab.getInterceptValue().toLowerCase(); logging.logToOutput("tool: " + requestToBeSent.toolSource().toolType().toolName()); if (enabled && Arrays.asList(options).contains(intercept)) { ArrayList<String> enabledTools = this.tab.getEnabledTools(); String toolSource = requestToBeSent.toolSource().toolType().toolName(); if (enabledTools.contains(toolSource.toLowerCase())) { String matchRegex = this.tab.getMatchSearchValue(); String requestAsStr = requestToBeSent.toString(); Pattern matchPattern = Pattern.compile(matchRegex, Pattern.MULTILINE); Matcher matcher = matchPattern.matcher(requestAsStr); Boolean matched = matcher.find(); if (matched) { String matchedValue = matcher.group(0); logging.logToOutput("Matched: " + matchedValue); annotations = annotations.withNotes("Request was modified with Super Replacer"); String replacerValue = null; if (this.tab.getMatchReplaceRegexValue()) { String replaceRegex = this.tab.getMatchSearchValue(); Pattern replacePattern = Pattern.compile(matchRegex, Pattern.MULTILINE); Matcher replacer = matchPattern.matcher(requestAsStr); Boolean replacerFound = replacer.find(); if (replacerFound) { replacerValue = replacer.group(0); } } else { replacerValue = this.tab.getReplaceWithValue(); } logging.logToOutput("Replacer: " + replacerValue); if (!replacerValue.isEmpty()) { String replaceCount = this.tab.getReplaceCountValue(); if (replaceCount.equalsIgnoreCase("first")) { requestAsStr = matcher.replaceFirst(replacerValue); } else if (replaceCount.equalsIgnoreCase("all")) { requestAsStr = matcher.replaceAll(replacerValue); } logging.logToOutput("Replaced " + matchedValue + " with " + replacerValue); logging.logToOutput(requestAsStr); //Modify the request by adding url param. modifiedRequest = HttpRequest.httpRequest(requestAsStr); if(modifiedRequest.httpVersion().equalsIgnoreCase("http/2")) { logging.logToOutput("Request is HTTP/2, converting."); HttpService service = modifiedRequest.httpService(); List<HttpHeader> headers = modifiedRequest.headers(); String body = modifiedRequest.bodyToString(); modifiedRequest = HttpRequest.http2Request(service, headers, body); } } else { logging.logToOutput("Replacer does not have a value"); } } else { logging.logToOutput("Matcher failed: " + matchRegex); } } else { logging.logToOutput(toolSource + " is not enabled for this tab."); } } else { logging.logToOutput("Tab is disabled or not set to intercept requests"); } //Return the modified request to burp with updated annotations. } catch(Exception e) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); logging.logToError(sw.toString()); } return continueWith(modifiedRequest, annotations); } @Override public ResponseReceivedAction handleHttpResponseReceived(HttpResponseReceived responseReceived) { return continueWith(responseReceived); } }

Eric | Last updated: Mar 14, 2023 11:05PM UTC