Version: 3.0.2 Update

This commit is contained in:
gh0stkey
2024-05-12 19:02:38 +08:00
parent 3363ca25ed
commit 4da3d3f42d
20 changed files with 140 additions and 130 deletions

View File

@@ -16,7 +16,7 @@ public class HaE implements BurpExtension {
@Override
public void initialize(MontoyaApi api) {
// 设置扩展名称
String version = "3.0.1";
String version = "3.0.2";
api.extension().setName(String.format("HaE (%s) - Highlighter and Extractor", version));
// 加载扩展后输出的项目信息

View File

@@ -1,6 +1,7 @@
package hae.cache;
import java.util.*;
import java.util.HashMap;
import java.util.Map;
public class CachePool {
private static final Map<String, Map<String, Map<String, Object>>> cache = new HashMap<>();

View File

@@ -3,20 +3,21 @@ package hae.component.board;
import burp.api.montoya.MontoyaApi;
import hae.Config;
import hae.component.board.message.MessageTableModel;
import hae.utils.string.StringProcessor;
import hae.utils.config.ConfigLoader;
import hae.component.board.message.MessageTableModel.MessageTable;
import hae.utils.config.ConfigLoader;
import hae.utils.string.StringProcessor;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import javax.swing.event.*;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
import java.awt.*;
import java.awt.event.*;
import java.util.List;
import javax.swing.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public class Databoard extends JPanel {
private final MontoyaApi api;
@@ -28,8 +29,8 @@ public class Databoard extends JPanel {
private MessageTable messageTable;
private static Boolean isMatchHost = false;
private DefaultComboBoxModel comboBoxModel = new DefaultComboBoxModel();
private JComboBox hostComboBox = new JComboBox(comboBoxModel);
private final DefaultComboBoxModel comboBoxModel = new DefaultComboBoxModel();
private final JComboBox hostComboBox = new JComboBox(comboBoxModel);
public Databoard(MontoyaApi api, ConfigLoader configLoader, MessageTableModel messageTableModel) {
this.api = api;

View File

@@ -2,21 +2,24 @@ package hae.component.board;
import burp.api.montoya.MontoyaApi;
import hae.component.board.message.MessageTableModel;
import hae.instances.editor.RequestEditor;
import jregex.Pattern;
import jregex.REFlags;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableRowSorter;
import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.*;
import java.util.Comparator;
import java.util.List;
import javax.swing.*;
import java.awt.datatransfer.*;
import javax.swing.event.*;
import javax.swing.table.*;
public class Datatable extends JPanel {
private final MontoyaApi api;

View File

@@ -1,18 +1,17 @@
package hae.component.board.message;
import java.awt.Color;
import java.awt.Component;
import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import java.awt.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
public class MessageRenderer extends DefaultTableCellRenderer {
private List<MessageEntry> log;
private Map<String, Color> colorMap = new HashMap<>();
private JTable table; // 保存对表格的引用
private final List<MessageEntry> log;
private final Map<String, Color> colorMap = new HashMap<>();
private final JTable table; // 保存对表格的引用
public MessageRenderer(List<MessageEntry> log, JTable table) {
this.log = log;

View File

@@ -14,18 +14,14 @@ import hae.cache.CachePool;
import hae.utils.string.HashCalculator;
import hae.utils.string.StringProcessor;
import java.nio.charset.StandardCharsets;
import java.text.MessageFormat;
import java.util.*;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.SwingWorker;
import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
import java.nio.charset.StandardCharsets;
import java.text.MessageFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
@@ -37,7 +33,7 @@ public class MessageTableModel extends AbstractTableModel {
private final JTabbedPane messageTab;
private final JSplitPane splitPane;
private final List<MessageEntry> log = new ArrayList<MessageEntry>();
private LinkedList<MessageEntry> filteredLog;
private final LinkedList<MessageEntry> filteredLog;
public MessageTableModel(MontoyaApi api) {
this.filteredLog = new LinkedList<>();
@@ -74,6 +70,7 @@ public class MessageTableModel extends AbstractTableModel {
int index2 = getIndex(s2);
return Integer.compare(index1, index2);
}
private int getIndex(String color) {
for (int i = 0; i < Config.color.length; i++) {
if (Config.color[i].equals(color)) {
@@ -120,7 +117,7 @@ public class MessageTableModel extends AbstractTableModel {
byte[] resByteB = reqResMessage.response().toByteArray().getBytes();
try {
// 通过URL、请求和响应报文、匹配数据内容多维度进行对比
if ((entry.getUrl().toString().equals(url.toString()) || (Arrays.equals(reqByteB, reqByteA) || Arrays.equals(resByteB, resByteA))) && (areMapsEqual(getCacheData(reqByteB), getCacheData(reqByteA)) && areMapsEqual(getCacheData(resByteB), getCacheData(resByteA)))) {
if ((entry.getUrl().equals(url) || (Arrays.equals(reqByteB, reqByteA) || Arrays.equals(resByteB, resByteA))) && (areMapsEqual(getCacheData(reqByteB), getCacheData(reqByteA)) && areMapsEqual(getCacheData(resByteB), getCacheData(resByteA)))) {
isDuplicate = true;
break;
}
@@ -243,6 +240,14 @@ public class MessageTableModel extends AbstractTableModel {
case "response body":
isMatch = matchingString(format, filterText, responseBody);
break;
case "request line":
String requestLine = requestString.split("\\r?\\n", 2)[0];
isMatch = matchingString(format, filterText, requestLine);
break;
case "response line":
String responseLine = responseString.split("\\r?\\n", 2)[0];
isMatch = matchingString(format, filterText, responseLine);
break;
default:
break;
}
@@ -334,13 +339,11 @@ public class MessageTableModel extends AbstractTableModel {
}
public JSplitPane getSplitPane()
{
public JSplitPane getSplitPane() {
return splitPane;
}
public MessageTable getMessageTable()
{
public MessageTable getMessageTable() {
return messageTable;
}
@@ -360,8 +363,7 @@ public class MessageTableModel extends AbstractTableModel {
}
@Override
public Object getValueAt(int rowIndex, int columnIndex)
{
public Object getValueAt(int rowIndex, int columnIndex) {
if (filteredLog.isEmpty()) {
return "";
}
@@ -379,8 +381,7 @@ public class MessageTableModel extends AbstractTableModel {
}
@Override
public String getColumnName(int columnIndex)
{
public String getColumnName(int columnIndex) {
return switch (columnIndex) {
case 0 -> "Method";
case 1 -> "URL";

View File

@@ -1,18 +1,17 @@
package hae.component.rule;
import burp.api.montoya.MontoyaApi;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import javax.swing.table.TableRowSorter;
import java.util.Vector;
import hae.Config;
import hae.utils.config.ConfigLoader;
import hae.utils.rule.RuleProcessor;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableRowSorter;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.util.Vector;
import static javax.swing.JOptionPane.YES_OPTION;
public class Rule extends JPanel {

View File

@@ -120,7 +120,7 @@ public class Rules extends JTabbedPane {
}
}
private Action renameTitleActionPerformed = new AbstractAction() {
private final Action renameTitleActionPerformed = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
String title = ruleGroupNameTextField.getText();
@@ -136,7 +136,7 @@ public class Rules extends JTabbedPane {
}
};
private Action cancelActionPerformed = new AbstractAction() {
private final Action cancelActionPerformed = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
if (selectedIndex >= 0) {

View File

@@ -3,12 +3,12 @@ package hae.instances.editor;
import burp.api.montoya.MontoyaApi;
import burp.api.montoya.core.ByteArray;
import burp.api.montoya.core.Range;
import burp.api.montoya.ui.editor.extension.EditorCreationContext;
import burp.api.montoya.ui.editor.extension.ExtensionProvidedHttpRequestEditor;
import burp.api.montoya.ui.editor.extension.HttpRequestEditorProvider;
import burp.api.montoya.http.message.HttpRequestResponse;
import burp.api.montoya.http.message.requests.HttpRequest;
import burp.api.montoya.ui.Selection;
import burp.api.montoya.ui.editor.extension.EditorCreationContext;
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;
@@ -36,10 +36,9 @@ public class RequestEditor implements HttpRequestEditorProvider {
private final MessageProcessor messageProcessor;
private HttpRequestResponse requestResponse;
private JTabbedPane jTabbedPane = new JTabbedPane();
private final JTabbedPane jTabbedPane = new JTabbedPane();
public Editor(MontoyaApi api, EditorCreationContext creationContext)
{
public Editor(MontoyaApi api, EditorCreationContext creationContext) {
this.api = api;
this.creationContext = creationContext;
this.messageProcessor = new MessageProcessor(api);

View File

@@ -5,10 +5,10 @@ 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.responses.HttpResponse;
import burp.api.montoya.ui.Selection;
import burp.api.montoya.ui.editor.extension.EditorCreationContext;
import burp.api.montoya.ui.editor.extension.ExtensionProvidedHttpResponseEditor;
import burp.api.montoya.ui.editor.extension.HttpResponseEditorProvider;
import burp.api.montoya.ui.Selection;
import hae.component.board.Datatable;
import hae.instances.http.utils.MessageProcessor;
@@ -35,10 +35,9 @@ public class ResponseEditor implements HttpResponseEditorProvider {
private final MessageProcessor messageProcessor;
private HttpRequestResponse requestResponse;
private JTabbedPane jTabbedPane = new JTabbedPane();
private final JTabbedPane jTabbedPane = new JTabbedPane();
public Editor(MontoyaApi api, EditorCreationContext creationContext)
{
public Editor(MontoyaApi api, EditorCreationContext creationContext) {
this.api = api;
this.creationContext = creationContext;
this.messageProcessor = new MessageProcessor(api);

View File

@@ -5,7 +5,9 @@ import burp.api.montoya.core.ByteArray;
import burp.api.montoya.core.Range;
import burp.api.montoya.ui.Selection;
import burp.api.montoya.ui.contextmenu.WebSocketMessage;
import burp.api.montoya.ui.editor.extension.*;
import burp.api.montoya.ui.editor.extension.EditorCreationContext;
import burp.api.montoya.ui.editor.extension.ExtensionProvidedWebSocketMessageEditor;
import burp.api.montoya.ui.editor.extension.WebSocketMessageEditorProvider;
import hae.component.board.Datatable;
import hae.instances.http.utils.MessageProcessor;
@@ -32,7 +34,7 @@ public class WebSocketEditor implements WebSocketMessageEditorProvider {
private final MessageProcessor messageProcessor;
private ByteArray message;
private JTabbedPane jTabbedPane = new JTabbedPane();
private final JTabbedPane jTabbedPane = new JTabbedPane();
public Editor(MontoyaApi api, EditorCreationContext creationContext) {
this.api = api;

View File

@@ -11,16 +11,19 @@ import hae.component.board.message.MessageTableModel;
import hae.instances.http.utils.MessageProcessor;
import hae.utils.string.StringProcessor;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class HttpMessageHandler implements HttpHandler {
private final MontoyaApi api;
private MessageTableModel messageTableModel;
private final MessageTableModel messageTableModel;
private final MessageProcessor messageProcessor;
private String host;
// Montoya API对HTTP消息的处理分为了请求和响应因此此处设置高亮和标记需要使用全局变量的方式以此兼顾请求和响应
// 同时采用 ThreadLocal 来保证多线程并发的情况下全局变量的安全性
private final ThreadLocal<String> host = ThreadLocal.withInitial(() -> "");
private final ThreadLocal<List<String>> colorList = ThreadLocal.withInitial(ArrayList::new);
private final ThreadLocal<List<String>> commentList = ThreadLocal.withInitial(ArrayList::new);
private final ThreadLocal<Boolean> matches = ThreadLocal.withInitial(() -> false);
@@ -41,13 +44,13 @@ public class HttpMessageHandler implements HttpHandler {
httpRequest.set(httpRequestToBeSent);
host = StringProcessor.getHostByUrl(httpRequestToBeSent.url());
host.set(StringProcessor.getHostByUrl(httpRequestToBeSent.url()));
List<String> suffixList = Arrays.asList(Config.suffix.split("\\|"));
matches.set(suffixList.contains(httpRequestToBeSent.fileExtension()));
if (!matches.get()) {
List<Map<String, String>> result = messageProcessor.processRequest(host, httpRequestToBeSent, true);
List<Map<String, String>> result = messageProcessor.processRequest(host.get(), httpRequestToBeSent, true);
setColorAndCommentList(result);
}
@@ -59,7 +62,7 @@ public class HttpMessageHandler implements HttpHandler {
Annotations annotations = httpResponseReceived.annotations();
if (!matches.get()) {
List<Map<String, String>> result = messageProcessor.processResponse(host, httpResponseReceived, true);
List<Map<String, String>> result = messageProcessor.processResponse(host.get(), httpResponseReceived, true);
setColorAndCommentList(result);
// 设置高亮颜色和注释
if (!colorList.get().isEmpty() && !commentList.get().isEmpty()) {

View File

@@ -24,6 +24,7 @@ public class MessageProcessor {
public List<Map<String, String>> processMessage(String host, String message, boolean flag) {
Map<String, Map<String, Object>> obj = null;
try {
obj = regularMatcher.match(host, "any", message, message, message);
} catch (Exception ignored) {
@@ -34,6 +35,7 @@ public class MessageProcessor {
public List<Map<String, String>> processResponse(String host, HttpResponse httpResponse, boolean flag) {
Map<String, Map<String, Object>> obj = null;
try {
String response = new String(httpResponse.toByteArray().getBytes(), StandardCharsets.UTF_8);
String body = new String(httpResponse.body().getBytes(), StandardCharsets.UTF_8);
@@ -57,6 +59,7 @@ public class MessageProcessor {
String header = httpRequest.headers().stream()
.map(HttpHeader::toString)
.collect(Collectors.joining("\n"));
obj = regularMatcher.match(host, "request", request, header, body);
} catch (Exception ignored) {
}
@@ -99,6 +102,7 @@ public class MessageProcessor {
String data = tempMap.get("data").toString();
extractedData.put(key, data);
});
return extractedData;
}
@@ -114,6 +118,7 @@ public class MessageProcessor {
List<List<String>> result = new ArrayList<>();
result.add(colorList);
result.add(commentList);
return result;
}
@@ -129,6 +134,7 @@ public class MessageProcessor {
}
}
}
return indices;
}

View File

@@ -1,15 +1,5 @@
package hae.utils.config;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;
import burp.api.montoya.MontoyaApi;
import burp.api.montoya.http.message.HttpRequestResponse;
import burp.api.montoya.http.message.requests.HttpRequest;
@@ -18,6 +8,12 @@ import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.representer.Representer;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
public class ConfigLoader {
private final MontoyaApi api;
private final Yaml yaml;

View File

@@ -2,11 +2,11 @@ package hae.utils.rule;
import burp.api.montoya.MontoyaApi;
import hae.Config;
import hae.utils.config.ConfigLoader;
import hae.utils.rule.model.Group;
import hae.utils.rule.model.Info;
import hae.utils.config.ConfigLoader;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.representer.Representer;
import java.io.File;
@@ -75,6 +75,7 @@ public class RuleProcessor {
Config.globalRules.put(type, x.toArray(new Object[x.size()][]));
this.rulesFormatAndSave();
}
public void removeRule(int select, String type) {
ArrayList<Object[]> x = new ArrayList<>(Arrays.asList(Config.globalRules.get(type)));
x.remove(select);