Version: 3.1 Update

This commit is contained in:
gh0stkey
2024-05-23 12:00:13 +08:00
parent ead03d42b9
commit 332b119064
18 changed files with 785 additions and 175 deletions

View File

@@ -11,6 +11,8 @@ import burp.api.montoya.ui.editor.extension.ExtensionProvidedHttpRequestEditor;
import burp.api.montoya.ui.editor.extension.HttpRequestEditorProvider;
import hae.component.board.Datatable;
import hae.instances.http.utils.MessageProcessor;
import hae.utils.config.ConfigLoader;
import hae.utils.string.StringProcessor;
import javax.swing.*;
import java.awt.*;
@@ -20,26 +22,31 @@ import java.util.Map;
public class RequestEditor implements HttpRequestEditorProvider {
private final MontoyaApi api;
private final ConfigLoader configLoader;
public RequestEditor(MontoyaApi api) {
public RequestEditor(MontoyaApi api, ConfigLoader configLoader) {
this.api = api;
this.configLoader = configLoader;
}
@Override
public ExtensionProvidedHttpRequestEditor provideHttpRequestEditor(EditorCreationContext editorCreationContext) {
return new Editor(api, editorCreationContext);
return new Editor(api, configLoader, editorCreationContext);
}
private static class Editor implements ExtensionProvidedHttpRequestEditor {
private final MontoyaApi api;
private final ConfigLoader configLoader;
private final EditorCreationContext creationContext;
private final MessageProcessor messageProcessor;
private HttpRequestResponse requestResponse;
private List<Map<String, String>> dataList;
private final JTabbedPane jTabbedPane = new JTabbedPane();
public Editor(MontoyaApi api, EditorCreationContext creationContext) {
public Editor(MontoyaApi api, ConfigLoader configLoader, EditorCreationContext creationContext) {
this.api = api;
this.configLoader = configLoader;
this.creationContext = creationContext;
this.messageProcessor = new MessageProcessor(api);
}
@@ -52,15 +59,29 @@ public class RequestEditor implements HttpRequestEditorProvider {
@Override
public void setRequestResponse(HttpRequestResponse requestResponse) {
this.requestResponse = requestResponse;
generateTabbedPaneFromResultMap(api, jTabbedPane, this.dataList);
}
@Override
public synchronized boolean isEnabledFor(HttpRequestResponse requestResponse) {
HttpRequest request = requestResponse.request();
if (request != null && !request.bodyToString().equals("Loading...")) {
List<Map<String, String>> result = messageProcessor.processRequest("", request, false);
generateTabbedPaneFromResultMap(api, jTabbedPane, result);
return jTabbedPane.getTabCount() > 0;
if (request != null) {
try {
String host = StringProcessor.getHostByUrl(request.url());
if (!host.isEmpty()) {
String[] hostList = configLoader.getBlockHost().split("\\|");
boolean isBlockHost = isBlockHost(hostList, host);
List<String> suffixList = Arrays.asList(configLoader.getExcludeSuffix().split("\\|"));
boolean matches = suffixList.contains(request.fileExtension().toLowerCase()) || isBlockHost;
if (!matches && !request.bodyToString().equals("Loading...")) {
this.dataList = messageProcessor.processRequest("", request, false);
return isListHasData(this.dataList);
}
}
} catch (Exception ignored) {
}
}
return false;
}
@@ -97,11 +118,30 @@ public class RequestEditor implements HttpRequestEditorProvider {
}
}
public static boolean isBlockHost(String[] hostList, String host) {
boolean isBlockHost = false;
for (String hostName : hostList) {
String cleanedHost = StringProcessor.replaceFirstOccurrence(hostName, "*.", "");
if (StringProcessor.matchFromEnd(host, cleanedHost)) {
isBlockHost = true;
}
}
return isBlockHost;
}
public static boolean isListHasData(List<Map<String, String>> dataList) {
if (dataList != null && !dataList.isEmpty()) {
Map<String, String> dataMap = dataList.get(0);
return dataMap != null && !dataMap.isEmpty();
}
return false;
}
public static void generateTabbedPaneFromResultMap(MontoyaApi api, JTabbedPane tabbedPane, List<Map<String, String>> result) {
tabbedPane.removeAll();
if (result != null && !result.isEmpty() && result.size() > 0) {
if (result != null && !result.isEmpty()) {
Map<String, String> dataMap = result.get(0);
if (dataMap != null && !dataMap.isEmpty() && dataMap.size() > 0) {
if (dataMap != null && !dataMap.isEmpty()) {
dataMap.keySet().forEach(i -> {
String[] extractData = dataMap.get(i).split("\n");
Datatable dataPanel = new Datatable(api, i, Arrays.asList(extractData));

View File

@@ -4,6 +4,7 @@ import burp.api.montoya.MontoyaApi;
import burp.api.montoya.core.ByteArray;
import burp.api.montoya.core.Range;
import burp.api.montoya.http.message.HttpRequestResponse;
import burp.api.montoya.http.message.requests.HttpRequest;
import burp.api.montoya.http.message.responses.HttpResponse;
import burp.api.montoya.ui.Selection;
import burp.api.montoya.ui.editor.extension.EditorCreationContext;
@@ -11,34 +12,42 @@ import burp.api.montoya.ui.editor.extension.ExtensionProvidedHttpResponseEditor;
import burp.api.montoya.ui.editor.extension.HttpResponseEditorProvider;
import hae.component.board.Datatable;
import hae.instances.http.utils.MessageProcessor;
import hae.utils.config.ConfigLoader;
import hae.utils.string.StringProcessor;
import javax.swing.*;
import java.awt.*;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class ResponseEditor implements HttpResponseEditorProvider {
private final MontoyaApi api;
private final ConfigLoader configLoader;
public ResponseEditor(MontoyaApi api) {
public ResponseEditor(MontoyaApi api, ConfigLoader configLoader) {
this.api = api;
this.configLoader = configLoader;
}
@Override
public ExtensionProvidedHttpResponseEditor provideHttpResponseEditor(EditorCreationContext editorCreationContext) {
return new Editor(api, editorCreationContext);
return new Editor(api, configLoader, editorCreationContext);
}
private static class Editor implements ExtensionProvidedHttpResponseEditor {
private final MontoyaApi api;
private final ConfigLoader configLoader;
private final EditorCreationContext creationContext;
private final MessageProcessor messageProcessor;
private HttpRequestResponse requestResponse;
private List<Map<String, String>> dataList;
private final JTabbedPane jTabbedPane = new JTabbedPane();
public Editor(MontoyaApi api, EditorCreationContext creationContext) {
public Editor(MontoyaApi api, ConfigLoader configLoader, EditorCreationContext creationContext) {
this.api = api;
this.configLoader = configLoader;
this.creationContext = creationContext;
this.messageProcessor = new MessageProcessor(api);
}
@@ -51,16 +60,37 @@ public class ResponseEditor implements HttpResponseEditorProvider {
@Override
public void setRequestResponse(HttpRequestResponse requestResponse) {
this.requestResponse = requestResponse;
RequestEditor.generateTabbedPaneFromResultMap(api, jTabbedPane, this.dataList);
}
@Override
public synchronized boolean isEnabledFor(HttpRequestResponse requestResponse) {
HttpResponse request = requestResponse.response();
if (request != null && !request.bodyToString().equals("Loading...")) {
List<Map<String, String>> result = messageProcessor.processResponse("", request, false);
RequestEditor.generateTabbedPaneFromResultMap(api, jTabbedPane, result);
return jTabbedPane.getTabCount() > 0;
HttpResponse response = requestResponse.response();
if (response != null) {
HttpRequest request = requestResponse.request();
boolean matches = false;
if (request != null) {
try {
String host = StringProcessor.getHostByUrl(request.url());
if (!host.isEmpty()) {
String[] hostList = configLoader.getBlockHost().split("\\|");
boolean isBlockHost = RequestEditor.isBlockHost(hostList, host);
List<String> suffixList = Arrays.asList(configLoader.getExcludeSuffix().split("\\|"));
matches = suffixList.contains(request.fileExtension().toLowerCase()) || isBlockHost;
}
} catch (Exception ignored) {
}
}
if (!matches && !response.bodyToString().equals("Loading...")) {
this.dataList = messageProcessor.processResponse("", response, false);
return RequestEditor.isListHasData(this.dataList);
}
}
return false;
}

View File

@@ -33,6 +33,7 @@ public class WebSocketEditor implements WebSocketMessageEditorProvider {
private final EditorCreationContext creationContext;
private final MessageProcessor messageProcessor;
private ByteArray message;
private List<Map<String, String>> dataList;
private final JTabbedPane jTabbedPane = new JTabbedPane();
@@ -50,15 +51,15 @@ public class WebSocketEditor implements WebSocketMessageEditorProvider {
@Override
public void setMessage(WebSocketMessage webSocketMessage) {
this.message = webSocketMessage.payload();
RequestEditor.generateTabbedPaneFromResultMap(api, jTabbedPane, this.dataList);
}
@Override
public boolean isEnabledFor(WebSocketMessage webSocketMessage) {
String websocketMessage = webSocketMessage.payload().toString();
if (!websocketMessage.isEmpty()) {
List<Map<String, String>> result = messageProcessor.processMessage("", websocketMessage, false);
RequestEditor.generateTabbedPaneFromResultMap(api, jTabbedPane, result);
return jTabbedPane.getTabCount() > 0;
this.dataList = messageProcessor.processMessage("", websocketMessage, false);
return RequestEditor.isListHasData(this.dataList);
}
return false;
}

View File

@@ -6,9 +6,10 @@ import burp.api.montoya.core.HighlightColor;
import burp.api.montoya.http.handler.*;
import burp.api.montoya.http.message.HttpRequestResponse;
import burp.api.montoya.http.message.requests.HttpRequest;
import hae.Config;
import hae.component.board.message.MessageTableModel;
import hae.instances.editor.RequestEditor;
import hae.instances.http.utils.MessageProcessor;
import hae.utils.config.ConfigLoader;
import hae.utils.string.StringProcessor;
import java.util.ArrayList;
@@ -18,6 +19,7 @@ import java.util.Map;
public class HttpMessageHandler implements HttpHandler {
private final MontoyaApi api;
private final ConfigLoader configLoader;
private final MessageTableModel messageTableModel;
private final MessageProcessor messageProcessor;
@@ -29,8 +31,9 @@ public class HttpMessageHandler implements HttpHandler {
private final ThreadLocal<Boolean> matches = ThreadLocal.withInitial(() -> false);
private final ThreadLocal<HttpRequest> httpRequest = new ThreadLocal<>();
public HttpMessageHandler(MontoyaApi api, MessageTableModel messageTableModel) {
public HttpMessageHandler(MontoyaApi api, ConfigLoader configLoader, MessageTableModel messageTableModel) {
this.api = api;
this.configLoader = configLoader;
this.messageTableModel = messageTableModel;
this.messageProcessor = new MessageProcessor(api);
}
@@ -46,8 +49,11 @@ public class HttpMessageHandler implements HttpHandler {
host.set(StringProcessor.getHostByUrl(httpRequestToBeSent.url()));
List<String> suffixList = Arrays.asList(Config.suffix.split("\\|"));
matches.set(suffixList.contains(httpRequestToBeSent.fileExtension()));
String[] hostList = configLoader.getBlockHost().split("\\|");
boolean isBlockHost = RequestEditor.isBlockHost(hostList, host.get());
List<String> suffixList = Arrays.asList(configLoader.getExcludeSuffix().split("\\|"));
matches.set(suffixList.contains(httpRequestToBeSent.fileExtension().toLowerCase()) || isBlockHost);
if (!matches.get()) {
List<Map<String, String>> result = messageProcessor.processRequest(host.get(), httpRequestToBeSent, true);

View File

@@ -9,12 +9,12 @@ import hae.Config;
import hae.cache.CachePool;
import hae.utils.string.HashCalculator;
import hae.utils.string.StringProcessor;
import jregex.Matcher;
import jregex.Pattern;
import java.text.MessageFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegularMatcher {
private final MontoyaApi api;
@@ -27,7 +27,7 @@ public class RegularMatcher {
public Map<String, Map<String, Object>> match(String host, String type, String message, String header, String body) {
// 先从缓存池里判断是否有已经匹配好的结果
String messageIndex = HashCalculator.calculateHash(message.getBytes());
Map<String, Map<String, Object>> map = CachePool.getFromCache(messageIndex);
Map<String, Map<String, Object>> map = CachePool.get(messageIndex);
if (map != null) {
return map;
} else {
@@ -81,6 +81,7 @@ public class RegularMatcher {
result.addAll(matchByRegex(f_regex, s_regex, matchContent, format, engine, sensitive));
} catch (Exception e) {
api.logging().logToError(String.format("[x] Error Info:\nName: %s\nRegex: %s", name, f_regex));
api.logging().logToError(e.getMessage());
continue;
}
@@ -98,27 +99,18 @@ public class RegularMatcher {
// 添加到全局变量中便于Databoard检索
if (!Objects.equals(host, "") && host != null) {
List<String> dataList = Arrays.asList(dataStr.split("\n"));
if (Config.globalDataMap.containsKey(host)) {
ConcurrentHashMap<String, List<String>> gRuleMap = new ConcurrentHashMap<>(Config.globalDataMap.get(host));
if (gRuleMap.containsKey(name)) {
// gDataList为不可变列表因此需要重新创建一个列表以便于使用addAll方法
List<String> gDataList = gRuleMap.get(name);
List<String> newDataList = new ArrayList<>(gDataList);
newDataList.addAll(dataList);
newDataList = new ArrayList<>(new HashSet<>(newDataList));
gRuleMap.remove(name);
gRuleMap.put(name, newDataList);
} else {
gRuleMap.put(name, dataList);
}
Config.globalDataMap.remove(host);
Config.globalDataMap.put(host, gRuleMap);
} else {
Map<String, List<String>> ruleMap = new HashMap<>();
ruleMap.put(name, dataList);
// 添加单一Host
Config.globalDataMap.put(host, ruleMap);
}
Config.globalDataMap.compute(host, (existingHost, existingMap) -> {
Map<String, List<String>> gRuleMap = Optional.ofNullable(existingMap).orElse(new ConcurrentHashMap<>());
gRuleMap.merge(name, new ArrayList<>(dataList), (existingList, newList) -> {
Set<String> combinedSet = new LinkedHashSet<>(existingList);
combinedSet.addAll(newList);
return new ArrayList<>(combinedSet);
});
return gRuleMap;
});
String[] splitHost = host.split("\\.");
String onlyHost = host.split(":")[0];
@@ -139,7 +131,7 @@ public class RegularMatcher {
}
}
});
CachePool.addToCache(messageIndex, finalMap);
CachePool.put(messageIndex, finalMap);
return finalMap;
}
}
@@ -229,7 +221,7 @@ public class RegularMatcher {
}
private Matcher createPatternMatcher(String regex, String content, boolean sensitive) {
Pattern pattern = (sensitive) ? new Pattern(regex) : new Pattern(regex, Pattern.IGNORE_CASE);
Pattern pattern = sensitive ? Pattern.compile(regex) : Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
return pattern.matcher(content);
}
@@ -242,7 +234,7 @@ public class RegularMatcher {
private LinkedList<Integer> parseIndexesFromString(String input) {
LinkedList<Integer> indexes = new LinkedList<>();
Pattern pattern = new Pattern("\\{(\\d+)}");
Pattern pattern = Pattern.compile("\\{(\\d+)}");
Matcher matcher = pattern.matcher(input);
while (matcher.find()) {
@@ -264,7 +256,7 @@ public class RegularMatcher {
}
private String reorderIndex(String format) {
Pattern pattern = new Pattern("\\{(\\d+)}");
Pattern pattern = Pattern.compile("\\{(\\d+)}");
Matcher matcher = pattern.matcher(format);
int count = 0;
while (matcher.find()) {