Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6014089594 | ||
|
|
910658f2e0 | ||
|
|
8692b0a494 | ||
|
|
5419d4a679 | ||
|
|
ae8cb2fd25 | ||
|
|
5b6bdbe5b6 | ||
|
|
ddb08e9a6e | ||
|
|
6a2f289d57 | ||
|
|
84746a7089 |
4
.github/ISSUE_TEMPLATE/问题反馈.md
vendored
4
.github/ISSUE_TEMPLATE/问题反馈.md
vendored
@@ -14,7 +14,9 @@ HaE 版本:
|
||||
有无自定义规则:
|
||||
BurpSuite 版本:
|
||||
操作系统版本:
|
||||
有无仔细阅读README:
|
||||
是否阅读README:
|
||||
是否知晓注意事项:
|
||||
是否查阅历史ISSUE:
|
||||
```
|
||||
|
||||
## 问题详情
|
||||
|
||||
@@ -12,9 +12,14 @@
|
||||
|
||||
> 随着现代化Web应用采用前后端分离的开发模式,日常漏洞挖掘的过程中,捕获的HTTP请求流量也相应增加。若想全面评估一个Web应用,会花费大量时间在无用的报文上。**HaE的出现旨在解决这类情况**,借助HaE,您能够**有效减少**测试时间,将更多精力集中在**有价值且有意义**的报文上,从而**提高漏洞挖掘效率**。
|
||||
|
||||
GitHub项目地址:https://github.com/gh0stkey/HaE
|
||||
|
||||
GitCode项目地址:https://gitcode.com/gh0stkey/HaE
|
||||
|
||||
**所获荣誉**:
|
||||
|
||||
1. [入选2022年KCon兵器谱](https://mp.weixin.qq.com/s/JohMsl1WD29LHCHuLf8mVQ)
|
||||
2. [入选GitCode G-Star项目](https://gitcode.com/gh0stkey/HaE)
|
||||
|
||||
**注意事项**:
|
||||
|
||||
|
||||
@@ -22,6 +22,8 @@ dependencies {
|
||||
implementation 'org.yaml:snakeyaml:2.0'
|
||||
implementation 'dk.brics.automaton:automaton:1.11-8'
|
||||
implementation 'com.github.ben-manes.caffeine:caffeine:3.1.8'
|
||||
implementation 'com.google.code.gson:gson:2.11.0'
|
||||
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
|
||||
}
|
||||
|
||||
test {
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 320 KiB After Width: | Height: | Size: 187 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 331 KiB After Width: | Height: | Size: 318 KiB |
@@ -12,6 +12,10 @@ public class Config {
|
||||
|
||||
public static String status = "404";
|
||||
|
||||
public static String size = "0";
|
||||
|
||||
public static String boundary = "\n\t\n";
|
||||
|
||||
public static String[] scope = new String[]{
|
||||
"any",
|
||||
"any header",
|
||||
|
||||
@@ -18,7 +18,7 @@ public class HaE implements BurpExtension {
|
||||
@Override
|
||||
public void initialize(MontoyaApi api) {
|
||||
// 设置扩展名称
|
||||
String version = "3.3.1";
|
||||
String version = "3.3.4";
|
||||
api.extension().setName(String.format("HaE (%s) - Highlighter and Extractor", version));
|
||||
|
||||
// 加载扩展后输出的项目信息
|
||||
@@ -30,7 +30,7 @@ public class HaE implements BurpExtension {
|
||||
// 配置文件加载
|
||||
ConfigLoader configLoader = new ConfigLoader(api);
|
||||
|
||||
MessageTableModel messageTableModel = new MessageTableModel(api);
|
||||
MessageTableModel messageTableModel = new MessageTableModel(api, configLoader);
|
||||
|
||||
// 注册Tab页(用于查询数据)
|
||||
api.userInterface().registerSuiteTab("HaE", new Main(api, configLoader, messageTableModel));
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package hae.component.config;
|
||||
package hae.component;
|
||||
|
||||
import burp.api.montoya.MontoyaApi;
|
||||
import hae.component.rule.Rules;
|
||||
@@ -66,7 +66,7 @@ public class Config extends JPanel {
|
||||
constraints.gridx = 1;
|
||||
JTabbedPane configTabbedPanel = new JTabbedPane();
|
||||
|
||||
String[] settingMode = new String[]{"Exclude suffix", "Block host", "Exclude status"};
|
||||
String[] settingMode = new String[]{"Exclude suffix", "Block host", "Exclude status", "Limit size (MB)"};
|
||||
JPanel settingPanel = createConfigTablePanel(settingMode, "Setting");
|
||||
JPanel scopePanel = getScopePanel();
|
||||
JScrollPane scopeScrollPane = new JScrollPane(scopePanel);
|
||||
@@ -153,6 +153,13 @@ public class Config extends JPanel {
|
||||
configLoader.setExcludeStatus(values);
|
||||
}
|
||||
}
|
||||
|
||||
if (selected.contains("Limit size")) {
|
||||
if (!values.equals(configLoader.getExcludeStatus()) && !values.isEmpty()) {
|
||||
String[] limit = values.split("\\|");
|
||||
configLoader.setLimitSize(limit[limit.length - 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -175,6 +182,10 @@ public class Config extends JPanel {
|
||||
if (selected.equals("Exclude status")) {
|
||||
addDataToTable(configLoader.getExcludeStatus().replaceAll("\\|", "\r\n"), model);
|
||||
}
|
||||
|
||||
if (selected.contains("Limit size")) {
|
||||
addDataToTable(configLoader.getLimitSize(), model);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -279,13 +290,13 @@ public class Config extends JPanel {
|
||||
settingPanel.add(inputPanel, BorderLayout.CENTER);
|
||||
|
||||
|
||||
addButton.addActionListener(e -> addActionPerformed(e, model, addTextField));
|
||||
addButton.addActionListener(e -> addActionPerformed(e, model, addTextField, setTypeComboBox.getSelectedItem().toString()));
|
||||
|
||||
addTextField.addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
|
||||
addActionPerformed(null, model, addTextField);
|
||||
addActionPerformed(null, model, addTextField, setTypeComboBox.getSelectedItem().toString());
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -294,7 +305,9 @@ public class Config extends JPanel {
|
||||
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||
try {
|
||||
String data = (String) clipboard.getData(DataFlavor.stringFlavor);
|
||||
|
||||
if (setTypeComboBox.getSelectedItem().toString().contains("Limit size")) {
|
||||
model.setRowCount(0);
|
||||
}
|
||||
if (data != null && !data.isEmpty()) {
|
||||
addDataToTable(data, model);
|
||||
}
|
||||
@@ -385,15 +398,17 @@ public class Config extends JPanel {
|
||||
configLoader.setScope(String.join("|", HaEScope));
|
||||
}
|
||||
|
||||
private void addActionPerformed(ActionEvent e, DefaultTableModel model, JTextField addTextField) {
|
||||
private void addActionPerformed(ActionEvent e, DefaultTableModel model, JTextField addTextField, String comboBoxSelected) {
|
||||
String addTextFieldText = addTextField.getText();
|
||||
api.logging().logToOutput(addTextFieldText);
|
||||
if (!addTextFieldText.equals(defaultText)) {
|
||||
addDataToTable(addTextFieldText, model);
|
||||
if (addTextField.getForeground().equals(Color.BLACK)) {
|
||||
if (comboBoxSelected.contains("Limit size")) {
|
||||
model.setRowCount(0);
|
||||
}
|
||||
addDataToTable(addTextFieldText, model);
|
||||
addTextField.setText("");
|
||||
addTextField.requestFocusInWindow();
|
||||
}
|
||||
}
|
||||
|
||||
private void onlineUpdateActionPerformed(ActionEvent e) {
|
||||
// 添加提示框防止用户误触导致配置更新
|
||||
@@ -3,7 +3,6 @@ package hae.component;
|
||||
import burp.api.montoya.MontoyaApi;
|
||||
import hae.component.board.Databoard;
|
||||
import hae.component.board.message.MessageTableModel;
|
||||
import hae.component.config.Config;
|
||||
import hae.component.rule.Rules;
|
||||
import hae.utils.ConfigLoader;
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import hae.component.board.message.MessageTableModel.MessageTable;
|
||||
import hae.component.board.table.Datatable;
|
||||
import hae.instances.http.utils.RegularMatcher;
|
||||
import hae.utils.ConfigLoader;
|
||||
import hae.utils.UIEnhancer;
|
||||
import hae.utils.project.ProjectProcessor;
|
||||
import hae.utils.project.model.HaeFileContent;
|
||||
import hae.utils.string.StringProcessor;
|
||||
@@ -54,6 +55,8 @@ public class Databoard extends JPanel {
|
||||
private SwingWorker<List<Object[]>, Void> exportActionWorker;
|
||||
private SwingWorker<List<Object[]>, Void> importActionWorker;
|
||||
|
||||
private final String defaultText = "Please enter the host";
|
||||
|
||||
public Databoard(MontoyaApi api, ConfigLoader configLoader, MessageTableModel messageTableModel) {
|
||||
this.api = api;
|
||||
this.configLoader = configLoader;
|
||||
@@ -85,6 +88,7 @@ public class Databoard extends JPanel {
|
||||
menu.add(menuPanel);
|
||||
|
||||
hostTextField = new JTextField();
|
||||
UIEnhancer.setTextFieldPlaceholder(hostTextField, defaultText);
|
||||
splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
|
||||
|
||||
dataTabbedPane = new JTabbedPane(JTabbedPane.TOP);
|
||||
@@ -415,8 +419,8 @@ public class Databoard extends JPanel {
|
||||
JTable taskStatusTable = new JTable(taskStatusTableModel);
|
||||
|
||||
for (Object[] data : dataList) {
|
||||
int rowCount = taskStatusTable.getRowCount();
|
||||
int id = rowCount > 0 ? (Integer) taskStatusTable.getValueAt(rowCount - 1, 0) + 1 : 1;
|
||||
int rowCount = taskStatusTableModel.getRowCount();
|
||||
int id = rowCount > 0 ? (Integer) taskStatusTableModel.getValueAt(rowCount - 1, 0) + 1 : 1;
|
||||
Object[] rowData = new Object[data.length + 1];
|
||||
rowData[0] = id;
|
||||
System.arraycopy(data, 0, rowData, 1, data.length);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package hae.component.board.message;
|
||||
|
||||
import burp.api.montoya.MontoyaApi;
|
||||
import burp.api.montoya.core.ByteArray;
|
||||
import burp.api.montoya.http.message.HttpHeader;
|
||||
import burp.api.montoya.http.message.HttpRequestResponse;
|
||||
import burp.api.montoya.http.message.requests.HttpRequest;
|
||||
@@ -11,6 +10,7 @@ import burp.api.montoya.ui.editor.HttpRequestEditor;
|
||||
import burp.api.montoya.ui.editor.HttpResponseEditor;
|
||||
import hae.Config;
|
||||
import hae.cache.CachePool;
|
||||
import hae.utils.ConfigLoader;
|
||||
import hae.utils.project.FileProcessor;
|
||||
import hae.utils.string.HashCalculator;
|
||||
import hae.utils.string.StringProcessor;
|
||||
@@ -23,6 +23,8 @@ import javax.swing.table.TableRowSorter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -30,15 +32,17 @@ import static burp.api.montoya.ui.editor.EditorOptions.READ_ONLY;
|
||||
|
||||
public class MessageTableModel extends AbstractTableModel {
|
||||
private final MontoyaApi api;
|
||||
private final ConfigLoader configLoader;
|
||||
private final MessageTable messageTable;
|
||||
private final JSplitPane splitPane;
|
||||
private final LinkedList<MessageEntry> log = new LinkedList<>();
|
||||
private final LinkedList<MessageEntry> filteredLog;
|
||||
private SwingWorker<Void, Void> currentWorker;
|
||||
|
||||
public MessageTableModel(MontoyaApi api) {
|
||||
public MessageTableModel(MontoyaApi api, ConfigLoader configLoader) {
|
||||
this.filteredLog = new LinkedList<>();
|
||||
this.api = api;
|
||||
this.configLoader = configLoader;
|
||||
|
||||
JTabbedPane messageTab = new JTabbedPane();
|
||||
UserInterface userInterface = api.userInterface();
|
||||
@@ -435,7 +439,7 @@ public class MessageTableModel extends AbstractTableModel {
|
||||
|
||||
public class MessageTable extends JTable {
|
||||
private MessageEntry messageEntry;
|
||||
private SwingWorker<ByteArray[], Void> currentWorker;
|
||||
private final ExecutorService executorService;
|
||||
private int lastSelectedIndex = -1;
|
||||
private final HttpRequestEditor requestEditor;
|
||||
private final HttpResponseEditor responseEditor;
|
||||
@@ -444,52 +448,31 @@ public class MessageTableModel extends AbstractTableModel {
|
||||
super(messageTableModel);
|
||||
this.requestEditor = requestEditor;
|
||||
this.responseEditor = responseEditor;
|
||||
this.executorService = Executors.newSingleThreadExecutor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeSelection(int row, int col, boolean toggle, boolean extend) {
|
||||
super.changeSelection(row, col, toggle, extend);
|
||||
|
||||
if (currentWorker != null && !currentWorker.isDone()) {
|
||||
currentWorker.cancel(true);
|
||||
}
|
||||
|
||||
currentWorker = new SwingWorker<>() {
|
||||
@Override
|
||||
protected ByteArray[] doInBackground() {
|
||||
int selectedIndex = convertRowIndexToModel(row);
|
||||
if (lastSelectedIndex != selectedIndex) {
|
||||
lastSelectedIndex = selectedIndex;
|
||||
messageEntry = filteredLog.get(selectedIndex);
|
||||
executorService.execute(this::getSelectedMessage);
|
||||
}
|
||||
}
|
||||
|
||||
private void getSelectedMessage() {
|
||||
messageEntry = filteredLog.get(lastSelectedIndex);
|
||||
|
||||
HttpRequestResponse httpRequestResponse = messageEntry.getRequestResponse();
|
||||
|
||||
ByteArray requestByte = httpRequestResponse.request().toByteArray();
|
||||
ByteArray responseByte = httpRequestResponse.response().toByteArray();
|
||||
|
||||
ByteArray[] httpByteArray = new ByteArray[2];
|
||||
httpByteArray[0] = requestByte;
|
||||
httpByteArray[1] = responseByte;
|
||||
return httpByteArray;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void done() {
|
||||
try {
|
||||
ByteArray[] retByteArray = get();
|
||||
if (retByteArray != null) {
|
||||
requestEditor.setRequest(HttpRequest.httpRequest(messageEntry.getRequestResponse().httpService(), retByteArray[0]));
|
||||
responseEditor.setResponse(HttpResponse.httpResponse(retByteArray[1]));
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
currentWorker.execute();
|
||||
requestEditor.setRequest(HttpRequest.httpRequest(messageEntry.getRequestResponse().httpService(), httpRequestResponse.request().toByteArray()));
|
||||
int responseSizeWithMb = httpRequestResponse.response().toString().length() / 1024 / 1024;
|
||||
if ((responseSizeWithMb < Integer.parseInt(configLoader.getLimitSize())) || configLoader.getLimitSize().equals("0")) {
|
||||
responseEditor.setResponse(httpRequestResponse.response());
|
||||
} else {
|
||||
responseEditor.setResponse(HttpResponse.httpResponse("Exceeds length limit."));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.awt.event.ActionEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -34,6 +35,7 @@ public class Datatable extends JPanel {
|
||||
private final JTable dataTable;
|
||||
private final DefaultTableModel dataTableModel;
|
||||
private final JTextField searchField;
|
||||
private final JTextField secondSearchField;
|
||||
private final TableRowSorter<DefaultTableModel> sorter;
|
||||
private final JCheckBox searchMode = new JCheckBox("Reverse search");
|
||||
private final String tabName;
|
||||
@@ -52,7 +54,8 @@ public class Datatable extends JPanel {
|
||||
|
||||
this.dataTable = new JTable(dataTableModel);
|
||||
this.sorter = new TableRowSorter<>(dataTableModel);
|
||||
this.searchField = new JTextField();
|
||||
this.searchField = new JTextField(10);
|
||||
this.secondSearchField = new JTextField(10);
|
||||
this.aiEmpoweredMenu = new JPopupMenu();
|
||||
this.footerPanel = new JPanel(new BorderLayout(0, 5));
|
||||
|
||||
@@ -70,21 +73,13 @@ public class Datatable extends JPanel {
|
||||
}
|
||||
});
|
||||
|
||||
dataTable.setRowSorter(sorter);
|
||||
TableColumn idColumn = dataTable.getColumnModel().getColumn(0);
|
||||
idColumn.setMaxWidth(50);
|
||||
|
||||
for (String item : dataList) {
|
||||
if (!item.isEmpty()) {
|
||||
addRowToTable(new Object[]{item});
|
||||
}
|
||||
}
|
||||
|
||||
// 设置灰色默认文本
|
||||
String searchText = "Search";
|
||||
UIEnhancer.setTextFieldPlaceholder(searchField, searchText);
|
||||
|
||||
// 监听输入框内容输入、更新、删除
|
||||
UIEnhancer.setTextFieldPlaceholder(searchField, "Search");
|
||||
searchField.getDocument().addDocumentListener(new DocumentListener() {
|
||||
@Override
|
||||
public void insertUpdate(DocumentEvent e) {
|
||||
@@ -103,10 +98,34 @@ public class Datatable extends JPanel {
|
||||
|
||||
});
|
||||
|
||||
UIEnhancer.setTextFieldPlaceholder(secondSearchField, "Second search");
|
||||
secondSearchField.getDocument().addDocumentListener(new DocumentListener() {
|
||||
@Override
|
||||
public void insertUpdate(DocumentEvent e) {
|
||||
performSearch();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeUpdate(DocumentEvent e) {
|
||||
performSearch();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changedUpdate(DocumentEvent e) {
|
||||
performSearch();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// 设置布局
|
||||
JScrollPane scrollPane = new JScrollPane(dataTable);
|
||||
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
|
||||
|
||||
dataTable.setRowSorter(sorter);
|
||||
TableColumn idColumn = dataTable.getColumnModel().getColumn(0);
|
||||
idColumn.setPreferredWidth(50);
|
||||
idColumn.setMaxWidth(100);
|
||||
|
||||
setLayout(new BorderLayout(0, 5));
|
||||
|
||||
JPanel optionsPanel = new JPanel();
|
||||
@@ -162,6 +181,8 @@ public class Datatable extends JPanel {
|
||||
optionsPanel.add(Box.createHorizontalStrut(5));
|
||||
optionsPanel.add(searchField);
|
||||
optionsPanel.add(Box.createHorizontalStrut(5));
|
||||
optionsPanel.add(secondSearchField);
|
||||
optionsPanel.add(Box.createHorizontalStrut(5));
|
||||
optionsPanel.add(aiEmpoweredButton);
|
||||
|
||||
footerPanel.setBorder(BorderFactory.createEmptyBorder(2, 3, 5, 3));
|
||||
@@ -252,8 +273,21 @@ public class Datatable extends JPanel {
|
||||
}
|
||||
|
||||
private void performSearch() {
|
||||
RowFilter<Object, Object> firstRowFilter = applyFirstSearchFilter();
|
||||
RowFilter<Object, Object> secondRowFilter = applySecondFilter();
|
||||
if (searchField.getForeground().equals(Color.BLACK)) {
|
||||
RowFilter<Object, Object> rowFilter = new RowFilter<Object, Object>() {
|
||||
sorter.setRowFilter(firstRowFilter);
|
||||
if (secondSearchField.getForeground().equals(Color.BLACK)) {
|
||||
List<RowFilter<Object, Object>> filters = new ArrayList<>();
|
||||
filters.add(firstRowFilter);
|
||||
filters.add(secondRowFilter);
|
||||
sorter.setRowFilter(RowFilter.andFilter(filters));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private RowFilter<Object, Object> applyFirstSearchFilter() {
|
||||
return new RowFilter<Object, Object>() {
|
||||
public boolean include(Entry<?, ?> entry) {
|
||||
String searchFieldTextText = searchField.getText();
|
||||
Pattern pattern = null;
|
||||
@@ -271,8 +305,27 @@ public class Datatable extends JPanel {
|
||||
}
|
||||
}
|
||||
};
|
||||
sorter.setRowFilter(rowFilter);
|
||||
}
|
||||
|
||||
private RowFilter<Object, Object> applySecondFilter() {
|
||||
return new RowFilter<Object, Object>() {
|
||||
public boolean include(Entry<?, ?> entry) {
|
||||
String searchFieldTextText = secondSearchField.getText();
|
||||
Pattern pattern = null;
|
||||
try {
|
||||
pattern = Pattern.compile(searchFieldTextText, Pattern.CASE_INSENSITIVE);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
String entryValue = ((String) entry.getValue(1)).toLowerCase();
|
||||
searchFieldTextText = searchFieldTextText.toLowerCase();
|
||||
if (pattern != null) {
|
||||
return searchFieldTextText.isEmpty() || pattern.matcher(entryValue).find();
|
||||
} else {
|
||||
return searchFieldTextText.isEmpty() || entryValue.contains(searchFieldTextText);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void setTableListener(MessageTableModel messagePanel) {
|
||||
|
||||
@@ -9,6 +9,7 @@ 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.Config;
|
||||
import hae.component.board.table.Datatable;
|
||||
import hae.instances.http.utils.MessageProcessor;
|
||||
import hae.utils.ConfigLoader;
|
||||
@@ -132,7 +133,7 @@ public class RequestEditor implements HttpRequestEditorProvider {
|
||||
Map<String, String> dataMap = result.get(0);
|
||||
if (dataMap != null && !dataMap.isEmpty()) {
|
||||
dataMap.keySet().forEach(i -> {
|
||||
String[] extractData = dataMap.get(i).split("\n");
|
||||
String[] extractData = dataMap.get(i).split(Config.boundary);
|
||||
Datatable dataPanel = new Datatable(api, configLoader, i, Arrays.asList(extractData));
|
||||
tabbedPane.addTab(i, dataPanel);
|
||||
});
|
||||
|
||||
@@ -29,7 +29,6 @@ public class HttpMessageHandler implements HttpHandler {
|
||||
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<HttpRequest> httpRequest = new ThreadLocal<>();
|
||||
|
||||
public HttpMessageHandler(MontoyaApi api, ConfigLoader configLoader, MessageTableModel messageTableModel) {
|
||||
this.api = api;
|
||||
@@ -47,7 +46,6 @@ public class HttpMessageHandler implements HttpHandler {
|
||||
Annotations annotations = httpRequestToBeSent.annotations();
|
||||
|
||||
try {
|
||||
httpRequest.set(httpRequestToBeSent);
|
||||
host.set(StringProcessor.getHostByUrl(httpRequestToBeSent.url()));
|
||||
} catch (Exception e) {
|
||||
api.logging().logToError("handleHttpRequestToBeSent: " + e.getMessage());
|
||||
@@ -77,11 +75,10 @@ public class HttpMessageHandler implements HttpHandler {
|
||||
String comment = StringProcessor.mergeComment(String.join(", ", commentList.get()));
|
||||
annotations.setNotes(comment);
|
||||
|
||||
HttpRequestResponse httpRequestResponse = HttpRequestResponse.httpRequestResponse(httpRequest.get(), httpResponseReceived);
|
||||
HttpRequestResponse httpRequestResponse = HttpRequestResponse.httpRequestResponse(request, httpResponseReceived);
|
||||
|
||||
// 添加到Databoard
|
||||
String method = httpRequest.get().method();
|
||||
String url = httpRequest.get().url();
|
||||
String method = request.method();
|
||||
String url = request.url();
|
||||
String status = String.valueOf(httpResponseReceived.statusCode());
|
||||
String length = String.valueOf(httpResponseReceived.toByteArray().length());
|
||||
|
||||
@@ -92,7 +89,7 @@ public class HttpMessageHandler implements HttpHandler {
|
||||
messageTableModel.add(httpRequestResponse, url, method, status, length, comment, color, "", "");
|
||||
return null;
|
||||
}
|
||||
}.run();
|
||||
}.execute();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
api.logging().logToError("handleHttpResponseReceived: " + e.getMessage());
|
||||
|
||||
@@ -92,7 +92,7 @@ public class RegularMatcher {
|
||||
|
||||
if (!result.isEmpty()) {
|
||||
tmpMap.put("color", color);
|
||||
String dataStr = String.join("\n", result);
|
||||
String dataStr = String.join(Config.boundary, result);
|
||||
tmpMap.put("data", dataStr);
|
||||
|
||||
String nameAndSize = String.format("%s (%s)", name, result.size());
|
||||
|
||||
@@ -77,8 +77,11 @@ public class ConfigLoader {
|
||||
|
||||
public void initConfig() {
|
||||
Map<String, Object> r = new LinkedHashMap<>();
|
||||
r.put("excludeSuffix", getExcludeSuffix());
|
||||
r.put("blockHost", getBlockHost());
|
||||
r.put("ExcludeSuffix", getExcludeSuffix());
|
||||
r.put("BlockHost", getBlockHost());
|
||||
r.put("ExcludeStatus", getExcludeStatus());
|
||||
r.put("LimitSize", getLimitSize());
|
||||
r.put("HaEScope", getScope());
|
||||
try {
|
||||
Writer ws = new OutputStreamWriter(Files.newOutputStream(Paths.get(configFilePath)), StandardCharsets.UTF_8);
|
||||
yaml.dump(r, ws);
|
||||
@@ -158,14 +161,18 @@ public class ConfigLoader {
|
||||
return getValueFromConfig("ExcludeStatus", Config.status);
|
||||
}
|
||||
|
||||
public String getLimitSize() {
|
||||
return getValueFromConfig("LimitSize", Config.size);
|
||||
}
|
||||
|
||||
public String getScope() {
|
||||
return getValueFromConfig("HaEScope", Config.scopeOptions);
|
||||
}
|
||||
|
||||
private String getValueFromConfig(String name, String value) {
|
||||
private String getValueFromConfig(String name, String defaultValue) {
|
||||
File yamlSetting = new File(configFilePath);
|
||||
if (!yamlSetting.exists() || !yamlSetting.isFile()) {
|
||||
return value;
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
try (InputStream inorder = Files.newInputStream(Paths.get(configFilePath))) {
|
||||
@@ -177,7 +184,7 @@ public class ConfigLoader {
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
return value;
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public void setAlibabaAIAPIKey(String apiKey) {
|
||||
@@ -204,6 +211,10 @@ public class ConfigLoader {
|
||||
setValueToConfig("ExcludeStatus", status);
|
||||
}
|
||||
|
||||
public void setLimitSize(String size) {
|
||||
setValueToConfig("LimitSize", size);
|
||||
}
|
||||
|
||||
public void setScope(String scope) {
|
||||
setValueToConfig("HaEScope", scope);
|
||||
}
|
||||
|
||||
@@ -26,12 +26,11 @@ public class HttpUtils {
|
||||
|
||||
String boundary = api.utilities().randomUtils().randomString(32, RandomUtils.CharacterSet.ASCII_LETTERS);
|
||||
|
||||
StringBuilder newBody = new StringBuilder();
|
||||
newBody.append(String.format("--%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\n\r\n%s\r\n", boundary, name, filename, content));
|
||||
newBody.append(String.format("--%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n", boundary, "purpose", "file-extract"));
|
||||
newBody.append("--").append(boundary).append("--\r\n");
|
||||
String newBody = String.format("--%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\n\r\n%s\r\n", boundary, name, filename, content) +
|
||||
String.format("--%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n", boundary, "purpose", "file-extract") +
|
||||
"--" + boundary + "--\r\n";
|
||||
|
||||
baseRequest = baseRequest.withUpdatedHeader("Content-Type", "multipart/form-data; boundary=" + boundary).withBody(newBody.toString());
|
||||
baseRequest = baseRequest.withUpdatedHeader("Content-Type", "multipart/form-data; boundary=" + boundary).withBody(newBody);
|
||||
|
||||
return baseRequest;
|
||||
}
|
||||
@@ -44,7 +43,8 @@ public class HttpUtils {
|
||||
public boolean verifyHttpRequestResponse(HttpRequestResponse requestResponse, String toolType) {
|
||||
HttpRequest request = requestResponse.request();
|
||||
HttpResponse response = requestResponse.response();
|
||||
|
||||
boolean retStatus = false;
|
||||
try {
|
||||
String host = StringProcessor.getHostByUrl(request.url());
|
||||
String[] hostList = configLoader.getBlockHost().split("\\|");
|
||||
boolean isBlockHost = isBlockHost(hostList, host);
|
||||
@@ -57,7 +57,11 @@ public class HttpUtils {
|
||||
List<String> statusList = Arrays.asList(configLoader.getExcludeStatus().split("\\|"));
|
||||
boolean isExcludeStatus = statusList.contains(String.valueOf(response.statusCode()));
|
||||
|
||||
return isExcludeSuffix || isBlockHost || isToolScope || isExcludeStatus;
|
||||
retStatus = isExcludeSuffix || isBlockHost || isToolScope || isExcludeStatus;
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
return retStatus;
|
||||
}
|
||||
|
||||
private boolean isBlockHost(String[] hostList, String host) {
|
||||
|
||||
@@ -237,15 +237,6 @@ rules:
|
||||
scope: response body
|
||||
engine: dfa
|
||||
sensitive: false
|
||||
- name: HTML Notes
|
||||
loaded: true
|
||||
f_regex: (<!--.*?-->)
|
||||
s_regex: ''
|
||||
format: '{0}'
|
||||
color: magenta
|
||||
scope: response body
|
||||
engine: nfa
|
||||
sensitive: false
|
||||
- name: Create Script
|
||||
loaded: true
|
||||
f_regex: (\{[^{}]*\}\s*\[[^\s]*\]\s*\+\s*"[^\s]*\.js")
|
||||
|
||||
Reference in New Issue
Block a user