diff --git a/src/main/java/burp/BurpExtender.java b/src/main/java/burp/BurpExtender.java index 0e35e32..39b1750 100644 --- a/src/main/java/burp/BurpExtender.java +++ b/src/main/java/burp/BurpExtender.java @@ -34,7 +34,7 @@ public class BurpExtender implements IBurpExtender, IHttpListener, IMessageEdito this.callbacks = callbacks; BurpExtender.helpers = callbacks.getHelpers(); - String version = "2.4.5"; + String version = "2.4.6"; callbacks.setExtensionName(String.format("HaE (%s) - Highlighter and Extractor", version)); // 定义输出 stdout = new PrintWriter(callbacks.getStdout(), true); diff --git a/src/main/java/burp/action/ExtractContent.java b/src/main/java/burp/action/ExtractContent.java index 9ab0fd1..bd8f786 100644 --- a/src/main/java/burp/action/ExtractContent.java +++ b/src/main/java/burp/action/ExtractContent.java @@ -1,5 +1,6 @@ package burp.action; +import burp.BurpExtender; import java.nio.charset.StandardCharsets; import java.util.*; import burp.Config; @@ -19,121 +20,127 @@ public class ExtractContent { public Map> matchRegex(byte[] content, String headers, byte[] body, String scopeString, String host) { Map> map = new HashMap<>(); // 最终返回的结果 Config.ruleConfig.keySet().forEach(i -> { - String matchContent = ""; for (Object[] objects : Config.ruleConfig.get(i)) { - // 遍历获取规则 - List result = new ArrayList<>(); - Map tmpMap = new HashMap<>(); + // 多线程执行,一定程度上减少阻塞现象 + Thread t = new Thread(() -> { + String matchContent = ""; + // 遍历获取规则 + List result = new ArrayList<>(); + Map tmpMap = new HashMap<>(); - String name = objects[1].toString(); - boolean loaded = (Boolean) objects[0]; - String regex = objects[2].toString(); - String color = objects[3].toString(); - String scope = objects[4].toString(); - String engine = objects[5].toString(); - boolean sensitive = (Boolean) objects[6]; - // 判断规则是否开启与作用域 - if (loaded && (scope.contains(scopeString) || scope.contains("any"))) { - switch (scope) { - case "any": - case "request": - case "response": - matchContent = new String(content, StandardCharsets.UTF_8).intern(); - break; - case "any header": - case "request header": - case "response header": - matchContent = headers; - break; - case "any body": - case "request body": - case "response body": - matchContent = new String(body, StandardCharsets.UTF_8).intern(); - break; - default: - return; - } + String name = objects[1].toString(); + boolean loaded = (Boolean) objects[0]; + String regex = objects[2].toString(); + String color = objects[3].toString(); + String scope = objects[4].toString(); + String engine = objects[5].toString(); + boolean sensitive = (Boolean) objects[6]; + // 判断规则是否开启与作用域 + if (loaded && (scope.contains(scopeString) || scope.contains("any"))) { + switch (scope) { + case "any": + case "request": + case "response": + matchContent = new String(content, StandardCharsets.UTF_8).intern(); + break; + case "any header": + case "request header": + case "response header": + matchContent = headers; + break; + case "any body": + case "request body": + case "response body": + matchContent = new String(body, StandardCharsets.UTF_8).intern(); + break; + default: + break; + } - if ("nfa".equals(engine)) { - Pattern pattern; - // 判断规则是否大小写敏感 - if (sensitive) { - pattern = new Pattern(regex); + if ("nfa".equals(engine)) { + Pattern pattern; + // 判断规则是否大小写敏感 + if (sensitive) { + pattern = new Pattern(regex); + } else { + pattern = new Pattern(regex, Pattern.IGNORE_CASE); + } + + Matcher matcher = pattern.matcher(matchContent); + while (matcher.find()) { + // 添加匹配数据至list + // 强制用户使用()包裹正则 + result.add(matcher.group(1)); + } } else { - pattern = new Pattern(regex, Pattern.IGNORE_CASE); + RegExp regexp = new RegExp(regex); + Automaton auto = regexp.toAutomaton(); + RunAutomaton runAuto = new RunAutomaton(auto, true); + AutomatonMatcher autoMatcher = runAuto.newMatcher(matchContent); + while (autoMatcher.find()) { + // 添加匹配数据至list + // 强制用户使用()包裹正则 + result.add(autoMatcher.group()); + } } - Matcher matcher = pattern.matcher(matchContent); - while (matcher.find()) { - // 添加匹配数据至list - // 强制用户使用()包裹正则 - result.add(matcher.group(1)); - } - } else { - RegExp regexp = new RegExp(regex); - Automaton auto = regexp.toAutomaton(); - RunAutomaton runAuto = new RunAutomaton(auto, true); - AutomatonMatcher autoMatcher = runAuto.newMatcher(matchContent); - while (autoMatcher.find()) { - // 添加匹配数据至list - // 强制用户使用()包裹正则 - result.add(autoMatcher.group()); + // 去除重复内容 + HashSet tmpList = new HashSet(result); + result.clear(); + result.addAll(tmpList); + + if (!result.isEmpty()) { + tmpMap.put("color", color); + String dataStr = String.join("\n", result); + tmpMap.put("data", dataStr); + + // 添加到全局变量中,便于Databoard检索 + if (!host.isEmpty()) { + String anyHost = host.replace(host.split("\\.")[0], "*"); + List dataList = Arrays.asList(dataStr.split("\n")); + if (Config.globalDataMap.containsKey(host)) { + Map> gRuleMap = Config.globalDataMap.get(host); + // 判断匹配规则是否存在(逻辑同Host判断) + if (gRuleMap.containsKey(name)) { + List gDataList = gRuleMap.get(name); + List mergeDataList = new ArrayList<>(gDataList); + // 合并两个List + mergeDataList.addAll(dataList); + // 去重操作 + tmpList = new HashSet(mergeDataList); + mergeDataList.clear(); + mergeDataList.addAll(tmpList); + // 替换操作 + gRuleMap.replace(name, gDataList, mergeDataList); + } else { + gRuleMap.put(name, dataList); + } + } else if (!Config.globalDataMap.containsKey(anyHost)) { + // 添加通配符Host + Config.globalDataMap.put(anyHost, new HashMap<>()); + } else { + Map> ruleMap = new HashMap<>(); + ruleMap.put(name, dataList); + // 添加单一Host + Config.globalDataMap.put(host, ruleMap); + } + } + + map.put(name, tmpMap); + } } - - // 去除重复内容 - HashSet tmpList = new HashSet(result); - result.clear(); - result.addAll(tmpList); - - if (!result.isEmpty()) { - tmpMap.put("color", color); - tmpMap.put("data", String.join("\n", result)); - // 初始化格式 - map.put(name, tmpMap); - } + }); + t.start(); + try { + t.join(); + } catch (InterruptedException e) { + e.printStackTrace(); } + + } }); - - // 将提取的数据存放到全局变量中 - if (!host.isEmpty()) { - map.keySet().forEach(i -> { - Map tmpMap = map.get(i); - List dataList = Arrays.asList(tmpMap.get("data").toString().split("\n")); - // 组合通配符Host - String anyHost = host.replace(host.split("\\.")[0], "*"); - // 判断Host是否存在,如存在则进行数据更新,反之则新增数据 - if (Config.globalDataMap.containsKey(host)) { - Map> gRuleMap = Config.globalDataMap.get(host); - // 判断匹配规则是否存在(逻辑同Host判断) - if (gRuleMap.containsKey(i)) { - List gDataList = gRuleMap.get(i); - List mergeDataList = new ArrayList<>(gDataList); - // 合并两个List - mergeDataList.addAll(dataList); - // 去重操作 - HashSet tmpList = new HashSet(mergeDataList); - mergeDataList.clear(); - mergeDataList.addAll(tmpList); - // 替换操作 - gRuleMap.replace(i, gDataList, mergeDataList); - } else { - gRuleMap.put(i, dataList); - } - } else if (!Config.globalDataMap.containsKey(anyHost)) { - // 添加通配符Host - Config.globalDataMap.put(anyHost, new HashMap<>()); - } - else { - Map> ruleMap = new HashMap<>(); - ruleMap.put(i, dataList); - // 添加单一Host - Config.globalDataMap.put(host, ruleMap); - } - }); - } - return map; } }