Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f387834c4d | ||
|
|
ca773f368b | ||
|
|
a6cd01300b |
@@ -38,7 +38,7 @@ HaE目前的规则一共有8个字段,分别是规则名称、规则正则、
|
|||||||
| F-Regex | 规则正则,主要用于填写正则表达式。在HaE中所需提取匹配的内容需要用`(`、`)`将正则表达式进行包裹。|
|
| F-Regex | 规则正则,主要用于填写正则表达式。在HaE中所需提取匹配的内容需要用`(`、`)`将正则表达式进行包裹。|
|
||||||
| S-Regex | 规则正则,作用及使用同F-Regex。S-Regex为二次正则,可以用于对F-Regex匹配的数据结果进行二次的匹配提取,如不需要的情况下可以留空。|
|
| S-Regex | 规则正则,作用及使用同F-Regex。S-Regex为二次正则,可以用于对F-Regex匹配的数据结果进行二次的匹配提取,如不需要的情况下可以留空。|
|
||||||
| Format | 格式化输出,在NFA引擎的正则表达式中,我们可以通过`{0}`、`{1}`、`{2}`…的方式进行取分组格式化输出。默认情况下使用`{0}`即可。 |
|
| Format | 格式化输出,在NFA引擎的正则表达式中,我们可以通过`{0}`、`{1}`、`{2}`…的方式进行取分组格式化输出。默认情况下使用`{0}`即可。 |
|
||||||
| Scope | 规则作用域,主要用于表示当前规则作用于HTTP报文的哪个部分。 |
|
| Scope | 规则作用域,主要用于表示当前规则作用于HTTP报文的哪个部分。支持请求、响应的行、头、体,以及完整的报文。 |
|
||||||
| Engine | 正则引擎,主要用于表示当前规则的正则表达式所使用的引擎。**DFA引擎**:对于文本串里的每一个字符只需扫描一次,速度快、特性少;**NFA引擎**:要翻来覆去标注字符、取消标注字符,速度慢,但是特性(如:分组、替换、分割)丰富。 |
|
| Engine | 正则引擎,主要用于表示当前规则的正则表达式所使用的引擎。**DFA引擎**:对于文本串里的每一个字符只需扫描一次,速度快、特性少;**NFA引擎**:要翻来覆去标注字符、取消标注字符,速度慢,但是特性(如:分组、替换、分割)丰富。 |
|
||||||
| Color | 规则匹配颜色,主要用于表示当前规则匹配到对应HTTP报文时所需标记的高亮颜色。在HaE中具备颜色升级算法,当出现相同颜色时会自动向上升级一个颜色进行标记。 |
|
| Color | 规则匹配颜色,主要用于表示当前规则匹配到对应HTTP报文时所需标记的高亮颜色。在HaE中具备颜色升级算法,当出现相同颜色时会自动向上升级一个颜色进行标记。 |
|
||||||
| Sensitive | 规则敏感性,主要用于表示当前规则对于大小写字母是否敏感,敏感(`True`)则严格按照大小写要求匹配,不敏感(`False`)则反之。 |
|
| Sensitive | 规则敏感性,主要用于表示当前规则对于大小写字母是否敏感,敏感(`True`)则严格按照大小写要求匹配,不敏感(`False`)则反之。 |
|
||||||
|
|||||||
@@ -13,9 +13,11 @@ public class Config {
|
|||||||
"any header",
|
"any header",
|
||||||
"any body",
|
"any body",
|
||||||
"response",
|
"response",
|
||||||
|
"response line",
|
||||||
"response header",
|
"response header",
|
||||||
"response body",
|
"response body",
|
||||||
"request",
|
"request",
|
||||||
|
"request line",
|
||||||
"request header",
|
"request header",
|
||||||
"request body"
|
"request body"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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";
|
String version = "3.0.1";
|
||||||
api.extension().setName(String.format("HaE (%s) - Highlighter and Extractor", version));
|
api.extension().setName(String.format("HaE (%s) - Highlighter and Extractor", version));
|
||||||
|
|
||||||
// 加载扩展后输出的项目信息
|
// 加载扩展后输出的项目信息
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ 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;
|
||||||
|
|
||||||
@@ -30,7 +31,6 @@ public class Datatable extends JPanel {
|
|||||||
this.api = api;
|
this.api = api;
|
||||||
this.tabName = tabName;
|
this.tabName = tabName;
|
||||||
|
|
||||||
|
|
||||||
String[] columnNames = {"#", "Information"};
|
String[] columnNames = {"#", "Information"};
|
||||||
|
|
||||||
dataTableModel = new DefaultTableModel(columnNames, 0);
|
dataTableModel = new DefaultTableModel(columnNames, 0);
|
||||||
@@ -114,19 +114,6 @@ public class Datatable extends JPanel {
|
|||||||
optionsPanel.add(Box.createHorizontalStrut(5));
|
optionsPanel.add(Box.createHorizontalStrut(5));
|
||||||
optionsPanel.add(searchField);
|
optionsPanel.add(searchField);
|
||||||
|
|
||||||
dataTable.setTransferHandler(new TransferHandler() {
|
|
||||||
@Override
|
|
||||||
public void exportToClipboard(JComponent comp, Clipboard clip, int action) throws IllegalStateException {
|
|
||||||
if (comp instanceof JTable) {
|
|
||||||
StringSelection stringSelection = new StringSelection(getSelectedData(
|
|
||||||
(JTable) comp));
|
|
||||||
clip.setContents(stringSelection, null);
|
|
||||||
} else {
|
|
||||||
super.exportToClipboard(comp, clip, action);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
add(scrollPane, BorderLayout.CENTER);
|
add(scrollPane, BorderLayout.CENTER);
|
||||||
add(optionsPanel, BorderLayout.SOUTH);
|
add(optionsPanel, BorderLayout.SOUTH);
|
||||||
}
|
}
|
||||||
@@ -186,26 +173,20 @@ public class Datatable extends JPanel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getSelectedData(JTable table) {
|
|
||||||
int[] selectRows = table.getSelectedRows();
|
|
||||||
StringBuilder selectData = new StringBuilder();
|
|
||||||
for (int row : selectRows) {
|
|
||||||
selectData.append(table.getValueAt(row, 1).toString()).append("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 便于单行复制,去除最后一个换行符
|
|
||||||
if (!selectData.isEmpty()){
|
|
||||||
selectData.deleteCharAt(selectData.length() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return selectData.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public JTable getDataTable() {
|
|
||||||
return this.dataTable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTableListener(MessageTableModel messagePanel) {
|
public void setTableListener(MessageTableModel messagePanel) {
|
||||||
|
// 表格复制功能
|
||||||
|
dataTable.setTransferHandler(new TransferHandler() {
|
||||||
|
@Override
|
||||||
|
public void exportToClipboard(JComponent comp, Clipboard clip, int action) throws IllegalStateException {
|
||||||
|
if (comp instanceof JTable) {
|
||||||
|
StringSelection stringSelection = new StringSelection(getSelectedDataAtTable((JTable) comp));
|
||||||
|
clip.setContents(stringSelection, null);
|
||||||
|
} else {
|
||||||
|
super.exportToClipboard(comp, clip, action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
dataTable.setDefaultEditor(Object.class, null);
|
dataTable.setDefaultEditor(Object.class, null);
|
||||||
|
|
||||||
// 表格内容双击事件
|
// 表格内容双击事件
|
||||||
@@ -222,5 +203,26 @@ public class Datatable extends JPanel {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getSelectedDataAtTable(JTable table) {
|
||||||
|
int[] selectRows = table.getSelectedRows();
|
||||||
|
StringBuilder selectData = new StringBuilder();
|
||||||
|
|
||||||
|
for (int row : selectRows) {
|
||||||
|
selectData.append(table.getValueAt(row, 1).toString()).append("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 便于单行复制,去除最后一个换行符
|
||||||
|
if (!selectData.isEmpty()){
|
||||||
|
selectData.deleteCharAt(selectData.length() - 1);
|
||||||
|
return selectData.toString();
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public JTable getDataTable() {
|
||||||
|
return this.dataTable;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -443,8 +443,7 @@ public class MessageTableModel extends AbstractTableModel {
|
|||||||
ByteArray[] result = (ByteArray[]) get();
|
ByteArray[] result = (ByteArray[]) get();
|
||||||
requestEditor.setRequest(HttpRequest.httpRequest(MessageEntry.getRequestResponse().httpService(), result[0]));
|
requestEditor.setRequest(HttpRequest.httpRequest(MessageEntry.getRequestResponse().httpService(), result[0]));
|
||||||
responseEditor.setResponse(HttpResponse.httpResponse(result[1]));
|
responseEditor.setResponse(HttpResponse.httpResponse(result[1]));
|
||||||
} catch (Exception e) {
|
} catch (Exception ignored) {
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import java.awt.event.*;
|
|||||||
|
|
||||||
public class Rules extends JTabbedPane {
|
public class Rules extends JTabbedPane {
|
||||||
private final MontoyaApi api;
|
private final MontoyaApi api;
|
||||||
private final ConfigLoader configLoader;
|
private ConfigLoader configLoader;
|
||||||
private final RuleProcessor ruleProcessor;
|
private final RuleProcessor ruleProcessor;
|
||||||
private final JTextField ruleGroupNameTextField;
|
private final JTextField ruleGroupNameTextField;
|
||||||
|
|
||||||
@@ -101,6 +101,8 @@ public class Rules extends JTabbedPane {
|
|||||||
|
|
||||||
public void reloadRuleGroup() {
|
public void reloadRuleGroup() {
|
||||||
removeAll();
|
removeAll();
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package hae.instances.editor;
|
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.Range;
|
||||||
import burp.api.montoya.ui.editor.extension.EditorCreationContext;
|
import burp.api.montoya.ui.editor.extension.EditorCreationContext;
|
||||||
import burp.api.montoya.ui.editor.extension.ExtensionProvidedHttpRequestEditor;
|
import burp.api.montoya.ui.editor.extension.ExtensionProvidedHttpRequestEditor;
|
||||||
import burp.api.montoya.ui.editor.extension.HttpRequestEditorProvider;
|
import burp.api.montoya.ui.editor.extension.HttpRequestEditorProvider;
|
||||||
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.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;
|
||||||
@@ -60,7 +60,7 @@ public class RequestEditor implements HttpRequestEditorProvider {
|
|||||||
HttpRequest request = requestResponse.request();
|
HttpRequest request = requestResponse.request();
|
||||||
if (request != null && !request.bodyToString().equals("Loading...")) {
|
if (request != null && !request.bodyToString().equals("Loading...")) {
|
||||||
List<Map<String, String>> result = messageProcessor.processRequest("", request, false);
|
List<Map<String, String>> result = messageProcessor.processRequest("", request, false);
|
||||||
jTabbedPane = generateTabbedPaneFromResultMap(api, result);
|
generateTabbedPaneFromResultMap(api, jTabbedPane, result);
|
||||||
return jTabbedPane.getTabCount() > 0;
|
return jTabbedPane.getTabCount() > 0;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -81,7 +81,8 @@ public class RequestEditor implements HttpRequestEditorProvider {
|
|||||||
return new Selection() {
|
return new Selection() {
|
||||||
@Override
|
@Override
|
||||||
public ByteArray contents() {
|
public ByteArray contents() {
|
||||||
return ByteArray.byteArray(Datatable.getSelectedData(((Datatable) jTabbedPane.getSelectedComponent()).getDataTable()));
|
Datatable dataTable = (Datatable) jTabbedPane.getSelectedComponent();
|
||||||
|
return ByteArray.byteArray(dataTable.getSelectedDataAtTable(dataTable.getDataTable()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -97,8 +98,8 @@ public class RequestEditor implements HttpRequestEditorProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static JTabbedPane generateTabbedPaneFromResultMap(MontoyaApi api, List<Map<String, String>> result) {
|
public static void generateTabbedPaneFromResultMap(MontoyaApi api, JTabbedPane tabbedPane, List<Map<String, String>> result) {
|
||||||
JTabbedPane tabbedPane = new JTabbedPane();
|
tabbedPane.removeAll();
|
||||||
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) {
|
||||||
@@ -109,7 +110,5 @@ public class RequestEditor implements HttpRequestEditorProvider {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return tabbedPane;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
package hae.instances.editor;
|
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.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.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.core.ByteArray;
|
|
||||||
import burp.api.montoya.core.Range;
|
|
||||||
import burp.api.montoya.ui.Selection;
|
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;
|
||||||
@@ -59,7 +59,7 @@ public class ResponseEditor implements HttpResponseEditorProvider {
|
|||||||
HttpResponse request = requestResponse.response();
|
HttpResponse request = requestResponse.response();
|
||||||
if (request != null && !request.bodyToString().equals("Loading...")) {
|
if (request != null && !request.bodyToString().equals("Loading...")) {
|
||||||
List<Map<String, String>> result = messageProcessor.processResponse("", request, false);
|
List<Map<String, String>> result = messageProcessor.processResponse("", request, false);
|
||||||
jTabbedPane = RequestEditor.generateTabbedPaneFromResultMap(api, result);
|
RequestEditor.generateTabbedPaneFromResultMap(api, jTabbedPane, result);
|
||||||
return jTabbedPane.getTabCount() > 0;
|
return jTabbedPane.getTabCount() > 0;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -80,7 +80,8 @@ public class ResponseEditor implements HttpResponseEditorProvider {
|
|||||||
return new Selection() {
|
return new Selection() {
|
||||||
@Override
|
@Override
|
||||||
public ByteArray contents() {
|
public ByteArray contents() {
|
||||||
return ByteArray.byteArray(Datatable.getSelectedData(((Datatable) jTabbedPane.getSelectedComponent()).getDataTable()));
|
Datatable dataTable = (Datatable) jTabbedPane.getSelectedComponent();
|
||||||
|
return ByteArray.byteArray(dataTable.getSelectedDataAtTable(dataTable.getDataTable()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ public class WebSocketEditor implements WebSocketMessageEditorProvider {
|
|||||||
String websocketMessage = webSocketMessage.payload().toString();
|
String websocketMessage = webSocketMessage.payload().toString();
|
||||||
if (!websocketMessage.isEmpty()) {
|
if (!websocketMessage.isEmpty()) {
|
||||||
List<Map<String, String>> result = messageProcessor.processMessage("", websocketMessage, false);
|
List<Map<String, String>> result = messageProcessor.processMessage("", websocketMessage, false);
|
||||||
jTabbedPane = RequestEditor.generateTabbedPaneFromResultMap(api, result);
|
RequestEditor.generateTabbedPaneFromResultMap(api, jTabbedPane, result);
|
||||||
return jTabbedPane.getTabCount() > 0;
|
return jTabbedPane.getTabCount() > 0;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -76,7 +76,8 @@ public class WebSocketEditor implements WebSocketMessageEditorProvider {
|
|||||||
return new Selection() {
|
return new Selection() {
|
||||||
@Override
|
@Override
|
||||||
public ByteArray contents() {
|
public ByteArray contents() {
|
||||||
return ByteArray.byteArray(Datatable.getSelectedData(((Datatable) jTabbedPane.getSelectedComponent()).getDataTable()));
|
Datatable dataTable = (Datatable) jTabbedPane.getSelectedComponent();
|
||||||
|
return ByteArray.byteArray(dataTable.getSelectedDataAtTable(dataTable.getDataTable()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -69,6 +69,10 @@ public class RegularMatcher {
|
|||||||
case "response body":
|
case "response body":
|
||||||
matchContent = body;
|
matchContent = body;
|
||||||
break;
|
break;
|
||||||
|
case "request line":
|
||||||
|
case "response line":
|
||||||
|
matchContent = message.split("\\r?\\n", 2)[0];
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user