Skip to content
Open
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
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ repositories {
}

dependencies {
compile 'net.portswigger.burp.extender:burp-extender-api:1.7.22'
implementation 'net.portswigger.burp.extender:burp-extender-api:1.7.22'
}

sourceSets {
Expand Down
59 changes: 48 additions & 11 deletions burp/BurpExtender.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
package burp;

import javax.swing.SwingUtilities;

import burp.IBurpExtender;
import burp.IBurpExtenderCallbacks;
import burp.IExtensionHelpers;
import burp.IExtensionStateListener;
import burp.IHttpRequestResponse;
import burp.IRequestInfo;
import burp.IResponseInfo;
import burp.ISessionHandlingAction;
import burp.ITab;

import java.awt.Component;
import java.util.ArrayList;
import java.util.Arrays;
Expand All @@ -12,6 +23,7 @@ public class BurpExtender implements IBurpExtender, ISessionHandlingAction, ITab

IExtensionHelpers helpers = null;
Pattern p;
private String lastToken = null;

static String extensionName = "Add Custom Header";
IBurpExtenderCallbacks callbacks = null;
Expand All @@ -28,13 +40,22 @@ public class BurpExtender implements IBurpExtender, ISessionHandlingAction, ITab
final String KEY_MODE = "setting_mode";
final String KEY_HEADER_NAME = "settings_header_name";
final String KEY_HEADER_VALUE_PREFIX = "settings_header_value_prefix";
final String KEY_LAST_TOKEN = "setting_last_token";

private BurpTab tab;

void useRegExp() {

}

private String ellipsize(String text, int maxLength) {
final int minLength = 30;
if (text == null || text.length() <= maxLength || maxLength <= minLength) {
return text;
}
return text.substring(0, minLength) + "..." + text.substring(text.length() - maxLength + minLength);
}

@Override
public void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks) {
this.callbacks = callbacks;
Expand Down Expand Up @@ -79,6 +100,7 @@ public void run() {
}else if("HARD_CODED".equalsIgnoreCase(mode)){
tab.setUseHardCoded();
}
lastToken = callbacks.loadExtensionSetting(KEY_LAST_TOKEN);
callbacks.printOutput("Mode loaded: " + mode);

// force update the example label
Expand All @@ -102,16 +124,18 @@ public String getActionName() {
public void performAction(IHttpRequestResponse currentRequest,
IHttpRequestResponse[] macroItems) {

if (tab == null) {
callbacks.printError("Cannot apply custom header because extension UI is not ready");
return;
}

String token = null;
int macroCount = macroItems == null ? 0 : macroItems.length;

if (tab.useHardCoded()) {
// token has priority over regexp
token = tab.getHardCodedText();
} else if (tab.useRegExp()) {
if (macroItems.length == 0) {
this.callbacks.issueAlert("No macro configured or macro did not return any response");
return;
}
String regexp = tab.getRegExpText();
try {
p = Pattern.compile(regexp);
Expand All @@ -122,16 +146,23 @@ public void performAction(IHttpRequestResponse currentRequest,
}

// go through all macros and run the regular expression on their body
for (int i = 0; i < macroItems.length; i++) {
for (int i = 0; i < macroCount; i++) {
byte[] _responseBody = macroItems[i].getResponse();
if (_responseBody == null) return;
if (_responseBody == null) {
return;
}
IResponseInfo macroResponse = helpers.analyzeResponse(_responseBody);
if (macroResponse == null ) return;
if (macroResponse == null ) {
return;
}
String responseBody = helpers.bytesToString(_responseBody);
Matcher m = p.matcher(responseBody);
if (m.find()) {
token = m.group(1);
if (token != null && token.length() > 0) {
lastToken = token;
callbacks.saveExtensionSetting(KEY_LAST_TOKEN, lastToken);
callbacks.printOutput("Regex matched new token (macro index " + i + ", preview=" + ellipsize(token, 80) + ")");
// found it
break;
}
Expand All @@ -143,9 +174,14 @@ public void performAction(IHttpRequestResponse currentRequest,
}

if (token == null) {
// nothing found: failing silently to avoid polluting the logs
callbacks.printError("No token found");
return;
if (lastToken != null && lastToken.length() > 0) {
token = lastToken;
callbacks.printOutput("No token found in macro response, reusing last stored token");
} else {
// nothing found: failing silently to avoid polluting the logs
callbacks.printError("No token found");
return;
}
}

String headerName = tab.getHeaderName();
Expand All @@ -162,7 +198,7 @@ public void performAction(IHttpRequestResponse currentRequest,
}
String newHeader = headerName + ": " + headerValuePrefix + token;
headers.add(newHeader);
callbacks.printOutput("Added header: '" + newHeader + "'");
callbacks.printOutput("Added header: '" + ellipsize(newHeader, 80) + "'");

byte[] message = helpers.buildHttpMessage(headers, Arrays.copyOfRange(currentRequest.getRequest(), rqInfo.getBodyOffset(), currentRequest.getRequest().length));
currentRequest.setRequest(message);
Expand Down Expand Up @@ -195,6 +231,7 @@ public void extensionUnloaded() {
mode = "REGEX";
}
callbacks.saveExtensionSetting(KEY_MODE, mode);
callbacks.saveExtensionSetting(KEY_LAST_TOKEN, lastToken);
callbacks.printOutput("Settings saved!");
}
// end ITab methods
Expand Down