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

@@ -8,7 +8,7 @@ import java.util.concurrent.ConcurrentHashMap;
public class Config { public class Config {
public static String suffix = "3g2|3gp|7z|aac|abw|aif|aifc|aiff|apk|arc|au|avi|azw|bat|bin|bmp|bz|bz2|cmd|cmx|cod|com|csh|css|csv|dll|doc|docx|ear|eot|epub|exe|flac|flv|gif|gz|ico|ics|ief|jar|jfif|jpe|jpeg|jpg|less|m3u|mid|midi|mjs|mkv|mov|mp2|mp3|mp4|mpa|mpe|mpeg|mpg|mpkg|mpp|mpv2|odp|ods|odt|oga|ogg|ogv|ogx|otf|pbm|pdf|pgm|png|pnm|ppm|ppt|pptx|ra|ram|rar|ras|rgb|rmi|rtf|scss|sh|snd|svg|swf|tar|tif|tiff|ttf|vsd|war|wav|weba|webm|webp|wmv|woff|woff2|xbm|xls|xlsx|xpm|xul|xwd|zip"; public static String suffix = "3g2|3gp|7z|aac|abw|aif|aifc|aiff|apk|arc|au|avi|azw|bat|bin|bmp|bz|bz2|cmd|cmx|cod|com|csh|css|csv|dll|doc|docx|ear|eot|epub|exe|flac|flv|gif|gz|ico|ics|ief|jar|jfif|jpe|jpeg|jpg|less|m3u|mid|midi|mjs|mkv|mov|mp2|mp3|mp4|mpa|mpe|mpeg|mpg|mpkg|mpp|mpv2|odp|ods|odt|oga|ogg|ogv|ogx|otf|pbm|pdf|pgm|png|pnm|ppm|ppt|pptx|ra|ram|rar|ras|rgb|rmi|rtf|scss|sh|snd|svg|swf|tar|tif|tiff|ttf|vsd|war|wav|weba|webm|webp|wmv|woff|woff2|xbm|xls|xlsx|xpm|xul|xwd|zip";
public static String[] scope = new String[] { public static String[] scope = new String[]{
"any", "any",
"any header", "any header",
"any body", "any body",
@@ -23,21 +23,21 @@ public class Config {
}; };
public static String[] ruleFields = { public static String[] ruleFields = {
"Loaded", "Name", "F-Regex", "S-Regex", "Format", "Color", "Scope", "Engine", "Sensitive" "Loaded", "Name", "F-Regex", "S-Regex", "Format", "Color", "Scope", "Engine", "Sensitive"
}; };
public static Object[][] ruleTemplate = new Object[][] { public static Object[][] ruleTemplate = new Object[][]{
{ {
false, "New Name", "(First Regex)", "(Second Regex)", "{0}", "gray", "any", "nfa", false false, "New Name", "(First Regex)", "(Second Regex)", "{0}", "gray", "any", "nfa", false
} }
}; };
public static String[] engine = new String[] { public static String[] engine = new String[]{
"nfa", "nfa",
"dfa" "dfa"
}; };
public static String[] color = new String[] { public static String[] color = new String[]{
"red", "red",
"orange", "orange",
"yellow", "yellow",

View File

@@ -16,7 +16,7 @@ public class HaE implements BurpExtension {
@Override @Override
public void initialize(MontoyaApi api) { 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)); api.extension().setName(String.format("HaE (%s) - Highlighter and Extractor", version));
// 加载扩展后输出的项目信息 // 加载扩展后输出的项目信息

View File

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

View File

@@ -28,10 +28,10 @@ public class Main extends JPanel {
private void initComponents() { private void initComponents() {
setLayout(new GridBagLayout()); setLayout(new GridBagLayout());
((GridBagLayout)getLayout()).columnWidths = new int[] {0, 0}; ((GridBagLayout) getLayout()).columnWidths = new int[]{0, 0};
((GridBagLayout)getLayout()).rowHeights = new int[] {0, 0}; ((GridBagLayout) getLayout()).rowHeights = new int[]{0, 0};
((GridBagLayout)getLayout()).columnWeights = new double[] {1.0, 1.0E-4}; ((GridBagLayout) getLayout()).columnWeights = new double[]{1.0, 1.0E-4};
((GridBagLayout)getLayout()).rowWeights = new double[] {1.0, 1.0E-4}; ((GridBagLayout) getLayout()).rowWeights = new double[]{1.0, 1.0E-4};
JTabbedPane mainTabbedPane = new JTabbedPane(); JTabbedPane mainTabbedPane = new JTabbedPane();

View File

@@ -3,20 +3,21 @@ package hae.component.board;
import burp.api.montoya.MontoyaApi; import burp.api.montoya.MontoyaApi;
import hae.Config; import hae.Config;
import hae.component.board.message.MessageTableModel; 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.component.board.message.MessageTableModel.MessageTable;
import hae.utils.config.ConfigLoader;
import hae.utils.string.StringProcessor;
import java.util.*; import javax.swing.*;
import java.util.concurrent.ConcurrentHashMap; import javax.swing.event.DocumentEvent;
import javax.swing.event.*; import javax.swing.event.DocumentListener;
import javax.swing.table.TableColumnModel; import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel; import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter; import javax.swing.table.TableRowSorter;
import java.awt.*; import java.awt.*;
import java.awt.event.*; import java.awt.event.*;
import java.util.List; import java.util.List;
import javax.swing.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public class Databoard extends JPanel { public class Databoard extends JPanel {
private final MontoyaApi api; private final MontoyaApi api;
@@ -28,8 +29,8 @@ public class Databoard extends JPanel {
private MessageTable messageTable; private MessageTable messageTable;
private static Boolean isMatchHost = false; private static Boolean isMatchHost = false;
private DefaultComboBoxModel comboBoxModel = new DefaultComboBoxModel(); private final DefaultComboBoxModel comboBoxModel = new DefaultComboBoxModel();
private JComboBox hostComboBox = new JComboBox(comboBoxModel); private final JComboBox hostComboBox = new JComboBox(comboBoxModel);
public Databoard(MontoyaApi api, ConfigLoader configLoader, MessageTableModel messageTableModel) { public Databoard(MontoyaApi api, ConfigLoader configLoader, MessageTableModel messageTableModel) {
this.api = api; this.api = api;
@@ -41,10 +42,10 @@ public class Databoard extends JPanel {
private void initComponents() { private void initComponents() {
setLayout(new GridBagLayout()); setLayout(new GridBagLayout());
((GridBagLayout)getLayout()).columnWidths = new int[] {25, 0, 0, 0,20, 0}; ((GridBagLayout) getLayout()).columnWidths = new int[]{25, 0, 0, 0, 20, 0};
((GridBagLayout)getLayout()).rowHeights = new int[] {0, 65, 20, 0}; ((GridBagLayout) getLayout()).rowHeights = new int[]{0, 65, 20, 0};
((GridBagLayout)getLayout()).columnWeights = new double[] {0.0, 0.0, 1.0, 0.0, 0.0, 1.0E-4}; ((GridBagLayout) getLayout()).columnWeights = new double[]{0.0, 0.0, 1.0, 0.0, 0.0, 1.0E-4};
((GridBagLayout)getLayout()).rowWeights = new double[] {0.0, 1.0, 0.0, 1.0E-4}; ((GridBagLayout) getLayout()).rowWeights = new double[]{0.0, 1.0, 0.0, 1.0E-4};
JLabel hostLabel = new JLabel("Host:"); JLabel hostLabel = new JLabel("Host:");
@@ -81,7 +82,7 @@ public class Databoard extends JPanel {
new Insets(8, 0, 5, 5), 0, 0)); new Insets(8, 0, 5, 5), 0, 0));
add(hostTextField, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, add(hostTextField, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(8, 0, 5, 5), 0, 0)); new Insets(8, 0, 5, 5), 0, 0));
add(actionButton, new GridBagConstraints(3, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, add(actionButton, new GridBagConstraints(3, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(8, 0, 5, 5), 0, 0)); new Insets(8, 0, 5, 5), 0, 0));
add(splitPane, new GridBagConstraints(1, 1, 3, 3, 0.0, 0.0, add(splitPane, new GridBagConstraints(1, 1, 3, 3, 0.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
@@ -196,7 +197,7 @@ public class Databoard extends JPanel {
Map<String, List<String>> selectedDataMap; Map<String, List<String>> selectedDataMap;
dataTabbedPane.removeAll(); dataTabbedPane.removeAll();
dataTabbedPane.setPreferredSize(new Dimension(500,0)); dataTabbedPane.setPreferredSize(new Dimension(500, 0));
dataTabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT); dataTabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
splitPane.setLeftComponent(dataTabbedPane); splitPane.setLeftComponent(dataTabbedPane);

View File

@@ -2,21 +2,24 @@ package hae.component.board;
import burp.api.montoya.MontoyaApi; import burp.api.montoya.MontoyaApi;
import hae.component.board.message.MessageTableModel; import hae.component.board.message.MessageTableModel;
import hae.instances.editor.RequestEditor;
import jregex.Pattern; import jregex.Pattern;
import jregex.REFlags; 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.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.FocusEvent; import java.awt.event.FocusEvent;
import java.awt.event.FocusListener; import java.awt.event.FocusListener;
import java.awt.event.MouseAdapter; import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.util.*; import java.util.Comparator;
import java.util.List; import java.util.List;
import javax.swing.*;
import java.awt.datatransfer.*;
import javax.swing.event.*;
import javax.swing.table.*;
public class Datatable extends JPanel { public class Datatable extends JPanel {
private final MontoyaApi api; private final MontoyaApi api;
@@ -213,7 +216,7 @@ public class Datatable extends JPanel {
} }
// 便于单行复制,去除最后一个换行符 // 便于单行复制,去除最后一个换行符
if (!selectData.isEmpty()){ if (!selectData.isEmpty()) {
selectData.deleteCharAt(selectData.length() - 1); selectData.deleteCharAt(selectData.length() - 1);
return selectData.toString(); return selectData.toString();
} else { } else {

View File

@@ -1,18 +1,17 @@
package hae.component.board.message; package hae.component.board.message;
import java.awt.Color; import javax.swing.*;
import java.awt.Component; import javax.swing.table.DefaultTableCellRenderer;
import java.awt.*;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
public class MessageRenderer extends DefaultTableCellRenderer { public class MessageRenderer extends DefaultTableCellRenderer {
private List<MessageEntry> log; private final List<MessageEntry> log;
private Map<String, Color> colorMap = new HashMap<>(); private final Map<String, Color> colorMap = new HashMap<>();
private JTable table; // 保存对表格的引用 private final JTable table; // 保存对表格的引用
public MessageRenderer(List<MessageEntry> log, JTable table) { public MessageRenderer(List<MessageEntry> log, JTable table) {
this.log = log; this.log = log;
@@ -42,7 +41,7 @@ public class MessageRenderer extends DefaultTableCellRenderer {
if (isSelected) { if (isSelected) {
// 通过更改RGB颜色来达成阴影效果 // 通过更改RGB颜色来达成阴影效果
component.setBackground(new Color(color.getRed()-0x20, color.getGreen()-0x20, color.getBlue()-0x20)); component.setBackground(new Color(color.getRed() - 0x20, color.getGreen() - 0x20, color.getBlue() - 0x20));
} else { } else {
// 否则使用原始颜色 // 否则使用原始颜色
component.setBackground(color); component.setBackground(color);

View File

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

View File

@@ -23,10 +23,10 @@ public class Config extends JPanel {
private void initComponents() { private void initComponents() {
setLayout(new GridBagLayout()); setLayout(new GridBagLayout());
((GridBagLayout) getLayout()).columnWidths = new int[] {0, 0, 0, 0, 0}; ((GridBagLayout) getLayout()).columnWidths = new int[]{0, 0, 0, 0, 0};
((GridBagLayout) getLayout()).rowHeights = new int[] {0, 0, 0}; ((GridBagLayout) getLayout()).rowHeights = new int[]{0, 0, 0};
((GridBagLayout) getLayout()).columnWeights = new double[] {0.0, 1.0, 0.0, 0.0, 1.0E-4}; ((GridBagLayout) getLayout()).columnWeights = new double[]{0.0, 1.0, 0.0, 0.0, 1.0E-4};
((GridBagLayout) getLayout()).rowWeights = new double[] {0.0, 0.0, 1.0E-4}; ((GridBagLayout) getLayout()).rowWeights = new double[]{0.0, 0.0, 1.0E-4};
JLabel rulesFilePathLabel = new JLabel("Rules Path:"); JLabel rulesFilePathLabel = new JLabel("Rules Path:");
JTextField rulesFilePathTextField = new JTextField(); JTextField rulesFilePathTextField = new JTextField();

View File

@@ -1,18 +1,17 @@
package hae.component.rule; package hae.component.rule;
import burp.api.montoya.MontoyaApi; 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.Config;
import hae.utils.config.ConfigLoader; import hae.utils.config.ConfigLoader;
import hae.utils.rule.RuleProcessor; 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; import static javax.swing.JOptionPane.YES_OPTION;
public class Rule extends JPanel { public class Rule extends JPanel {
@@ -32,10 +31,10 @@ public class Rule extends JPanel {
private void initComponents(Object[][] data) { private void initComponents(Object[][] data) {
setLayout(new GridBagLayout()); setLayout(new GridBagLayout());
((GridBagLayout)getLayout()).columnWidths = new int[] {0, 0, 0}; ((GridBagLayout) getLayout()).columnWidths = new int[]{0, 0, 0};
((GridBagLayout)getLayout()).rowHeights = new int[] {0, 0, 0, 0, 0}; ((GridBagLayout) getLayout()).rowHeights = new int[]{0, 0, 0, 0, 0};
((GridBagLayout)getLayout()).columnWeights = new double[] {0.0, 1.0, 1.0E-4}; ((GridBagLayout) getLayout()).columnWeights = new double[]{0.0, 1.0, 1.0E-4};
((GridBagLayout)getLayout()).rowWeights = new double[] {0.0, 0.0, 0.0, 1.0, 1.0E-4}; ((GridBagLayout) getLayout()).rowWeights = new double[]{0.0, 0.0, 0.0, 1.0, 1.0E-4};
JButton addButton = new JButton("Add"); JButton addButton = new JButton("Add");
JButton editButton = new JButton("Edit"); JButton editButton = new JButton("Edit");
@@ -74,7 +73,7 @@ public class Rule extends JPanel {
model.setDataVector(data, Config.ruleFields); model.setDataVector(data, Config.ruleFields);
model.addTableModelListener(e -> { model.addTableModelListener(e -> {
if (e.getColumn() == 0 && ruleTable.getSelectedRow() != -1){ if (e.getColumn() == 0 && ruleTable.getSelectedRow() != -1) {
int select = ruleTable.convertRowIndexToModel(ruleTable.getSelectedRow()); int select = ruleTable.convertRowIndexToModel(ruleTable.getSelectedRow());
ruleProcessor.changeRule(model.getDataVector().get(select), select, tabbedPane.getTitleAt(tabbedPane.getSelectedIndex())); ruleProcessor.changeRule(model.getDataVector().get(select), select, tabbedPane.getTitleAt(tabbedPane.getSelectedIndex()));
} }
@@ -117,8 +116,8 @@ public class Rule extends JPanel {
} }
} }
private void ruleEditActionPerformed(ActionEvent e, JTable ruleTable, JTabbedPane tabbedPane){ private void ruleEditActionPerformed(ActionEvent e, JTable ruleTable, JTabbedPane tabbedPane) {
if (ruleTable.getSelectedRowCount() >= 1){ if (ruleTable.getSelectedRowCount() >= 1) {
DefaultTableModel model = (DefaultTableModel) ruleTable.getModel(); DefaultTableModel model = (DefaultTableModel) ruleTable.getModel();
Display ruleDisplay = new Display(); Display ruleDisplay = new Display();
@@ -129,12 +128,12 @@ public class Rule extends JPanel {
ruleDisplay.colorComboBox.setSelectedItem(ruleTable.getValueAt(ruleTable.getSelectedRow(), 5).toString()); ruleDisplay.colorComboBox.setSelectedItem(ruleTable.getValueAt(ruleTable.getSelectedRow(), 5).toString());
ruleDisplay.scopeComboBox.setSelectedItem(ruleTable.getValueAt(ruleTable.getSelectedRow(), 6).toString()); ruleDisplay.scopeComboBox.setSelectedItem(ruleTable.getValueAt(ruleTable.getSelectedRow(), 6).toString());
ruleDisplay.engineComboBox.setSelectedItem(ruleTable.getValueAt(ruleTable.getSelectedRow(), 7).toString()); ruleDisplay.engineComboBox.setSelectedItem(ruleTable.getValueAt(ruleTable.getSelectedRow(), 7).toString());
ruleDisplay.sensitiveComboBox.setSelectedItem(ruleTable.getValueAt(ruleTable.getSelectedRow(),8)); ruleDisplay.sensitiveComboBox.setSelectedItem(ruleTable.getValueAt(ruleTable.getSelectedRow(), 8));
ruleDisplay.formatTextField.setEnabled(ruleDisplay.engineComboBox.getSelectedItem().toString().equals("nfa")); ruleDisplay.formatTextField.setEnabled(ruleDisplay.engineComboBox.getSelectedItem().toString().equals("nfa"));
int showState = JOptionPane.showConfirmDialog(null, ruleDisplay, "Edit Rule", JOptionPane.OK_OPTION); int showState = JOptionPane.showConfirmDialog(null, ruleDisplay, "Edit Rule", JOptionPane.OK_OPTION);
if (showState == 0){ if (showState == 0) {
int select = ruleTable.convertRowIndexToModel(ruleTable.getSelectedRow()); int select = ruleTable.convertRowIndexToModel(ruleTable.getSelectedRow());
model.setValueAt(ruleDisplay.ruleNameTextField.getText(), select, 1); model.setValueAt(ruleDisplay.ruleNameTextField.getText(), select, 1);
model.setValueAt(ruleDisplay.firstRegexTextField.getText(), select, 2); model.setValueAt(ruleDisplay.firstRegexTextField.getText(), select, 2);
@@ -150,9 +149,9 @@ public class Rule extends JPanel {
} }
} }
private void ruleRemoveActionPerformed(ActionEvent e, JTable ruleTable, JTabbedPane tabbedPane){ private void ruleRemoveActionPerformed(ActionEvent e, JTable ruleTable, JTabbedPane tabbedPane) {
if (ruleTable.getSelectedRowCount() >= 1){ if (ruleTable.getSelectedRowCount() >= 1) {
if (JOptionPane.showConfirmDialog(null, "Are you sure you want to delete this rule?", "Info", JOptionPane.OK_OPTION) == 0){ if (JOptionPane.showConfirmDialog(null, "Are you sure you want to delete this rule?", "Info", JOptionPane.OK_OPTION) == 0) {
DefaultTableModel model = (DefaultTableModel) ruleTable.getModel(); DefaultTableModel model = (DefaultTableModel) ruleTable.getModel();
int select = ruleTable.convertRowIndexToModel(ruleTable.getSelectedRow()); int select = ruleTable.convertRowIndexToModel(ruleTable.getSelectedRow());

View File

@@ -103,7 +103,7 @@ public class Rules extends JTabbedPane {
removeAll(); removeAll();
this.configLoader = new ConfigLoader(api); this.configLoader = new ConfigLoader(api);
Config.globalRules.keySet().forEach(i-> addTab(i, new Rule(api, configLoader, hae.Config.globalRules.get(i), this))); Config.globalRules.keySet().forEach(i -> addTab(i, new Rule(api, configLoader, hae.Config.globalRules.get(i), this)));
addTab("...", null); addTab("...", null);
} }
@@ -120,7 +120,7 @@ public class Rules extends JTabbedPane {
} }
} }
private Action renameTitleActionPerformed = new AbstractAction() { private final Action renameTitleActionPerformed = new AbstractAction() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
String title = ruleGroupNameTextField.getText(); 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 @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
if (selectedIndex >= 0) { if (selectedIndex >= 0) {

View File

@@ -3,12 +3,12 @@ package hae.instances.editor;
import burp.api.montoya.MontoyaApi; import burp.api.montoya.MontoyaApi;
import burp.api.montoya.core.ByteArray; import burp.api.montoya.core.ByteArray;
import burp.api.montoya.core.Range; 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.HttpRequestResponse;
import burp.api.montoya.http.message.requests.HttpRequest; import burp.api.montoya.http.message.requests.HttpRequest;
import burp.api.montoya.ui.Selection; 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.component.board.Datatable;
import hae.instances.http.utils.MessageProcessor; import hae.instances.http.utils.MessageProcessor;
@@ -36,10 +36,9 @@ public class RequestEditor implements HttpRequestEditorProvider {
private final MessageProcessor messageProcessor; private final MessageProcessor messageProcessor;
private HttpRequestResponse requestResponse; 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.api = api;
this.creationContext = creationContext; this.creationContext = creationContext;
this.messageProcessor = new MessageProcessor(api); this.messageProcessor = new MessageProcessor(api);
@@ -103,7 +102,7 @@ public class RequestEditor implements HttpRequestEditorProvider {
if (result != null && !result.isEmpty() && result.size() > 0) { if (result != null && !result.isEmpty() && result.size() > 0) {
Map<String, String> dataMap = result.get(0); Map<String, String> dataMap = result.get(0);
if (dataMap != null && !dataMap.isEmpty() && dataMap.size() > 0) { if (dataMap != null && !dataMap.isEmpty() && dataMap.size() > 0) {
dataMap.keySet().forEach(i->{ dataMap.keySet().forEach(i -> {
String[] extractData = dataMap.get(i).split("\n"); String[] extractData = dataMap.get(i).split("\n");
Datatable dataPanel = new Datatable(api, i, Arrays.asList(extractData)); Datatable dataPanel = new Datatable(api, i, Arrays.asList(extractData));
tabbedPane.addTab(i, dataPanel); tabbedPane.addTab(i, dataPanel);

View File

@@ -5,10 +5,10 @@ import burp.api.montoya.core.ByteArray;
import burp.api.montoya.core.Range; import burp.api.montoya.core.Range;
import burp.api.montoya.http.message.HttpRequestResponse; import burp.api.montoya.http.message.HttpRequestResponse;
import burp.api.montoya.http.message.responses.HttpResponse; 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.EditorCreationContext;
import burp.api.montoya.ui.editor.extension.ExtensionProvidedHttpResponseEditor; import burp.api.montoya.ui.editor.extension.ExtensionProvidedHttpResponseEditor;
import burp.api.montoya.ui.editor.extension.HttpResponseEditorProvider; import burp.api.montoya.ui.editor.extension.HttpResponseEditorProvider;
import burp.api.montoya.ui.Selection;
import hae.component.board.Datatable; import hae.component.board.Datatable;
import hae.instances.http.utils.MessageProcessor; import hae.instances.http.utils.MessageProcessor;
@@ -35,10 +35,9 @@ public class ResponseEditor implements HttpResponseEditorProvider {
private final MessageProcessor messageProcessor; private final MessageProcessor messageProcessor;
private HttpRequestResponse requestResponse; 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.api = api;
this.creationContext = creationContext; this.creationContext = creationContext;
this.messageProcessor = new MessageProcessor(api); 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.core.Range;
import burp.api.montoya.ui.Selection; import burp.api.montoya.ui.Selection;
import burp.api.montoya.ui.contextmenu.WebSocketMessage; 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.component.board.Datatable;
import hae.instances.http.utils.MessageProcessor; import hae.instances.http.utils.MessageProcessor;
@@ -32,7 +34,7 @@ public class WebSocketEditor implements WebSocketMessageEditorProvider {
private final MessageProcessor messageProcessor; private final MessageProcessor messageProcessor;
private ByteArray message; private ByteArray message;
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.api = api;

View File

@@ -11,16 +11,19 @@ import hae.component.board.message.MessageTableModel;
import hae.instances.http.utils.MessageProcessor; import hae.instances.http.utils.MessageProcessor;
import hae.utils.string.StringProcessor; 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 { public class HttpMessageHandler implements HttpHandler {
private final MontoyaApi api; private final MontoyaApi api;
private MessageTableModel messageTableModel; private final MessageTableModel messageTableModel;
private final MessageProcessor messageProcessor; private final MessageProcessor messageProcessor;
private String host;
// Montoya API对HTTP消息的处理分为了请求和响应因此此处设置高亮和标记需要使用全局变量的方式以此兼顾请求和响应 // Montoya API对HTTP消息的处理分为了请求和响应因此此处设置高亮和标记需要使用全局变量的方式以此兼顾请求和响应
// 同时采用 ThreadLocal 来保证多线程并发的情况下全局变量的安全性 // 同时采用 ThreadLocal 来保证多线程并发的情况下全局变量的安全性
private final ThreadLocal<String> host = ThreadLocal.withInitial(() -> "");
private final ThreadLocal<List<String>> colorList = ThreadLocal.withInitial(ArrayList::new); private final ThreadLocal<List<String>> colorList = ThreadLocal.withInitial(ArrayList::new);
private final ThreadLocal<List<String>> commentList = ThreadLocal.withInitial(ArrayList::new); private final ThreadLocal<List<String>> commentList = ThreadLocal.withInitial(ArrayList::new);
private final ThreadLocal<Boolean> matches = ThreadLocal.withInitial(() -> false); private final ThreadLocal<Boolean> matches = ThreadLocal.withInitial(() -> false);
@@ -41,13 +44,13 @@ public class HttpMessageHandler implements HttpHandler {
httpRequest.set(httpRequestToBeSent); httpRequest.set(httpRequestToBeSent);
host = StringProcessor.getHostByUrl(httpRequestToBeSent.url()); host.set(StringProcessor.getHostByUrl(httpRequestToBeSent.url()));
List<String> suffixList = Arrays.asList(Config.suffix.split("\\|")); List<String> suffixList = Arrays.asList(Config.suffix.split("\\|"));
matches.set(suffixList.contains(httpRequestToBeSent.fileExtension())); matches.set(suffixList.contains(httpRequestToBeSent.fileExtension()));
if (!matches.get()) { 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); setColorAndCommentList(result);
} }
@@ -59,7 +62,7 @@ public class HttpMessageHandler implements HttpHandler {
Annotations annotations = httpResponseReceived.annotations(); Annotations annotations = httpResponseReceived.annotations();
if (!matches.get()) { 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); setColorAndCommentList(result);
// 设置高亮颜色和注释 // 设置高亮颜色和注释
if (!colorList.get().isEmpty() && !commentList.get().isEmpty()) { 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) { public List<Map<String, String>> processMessage(String host, String message, boolean flag) {
Map<String, Map<String, Object>> obj = null; Map<String, Map<String, Object>> obj = null;
try { try {
obj = regularMatcher.match(host, "any", message, message, message); obj = regularMatcher.match(host, "any", message, message, message);
} catch (Exception ignored) { } catch (Exception ignored) {
@@ -34,6 +35,7 @@ public class MessageProcessor {
public List<Map<String, String>> processResponse(String host, HttpResponse httpResponse, boolean flag) { public List<Map<String, String>> processResponse(String host, HttpResponse httpResponse, boolean flag) {
Map<String, Map<String, Object>> obj = null; Map<String, Map<String, Object>> obj = null;
try { try {
String response = new String(httpResponse.toByteArray().getBytes(), StandardCharsets.UTF_8); String response = new String(httpResponse.toByteArray().getBytes(), StandardCharsets.UTF_8);
String body = new String(httpResponse.body().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() String header = httpRequest.headers().stream()
.map(HttpHeader::toString) .map(HttpHeader::toString)
.collect(Collectors.joining("\n")); .collect(Collectors.joining("\n"));
obj = regularMatcher.match(host, "request", request, header, body); obj = regularMatcher.match(host, "request", request, header, body);
} catch (Exception ignored) { } catch (Exception ignored) {
} }
@@ -99,6 +102,7 @@ public class MessageProcessor {
String data = tempMap.get("data").toString(); String data = tempMap.get("data").toString();
extractedData.put(key, data); extractedData.put(key, data);
}); });
return extractedData; return extractedData;
} }
@@ -114,10 +118,11 @@ public class MessageProcessor {
List<List<String>> result = new ArrayList<>(); List<List<String>> result = new ArrayList<>();
result.add(colorList); result.add(colorList);
result.add(commentList); result.add(commentList);
return result; return result;
} }
public List<Integer> retrieveColorIndices(List<String> colors){ public List<Integer> retrieveColorIndices(List<String> colors) {
List<Integer> indices = new ArrayList<>(); List<Integer> indices = new ArrayList<>();
String[] colorArray = Config.color; String[] colorArray = Config.color;
int size = colorArray.length; int size = colorArray.length;
@@ -129,6 +134,7 @@ public class MessageProcessor {
} }
} }
} }
return indices; return indices;
} }
@@ -154,7 +160,7 @@ public class MessageProcessor {
HashSet tmpList = new HashSet(stack); HashSet tmpList = new HashSet(stack);
if (stack.size() == tmpList.size()) { if (stack.size() == tmpList.size()) {
stack.sort(Comparator.comparingInt(Integer::intValue)); stack.sort(Comparator.comparingInt(Integer::intValue));
if(stack.get(0) < 0) { if (stack.get(0) < 0) {
finalColor = colorArray[0]; finalColor = colorArray[0];
} else { } else {
finalColor = colorArray[stack.get(0)]; finalColor = colorArray[stack.get(0)];

View File

@@ -202,8 +202,8 @@ public class RegularMatcher {
while (matcher.find()) { while (matcher.find()) {
if (!matcher.group(1).isEmpty()) { if (!matcher.group(1).isEmpty()) {
Object[] params = indexList.stream().map(i -> { Object[] params = indexList.stream().map(i -> {
if (!matcher.group(i+1).isEmpty()) { if (!matcher.group(i + 1).isEmpty()) {
return matcher.group(i+1); return matcher.group(i + 1);
} }
return ""; return "";
}).toArray(); }).toArray();

View File

@@ -1,15 +1,5 @@
package hae.utils.config; 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.MontoyaApi;
import burp.api.montoya.http.message.HttpRequestResponse; import burp.api.montoya.http.message.HttpRequestResponse;
import burp.api.montoya.http.message.requests.HttpRequest; 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.Yaml;
import org.yaml.snakeyaml.representer.Representer; 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 { public class ConfigLoader {
private final MontoyaApi api; private final MontoyaApi api;
private final Yaml yaml; private final Yaml yaml;
@@ -32,7 +28,7 @@ public class ConfigLoader {
this.yaml = new Yaml(representer, dop); this.yaml = new Yaml(representer, dop);
String configPath = determineConfigPath(); String configPath = determineConfigPath();
this.configFilePath = String.format("%s/%s", configPath, "Config.yml"); this.configFilePath = String.format("%s/%s", configPath, "Config.yml");
this.rulesFilePath = String.format("%s/%s", configPath, "Rules.yml"); this.rulesFilePath = String.format("%s/%s", configPath, "Rules.yml");
// 构造函数,初始化配置 // 构造函数,初始化配置
@@ -104,7 +100,7 @@ public class ConfigLoader {
if (r.containsKey("excludeSuffix")) { if (r.containsKey("excludeSuffix")) {
return r.get("excludeSuffix").toString(); return r.get("excludeSuffix").toString();
} }
}catch (Exception ignored) { } catch (Exception ignored) {
} }
return Config.suffix; return Config.suffix;
@@ -147,16 +143,16 @@ public class ConfigLoader {
} }
return rules; return rules;
} catch (Exception ignored){ } catch (Exception ignored) {
} }
return rules; return rules;
} }
public void setExcludeSuffix(String excludeSuffix) { public void setExcludeSuffix(String excludeSuffix) {
Map<String,Object> r = new LinkedHashMap<>(); Map<String, Object> r = new LinkedHashMap<>();
r.put("excludeSuffix", excludeSuffix); r.put("excludeSuffix", excludeSuffix);
try{ try {
Writer ws = new OutputStreamWriter(Files.newOutputStream(Paths.get(configFilePath)), StandardCharsets.UTF_8); Writer ws = new OutputStreamWriter(Files.newOutputStream(Paths.get(configFilePath)), StandardCharsets.UTF_8);
yaml.dump(r, ws); yaml.dump(r, ws);
ws.close(); ws.close();

View File

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

View File

@@ -3,7 +3,7 @@ package hae.utils.string;
import java.security.MessageDigest; import java.security.MessageDigest;
public class HashCalculator { public class HashCalculator {
public static String calculateHash(byte[] bytes){ public static String calculateHash(byte[] bytes) {
MessageDigest digest; MessageDigest digest;
try { try {
digest = MessageDigest.getInstance("MD5"); digest = MessageDigest.getInstance("MD5");