Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a06ef8e25e | ||
|
|
7e53e250af | ||
|
|
b686b5e75e | ||
|
|
e83a6a1478 |
@@ -61,6 +61,8 @@ public class Config {
|
||||
"gray"
|
||||
};
|
||||
|
||||
public static Boolean proVersionStatus = true;
|
||||
|
||||
public static Map<String, Object[][]> globalRules = new HashMap<>();
|
||||
|
||||
public static ConcurrentHashMap<String, Map<String, List<String>>> globalDataMap = new ConcurrentHashMap<>();
|
||||
|
||||
@@ -10,6 +10,7 @@ import hae.component.board.message.MessageTableModel;
|
||||
import hae.instances.editor.RequestEditor;
|
||||
import hae.instances.editor.ResponseEditor;
|
||||
import hae.instances.editor.WebSocketEditor;
|
||||
import hae.instances.http.HttpMessagePassiveHandler;
|
||||
import hae.instances.websocket.WebSocketMessageHandler;
|
||||
import hae.utils.ConfigLoader;
|
||||
import hae.utils.DataManager;
|
||||
@@ -18,8 +19,8 @@ public class HaE implements BurpExtension {
|
||||
@Override
|
||||
public void initialize(MontoyaApi api) {
|
||||
// 设置扩展名称
|
||||
String version = "4.0";
|
||||
api.extension().setName("HaE - Highlighter and Extractor");
|
||||
String version = "4.0.2";
|
||||
|
||||
// 加载扩展后输出的项目信息
|
||||
Logging logging = api.logging();
|
||||
@@ -33,6 +34,9 @@ public class HaE implements BurpExtension {
|
||||
|
||||
MessageTableModel messageTableModel = new MessageTableModel(api, configLoader);
|
||||
|
||||
// 设置BurpSuite专业版状态
|
||||
Config.proVersionStatus = getBurpSuiteProStatus(api, configLoader, messageTableModel);
|
||||
|
||||
// 注册Tab页(用于查询数据)
|
||||
api.userInterface().registerSuiteTab("HaE", new Main(api, configLoader, messageTableModel));
|
||||
|
||||
@@ -48,6 +52,7 @@ public class HaE implements BurpExtension {
|
||||
DataManager dataManager = new DataManager(api);
|
||||
dataManager.loadData(messageTableModel);
|
||||
|
||||
|
||||
api.extension().registerUnloadingHandler(new ExtensionUnloadingHandler() {
|
||||
@Override
|
||||
public void extensionUnloaded() {
|
||||
@@ -57,4 +62,19 @@ public class HaE implements BurpExtension {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private Boolean getBurpSuiteProStatus(MontoyaApi api, ConfigLoader configLoader, MessageTableModel messageTableModel) {
|
||||
boolean burpSuiteProStatus = false;
|
||||
try {
|
||||
burpSuiteProStatus = api.burpSuite().version().name().contains("Professional");
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
api.scanner().registerScanCheck(new HttpMessagePassiveHandler(api, configLoader, messageTableModel)).deregister();
|
||||
burpSuiteProStatus = true;
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
return burpSuiteProStatus;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,6 +135,7 @@ public class Config extends JPanel {
|
||||
modePanel.setLayout(new BoxLayout(modePanel, BoxLayout.X_AXIS));
|
||||
|
||||
JCheckBox checkBox = new JCheckBox("Enable active http message handler");
|
||||
checkBox.setEnabled(hae.Config.proVersionStatus);
|
||||
modePanel.add(checkBox);
|
||||
checkBox.addActionListener(e -> updateModeStatus(checkBox));
|
||||
checkBox.setSelected(configLoader.getMode());
|
||||
@@ -379,7 +380,7 @@ public class Config extends JPanel {
|
||||
configLoader.setMode(selected ? "true" : "false");
|
||||
|
||||
if (checkBox.isSelected()) {
|
||||
if (passiveHandler.isRegistered()) {
|
||||
if (hae.Config.proVersionStatus && passiveHandler.isRegistered()) {
|
||||
passiveHandler.deregister();
|
||||
}
|
||||
|
||||
@@ -387,7 +388,7 @@ public class Config extends JPanel {
|
||||
activeHandler = api.http().registerHttpHandler(new HttpMessageActiveHandler(api, configLoader, messageTableModel));
|
||||
}
|
||||
} else {
|
||||
if (!passiveHandler.isRegistered()) {
|
||||
if (hae.Config.proVersionStatus && !passiveHandler.isRegistered()) {
|
||||
passiveHandler = api.scanner().registerScanCheck(new HttpMessagePassiveHandler(api, configLoader, messageTableModel));
|
||||
}
|
||||
|
||||
|
||||
@@ -136,14 +136,18 @@ public class MessageTableModel extends AbstractTableModel {
|
||||
|
||||
if (!isDuplicate) {
|
||||
if (flag) {
|
||||
DataManager dataManager = new DataManager(api);
|
||||
// 数据存储在BurpSuite空间内
|
||||
PersistedObject persistedObject = PersistedObject.persistedObject();
|
||||
persistedObject.setHttpRequestResponse("messageInfo", messageInfo);
|
||||
persistedObject.setString("comment", comment);
|
||||
persistedObject.setString("color", color);
|
||||
String uuidIndex = StringProcessor.getRandomUUID();
|
||||
dataManager.putData("message", uuidIndex, persistedObject);
|
||||
try {
|
||||
DataManager dataManager = new DataManager(api);
|
||||
// 数据存储在BurpSuite空间内
|
||||
PersistedObject persistedObject = PersistedObject.persistedObject();
|
||||
persistedObject.setHttpRequestResponse("messageInfo", messageInfo);
|
||||
persistedObject.setString("comment", comment);
|
||||
persistedObject.setString("color", color);
|
||||
String uuidIndex = StringProcessor.getRandomUUID();
|
||||
dataManager.putData("message", uuidIndex, persistedObject);
|
||||
} catch (Exception ignored) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 添加进日志
|
||||
|
||||
@@ -111,7 +111,7 @@ public class RegularMatcher {
|
||||
}
|
||||
}
|
||||
|
||||
public static void putDataToGlobalMap(MontoyaApi api, String host, String name, List<String> dataList, boolean flag) {
|
||||
public synchronized static void putDataToGlobalMap(MontoyaApi api, String host, String name, List<String> dataList, boolean flag) {
|
||||
// 添加到全局变量中,便于Databoard检索
|
||||
if (!Objects.equals(host, "") && host != null) {
|
||||
Config.globalDataMap.compute(host, (existingHost, existingMap) -> {
|
||||
@@ -125,14 +125,17 @@ public class RegularMatcher {
|
||||
|
||||
if (flag) {
|
||||
// 数据存储在BurpSuite空间内
|
||||
DataManager dataManager = new DataManager(api);
|
||||
PersistedObject persistedObject = PersistedObject.persistedObject();
|
||||
gRuleMap.forEach((kName, vList) -> {
|
||||
PersistedList<String> persistedList = PersistedList.persistedStringList();
|
||||
persistedList.addAll(vList);
|
||||
persistedObject.setStringList(kName, persistedList);
|
||||
});
|
||||
dataManager.putData("data", host, persistedObject);
|
||||
try {
|
||||
DataManager dataManager = new DataManager(api);
|
||||
PersistedObject persistedObject = PersistedObject.persistedObject();
|
||||
gRuleMap.forEach((kName, vList) -> {
|
||||
PersistedList<String> persistedList = PersistedList.persistedStringList();
|
||||
persistedList.addAll(vList);
|
||||
persistedObject.setStringList(kName, persistedList);
|
||||
});
|
||||
dataManager.putData("data", host, persistedObject);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
return gRuleMap;
|
||||
|
||||
@@ -19,6 +19,24 @@ public class DataManager {
|
||||
this.persistence = api.persistence();
|
||||
}
|
||||
|
||||
public synchronized void putData(String dataType, String dataName, PersistedObject persistedObject) {
|
||||
if (persistence.extensionData().getChildObject(dataName) != null) {
|
||||
persistence.extensionData().deleteChildObject(dataName);
|
||||
}
|
||||
persistence.extensionData().setChildObject(dataName, persistedObject);
|
||||
saveIndex(dataType, dataName);
|
||||
}
|
||||
|
||||
public void loadData(MessageTableModel messageTableModel) {
|
||||
// 1. 获取索引
|
||||
PersistedList<String> dataIndex = persistence.extensionData().getStringList("data"); // 数据索引
|
||||
PersistedList<String> messageIndex = persistence.extensionData().getStringList("message"); // 消息索引
|
||||
|
||||
// 2. 从索引获取数据
|
||||
loadHaEData(dataIndex);
|
||||
loadMessageData(messageIndex, messageTableModel);
|
||||
}
|
||||
|
||||
private void saveIndex(String indexName, String indexValue) {
|
||||
PersistedList<String> indexList = persistence.extensionData().getStringList(indexName);
|
||||
|
||||
@@ -35,32 +53,17 @@ public class DataManager {
|
||||
persistence.extensionData().setStringList(indexName, indexList);
|
||||
}
|
||||
|
||||
public void putData(String dataType, String dataName, PersistedObject persistedObject) {
|
||||
if (persistence.extensionData().getChildObject(dataName) != null) {
|
||||
persistence.extensionData().deleteChildObject(dataName);
|
||||
}
|
||||
persistence.extensionData().setChildObject(dataName, persistedObject);
|
||||
saveIndex(dataType, dataName);
|
||||
}
|
||||
|
||||
public void loadData(MessageTableModel messageTableModel) {
|
||||
// 1. 获取索引
|
||||
PersistedList<String> dataIndex = persistence.extensionData().getStringList("data"); // 数据索引
|
||||
PersistedList<String> messageIndex = persistence.extensionData().getStringList("message"); // 消息索引
|
||||
|
||||
// 2. 从索引获取数据
|
||||
loadHaEData(dataIndex);
|
||||
loadMessageData(messageIndex, messageTableModel);
|
||||
|
||||
}
|
||||
|
||||
private void loadHaEData(PersistedList<String> dataIndex) {
|
||||
if (dataIndex != null && !dataIndex.isEmpty()) {
|
||||
dataIndex.parallelStream().forEach(index -> {
|
||||
PersistedObject dataObj = persistence.extensionData().getChildObject(index);
|
||||
dataObj.stringListKeys().forEach(dataKey -> {
|
||||
RegularMatcher.putDataToGlobalMap(api, index, dataKey, dataObj.getStringList(dataKey).stream().toList(), false);
|
||||
});
|
||||
try {
|
||||
dataObj.stringListKeys().forEach(dataKey -> {
|
||||
RegularMatcher.putDataToGlobalMap(api, index, dataKey, dataObj.getStringList(dataKey).stream().toList(), false);
|
||||
});
|
||||
} catch (Exception e) {
|
||||
api.logging().logToOutput("loadHaEData:" + e.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -69,16 +72,18 @@ public class DataManager {
|
||||
if (messageIndex != null && !messageIndex.isEmpty()) {
|
||||
messageIndex.parallelStream().forEach(index -> {
|
||||
PersistedObject dataObj = persistence.extensionData().getChildObject(index);
|
||||
HttpRequestResponse messageInfo = dataObj.getHttpRequestResponse("messageInfo");
|
||||
String comment = dataObj.getString("comment");
|
||||
String color = dataObj.getString("color");
|
||||
HttpRequest request = messageInfo.request();
|
||||
HttpResponse response = messageInfo.response();
|
||||
String method = request.method();
|
||||
String url = request.url();
|
||||
String status = String.valueOf(response.statusCode());
|
||||
String length = String.valueOf(response.toByteArray().length());
|
||||
messageTableModel.add(messageInfo, url, method, status, length, comment, color, false);
|
||||
if (dataObj != null) {
|
||||
HttpRequestResponse messageInfo = dataObj.getHttpRequestResponse("messageInfo");
|
||||
String comment = dataObj.getString("comment");
|
||||
String color = dataObj.getString("color");
|
||||
HttpRequest request = messageInfo.request();
|
||||
HttpResponse response = messageInfo.response();
|
||||
String method = request.method();
|
||||
String url = request.url();
|
||||
String status = String.valueOf(response.statusCode());
|
||||
String length = String.valueOf(response.toByteArray().length());
|
||||
messageTableModel.add(messageInfo, url, method, status, length, comment, color, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,7 +231,7 @@ rules:
|
||||
rule:
|
||||
- name: Linkfinder
|
||||
loaded: true
|
||||
f_regex: (?:"|')(((?:[a-zA-Z]{1,10}://|//)[^"'/]{1,}\.[a-zA-Z]{2,}[^"']{0,})|((?:/|\.\./|\./)[^"'><,;|*()(%%$^/\\\[\]][^"'><,;|()]{1,})|([a-zA-Z0-9_\-/]{1,}/[a-zA-Z0-9_\-/]{1,}\.(?:[a-zA-Z]{1,4}|action)(?:[\?|#][^"|']{0,}|))|([a-zA-Z0-9_\-/]{1,}/[a-zA-Z0-9_\-/]{3,}(?:[\?|#][^"|']{0,}|))|([a-zA-Z0-9_\-]{1,}\.(?:\w)(?:[\?|#][^"|']{0,}|)))(?:"|')
|
||||
f_regex: (?:"|')((?:(?:[a-zA-Z]{1,10}://|//)[^"'/]{1,}\.[a-zA-Z]{2,}[^"']{0,})|(?:(?:(?:/|\.\./|\./)?[^"'><,;|*()(%%$^/\\\[\]][^"'><,;|()]{1,}\.[a-zA-Z]{1,4})|(?:(?:/|\.\./|\./)?[^"'><,;|*()(%%$^/\\\[\]][^"'><,;|()]{1,}/[^"'><,;|()]{1,}(?:\.[a-zA-Z]{1,4}|action)?)))(?:[\?|#][^"|']{0,})?(?:"|')
|
||||
s_regex: ''
|
||||
format: '{0}'
|
||||
color: gray
|
||||
|
||||
Reference in New Issue
Block a user