diff --git a/src/main/java/hae/Config.java b/src/main/java/hae/Config.java index 1b8a9a8..74ef3d1 100644 --- a/src/main/java/hae/Config.java +++ b/src/main/java/hae/Config.java @@ -12,6 +12,8 @@ public class Config { public static String status = "404"; + public static String boundary = "\n\t\n"; + public static String[] scope = new String[]{ "any", "any header", diff --git a/src/main/java/hae/HaE.java b/src/main/java/hae/HaE.java index 0432ace..dda4e19 100644 --- a/src/main/java/hae/HaE.java +++ b/src/main/java/hae/HaE.java @@ -18,7 +18,7 @@ public class HaE implements BurpExtension { @Override public void initialize(MontoyaApi api) { // 设置扩展名称 - String version = "3.3.1"; + String version = "3.3.2"; api.extension().setName(String.format("HaE (%s) - Highlighter and Extractor", version)); // 加载扩展后输出的项目信息 diff --git a/src/main/java/hae/component/config/Config.java b/src/main/java/hae/component/Config.java similarity index 99% rename from src/main/java/hae/component/config/Config.java rename to src/main/java/hae/component/Config.java index b4dc82c..cb9a40a 100644 --- a/src/main/java/hae/component/config/Config.java +++ b/src/main/java/hae/component/Config.java @@ -1,4 +1,4 @@ -package hae.component.config; +package hae.component; import burp.api.montoya.MontoyaApi; import hae.component.rule.Rules; @@ -387,7 +387,6 @@ public void updateScope(JCheckBox checkBox) { private void addActionPerformed(ActionEvent e, DefaultTableModel model, JTextField addTextField) { String addTextFieldText = addTextField.getText(); - api.logging().logToOutput(addTextFieldText); if (!addTextFieldText.equals(defaultText)) { addDataToTable(addTextFieldText, model); } diff --git a/src/main/java/hae/component/Main.java b/src/main/java/hae/component/Main.java index f7f5c24..d558008 100644 --- a/src/main/java/hae/component/Main.java +++ b/src/main/java/hae/component/Main.java @@ -3,7 +3,6 @@ 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; diff --git a/src/main/java/hae/component/board/Databoard.java b/src/main/java/hae/component/board/Databoard.java index 2270474..750894a 100644 --- a/src/main/java/hae/component/board/Databoard.java +++ b/src/main/java/hae/component/board/Databoard.java @@ -8,6 +8,7 @@ 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, Void> exportActionWorker; private SwingWorker, 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 @@ private void initComponents() { menu.add(menuPanel); hostTextField = new JTextField(); + UIEnhancer.setTextFieldPlaceholder(hostTextField, defaultText); splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); dataTabbedPane = new JTabbedPane(JTabbedPane.TOP); diff --git a/src/main/java/hae/instances/editor/RequestEditor.java b/src/main/java/hae/instances/editor/RequestEditor.java index 0853e8e..5749e9f 100644 --- a/src/main/java/hae/instances/editor/RequestEditor.java +++ b/src/main/java/hae/instances/editor/RequestEditor.java @@ -9,6 +9,7 @@ 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 static void generateTabbedPaneFromResultMap(MontoyaApi api, ConfigLoader Map 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); }); diff --git a/src/main/java/hae/instances/http/HttpMessageHandler.java b/src/main/java/hae/instances/http/HttpMessageHandler.java index bb3c10d..0fbe48d 100644 --- a/src/main/java/hae/instances/http/HttpMessageHandler.java +++ b/src/main/java/hae/instances/http/HttpMessageHandler.java @@ -29,7 +29,6 @@ public class HttpMessageHandler implements HttpHandler { private final ThreadLocal host = ThreadLocal.withInitial(() -> ""); private final ThreadLocal> colorList = ThreadLocal.withInitial(ArrayList::new); private final ThreadLocal> commentList = ThreadLocal.withInitial(ArrayList::new); - private final ThreadLocal httpRequest = new ThreadLocal<>(); public HttpMessageHandler(MontoyaApi api, ConfigLoader configLoader, MessageTableModel messageTableModel) { this.api = api; @@ -47,7 +46,6 @@ public RequestToBeSentAction handleHttpRequestToBeSent(HttpRequestToBeSent httpR 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 ResponseReceivedAction handleHttpResponseReceived(HttpResponseReceived ht 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 @@ protected Void doInBackground() { messageTableModel.add(httpRequestResponse, url, method, status, length, comment, color, "", ""); return null; } - }.run(); + }.execute(); } } catch (Exception e) { api.logging().logToError("handleHttpResponseReceived: " + e.getMessage()); diff --git a/src/main/java/hae/instances/http/utils/RegularMatcher.java b/src/main/java/hae/instances/http/utils/RegularMatcher.java index 6a01d61..70df3de 100644 --- a/src/main/java/hae/instances/http/utils/RegularMatcher.java +++ b/src/main/java/hae/instances/http/utils/RegularMatcher.java @@ -92,7 +92,7 @@ public Map> match(String host, String type, String m 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()); diff --git a/src/main/java/hae/utils/ConfigLoader.java b/src/main/java/hae/utils/ConfigLoader.java index ca48565..4eab136 100644 --- a/src/main/java/hae/utils/ConfigLoader.java +++ b/src/main/java/hae/utils/ConfigLoader.java @@ -77,8 +77,10 @@ private static boolean isValidConfigPath(String configPath) { public void initConfig() { Map 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("HaEScope", getScope()); try { Writer ws = new OutputStreamWriter(Files.newOutputStream(Paths.get(configFilePath)), StandardCharsets.UTF_8); yaml.dump(r, ws); @@ -162,10 +164,10 @@ 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 +179,7 @@ private String getValueFromConfig(String name, String value) { } catch (Exception ignored) { } - return value; + return defaultValue; } public void setAlibabaAIAPIKey(String apiKey) { diff --git a/src/main/java/hae/utils/http/HttpUtils.java b/src/main/java/hae/utils/http/HttpUtils.java index 79e0651..2b87905 100644 --- a/src/main/java/hae/utils/http/HttpUtils.java +++ b/src/main/java/hae/utils/http/HttpUtils.java @@ -26,12 +26,11 @@ public HttpRequest generateRequestByMultipartUploadMethod(String url, String nam 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,20 +43,25 @@ public HttpRequest generateRequestByDeleteMethod(String url) { 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); - String host = StringProcessor.getHostByUrl(request.url()); - String[] hostList = configLoader.getBlockHost().split("\\|"); - boolean isBlockHost = isBlockHost(hostList, host); + List suffixList = Arrays.asList(configLoader.getExcludeSuffix().split("\\|")); + boolean isExcludeSuffix = suffixList.contains(request.fileExtension().toLowerCase()); - List suffixList = Arrays.asList(configLoader.getExcludeSuffix().split("\\|")); - boolean isExcludeSuffix = suffixList.contains(request.fileExtension().toLowerCase()); + boolean isToolScope = !configLoader.getScope().contains(toolType); - boolean isToolScope = !configLoader.getScope().contains(toolType); + List statusList = Arrays.asList(configLoader.getExcludeStatus().split("\\|")); + boolean isExcludeStatus = statusList.contains(String.valueOf(response.statusCode())); - List statusList = Arrays.asList(configLoader.getExcludeStatus().split("\\|")); - boolean isExcludeStatus = statusList.contains(String.valueOf(response.statusCode())); + retStatus = isExcludeSuffix || isBlockHost || isToolScope || isExcludeStatus; + } catch (Exception ignored) { + } - return isExcludeSuffix || isBlockHost || isToolScope || isExcludeStatus; + return retStatus; } private boolean isBlockHost(String[] hostList, String host) { diff --git a/src/main/resources/rules/Rules.yml b/src/main/resources/rules/Rules.yml index e6a35ee..d577b98 100644 --- a/src/main/resources/rules/Rules.yml +++ b/src/main/resources/rules/Rules.yml @@ -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")