diff --git a/README.md b/README.md index e857273..ab5322f 100644 --- a/README.md +++ b/README.md @@ -25,14 +25,16 @@ ### 规则释义 -HaE目前的规则一共有6个字段,分别是规则名称、规则正则、规则作用域、正则引擎、规则匹配颜色、规则敏感性。 +HaE目前的规则一共有8个字段,分别是规则名称、规则正则、规则作用域、正则引擎、规则匹配颜色、规则敏感性。 详细的含义如下所示: | 字段 | 含义 | |-----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | Name | 规则名称,主要用于简短概括当前规则的作用。 | -| Regex | 规则正则,主要用于填写正则表达式。在HaE中所需提取匹配的内容需要用`(`、`)`将正则表达式进行包裹。 | +| F-Regex | 规则正则,主要用于填写正则表达式。在HaE中所需提取匹配的内容需要用`(`、`)`将正则表达式进行包裹。| +| S-Regex | 规则正则,作用及使用同F-Regex。S-Regex为二次正则,可以用于对F-Regex匹配的数据结果进行二次的匹配提取,如不需要的情况下可以留空。| +| Format | 格式化输出,在NFA引擎的正则表达式中,我们可以通过`{0}`、`{1}`、`{2}`…的方式进行取分组格式化输出。默认情况下使用`{0}`即可。 | | Scope | 规则作用域,主要用于表示当前规则作用于HTTP报文的哪个部分。 | | Engine | 正则引擎,主要用于表示当前规则的正则表达式所使用的引擎。**DFA引擎**:对于文本串里的每一个字符只需扫描一次,速度快、特性少;**NFA引擎**:要翻来覆去标注字符、取消标注字符,速度慢,但是特性(如:分组、替换、分割)丰富。 | | Color | 规则匹配颜色,主要用于表示当前规则匹配到对应HTTP报文时所需标记的高亮颜色。在HaE中具备颜色升级算法,当出现相同颜色时会自动向上升级一个颜色进行标记。 | diff --git a/images/rules.png b/images/rules.png index 3dfadbc..7f5c59a 100644 Binary files a/images/rules.png and b/images/rules.png differ diff --git a/src/main/java/burp/BurpExtender.java b/src/main/java/burp/BurpExtender.java index 0ee2439..55a01c1 100644 --- a/src/main/java/burp/BurpExtender.java +++ b/src/main/java/burp/BurpExtender.java @@ -36,7 +36,7 @@ public class BurpExtender implements IBurpExtender, IHttpListener, IMessageEdito new ConfigLoader(); - String version = "2.5.11"; + String version = "2.6"; callbacks.setExtensionName(String.format("HaE (%s) - Highlighter and Extractor", version)); // 定义输出 diff --git a/src/main/java/burp/config/ConfigLoader.java b/src/main/java/burp/config/ConfigLoader.java index 02f8404..95f96af 100644 --- a/src/main/java/burp/config/ConfigLoader.java +++ b/src/main/java/burp/config/ConfigLoader.java @@ -112,7 +112,7 @@ public class ConfigLoader { public static Map getRules() { Map rulesMap = YamlTool.loadYaml(getRulesFilePath()); Map resRule = new HashMap<>(); - String[] fieldKeys = {"loaded", "name", "regex", "color", "scope", "engine", "sensitive"}; + String[] fieldKeys = {"loaded", "name", "f_regex", "s_regex", "format", "color", "scope", "engine", "sensitive"}; Object rulesObj = rulesMap.get("rules"); if (rulesObj instanceof List) { diff --git a/src/main/java/burp/core/processor/DataProcessingUnit.java b/src/main/java/burp/core/processor/DataProcessingUnit.java index 618fed1..0d2b03b 100644 --- a/src/main/java/burp/core/processor/DataProcessingUnit.java +++ b/src/main/java/burp/core/processor/DataProcessingUnit.java @@ -12,6 +12,7 @@ import dk.brics.automaton.RegExp; import dk.brics.automaton.RunAutomaton; import java.nio.charset.StandardCharsets; import java.security.NoSuchAlgorithmException; +import java.text.MessageFormat; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @@ -66,13 +67,16 @@ public class DataProcessingUnit { 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]; + String name = objects[1].toString(); + String f_regex = objects[2].toString(); + String s_regex = objects[3].toString(); + String format = objects[4].toString(); + String color = objects[5].toString(); + String scope = objects[6].toString(); + String engine = objects[7].toString(); + boolean sensitive = (Boolean) objects[8]; + // 判断规则是否开启与作用域 if (loaded && (scope.contains(scopeString) || scope.contains("any"))) { switch (scope) { @@ -96,34 +100,9 @@ public class DataProcessingUnit { } try { - 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 { - 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()); - } - } + result.addAll(matchByRegex(f_regex, s_regex, matchContent, format, engine, sensitive)); } catch (Exception e) { - BurpExtender.stdout.println(String.format("[x] Error Info:\nName: %s\nRegex: %s", name, regex)); + BurpExtender.stdout.println(String.format("[x] Error Info:\nName: %s\nRegex: %s", name, f_regex)); e.printStackTrace(); continue; } @@ -190,6 +169,122 @@ public class DataProcessingUnit { GlobalCachePool.addToCache(messageIndex, finalMap); return finalMap; } - } -} \ No newline at end of file + + private List matchByRegex(String f_regex, String s_regex, String content, String format, String engine, boolean sensitive) { + List retList = new ArrayList<>(); + if ("nfa".equals(engine)) { + Matcher matcher = createPatternMatcher(f_regex, content, sensitive); + retList.addAll(extractMatches(s_regex, format, sensitive, matcher)); + } else { + String newContent = content; + String newFirstRegex = f_regex; + if (!sensitive) { + newContent = content.toLowerCase(); + newFirstRegex = f_regex.toLowerCase(); + } + AutomatonMatcher autoMatcher = createAutomatonMatcher(newFirstRegex, newContent); + retList.addAll(extractMatches(s_regex, format, autoMatcher, content)); + } + return retList; + } + + private List extractMatches(String s_regex, String format, boolean sensitive, Matcher matcher) { + List matches = new ArrayList<>(); + if (s_regex.isEmpty()) { + matches.addAll(getFormatString(matcher, format)); + } else { + while (matcher.find()) { + matcher = createPatternMatcher(s_regex, matcher.group(1), sensitive); + matches.addAll(getFormatString(matcher, format)); + } + } + return matches; + } + + private List extractMatches(String s_regex, String format, AutomatonMatcher autoMatcher, String content) { + List matches = new ArrayList<>(); + if (s_regex.isEmpty()) { + matches.addAll(getFormatString(autoMatcher, format, content)); + } else { + while (autoMatcher.find()) { + autoMatcher = createAutomatonMatcher(s_regex, getSubString(content, autoMatcher.group())); + matches.addAll(getFormatString(autoMatcher, format, content)); + } + } + return matches; + } + + public List getFormatString(Matcher matcher, String format) { + List indexList = parseIndexesFromString(format); + List stringList = new ArrayList<>(); + + while (matcher.find()) { + Object[] params = indexList.stream().map(i -> { + if (matcher.group(i+1) != null) { + return matcher.group(i+1); + } + return ""; + }).toArray(); + stringList.add(MessageFormat.format(reorderIndex(format), params)); + } + + return stringList; + } + + public List getFormatString(AutomatonMatcher matcher, String format, String content) { + List indexList = parseIndexesFromString(format); + List stringList = new ArrayList<>(); + + while (matcher.find()) { + Object[] params = indexList.stream().map(i -> getSubString(content, matcher.group(i))).toArray(); + stringList.add(MessageFormat.format(reorderIndex(format), params)); + } + + return stringList; + } + + private Matcher createPatternMatcher(String regex, String content, boolean sensitive) { + Pattern pattern = (sensitive) ? new Pattern(regex) : new Pattern(regex, Pattern.IGNORE_CASE); + return pattern.matcher(content); + } + + private AutomatonMatcher createAutomatonMatcher(String regex, String content) { + RegExp regexp = new RegExp(regex); + Automaton auto = regexp.toAutomaton(); + RunAutomaton runAuto = new RunAutomaton(auto, true); + return runAuto.newMatcher(content); + } + + private LinkedList parseIndexesFromString(String input) { + LinkedList indexes = new LinkedList<>(); + Pattern pattern = new Pattern("\\{(\\d+)}"); + Matcher matcher = pattern.matcher(input); + + while (matcher.find()) { + indexes.add(Integer.valueOf(matcher.group(1))); + } + + return indexes; + } + + private String getSubString(String content, String s) { + int startIndex = content.toLowerCase().indexOf(s); + int endIndex = startIndex + s.length(); + return content.substring(startIndex, endIndex); + } + + private String reorderIndex(String format) { + Pattern pattern = new Pattern("\\{(\\d+)}"); + Matcher matcher = pattern.matcher(format); + int count = 0; + while (matcher.find()) { + String newStr = String.format("{%s}", count); + String matchStr = matcher.group(0); + format = format.replace(matchStr, newStr); + count++; + } + return format; + } +} + diff --git a/src/main/java/burp/rule/RuleProcessor.java b/src/main/java/burp/rule/RuleProcessor.java index 5f655ed..bd1d1b1 100644 --- a/src/main/java/burp/rule/RuleProcessor.java +++ b/src/main/java/burp/rule/RuleProcessor.java @@ -33,7 +33,9 @@ public class RuleProcessor { (String) objects[3], (String) objects[4], (String) objects[5], - (boolean) objects[6])) + (String) objects[6], + (String) objects[7], + (boolean) objects[8])) .collect(Collectors.toList()); ruleGroupList.add(new RuleGroup(k, ruleList)); }); @@ -80,17 +82,20 @@ public class RuleProcessor { ConfigEntry.globalRules.remove(Rules); this.rulesFormatAndSave(); } + public String newRule() { int i = 0; String name = "New "; Object[][] data = new Object[][] { { - false, "New Name", "(New Regex)", "gray", "any", "nfa", false + false, "New Name", "(First Regex)", "(Second Regex)", "{0}", "gray", "any", "nfa", false } }; + while (ConfigEntry.globalRules.containsKey(name + i)) { i++; } + ConfigEntry.globalRules.put(name + i, data); this.rulesFormatAndSave(); return name + i; diff --git a/src/main/java/burp/rule/model/Rule.java b/src/main/java/burp/rule/model/Rule.java index fcc5191..a22a778 100644 --- a/src/main/java/burp/rule/model/Rule.java +++ b/src/main/java/burp/rule/model/Rule.java @@ -10,11 +10,13 @@ import java.util.Map; public class Rule { private Map fields; - public Rule(boolean loaded, String name, String regex, String color, String scope, String engine, boolean sensitive) { + public Rule(boolean loaded, String name, String f_regex, String s_regex, String format, String color, String scope, String engine, boolean sensitive) { fields = new LinkedHashMap<>(); fields.put("name", name); fields.put("loaded", loaded); - fields.put("regex", regex); + fields.put("f_regex", f_regex); + fields.put("s_regex", s_regex); + fields.put("format", format); fields.put("color", color); fields.put("scope", scope); fields.put("engine", engine); diff --git a/src/main/java/burp/ui/MainUI.java b/src/main/java/burp/ui/MainUI.java index b1d293b..de9afd0 100644 --- a/src/main/java/burp/ui/MainUI.java +++ b/src/main/java/burp/ui/MainUI.java @@ -294,7 +294,7 @@ class TabTitleEditListener extends MouseAdapter implements ChangeListener, Docum } public void newTab(){ - Object[][] data = new Object[][]{{false, "New Name", "(New Regex)", "gray", "any", "nfa", false}}; + Object[][] data = new Object[][]{{false, "New Name", "(New Regex)", "", "{0}", "gray", "any", "nfa", false}}; insertTab(ruleEditTabbedPane, ruleProcessor.newRule(),data); } diff --git a/src/main/java/burp/ui/board/Databoard.java b/src/main/java/burp/ui/board/Databoard.java index 60c8808..891633e 100644 --- a/src/main/java/burp/ui/board/Databoard.java +++ b/src/main/java/burp/ui/board/Databoard.java @@ -109,9 +109,28 @@ public class Databoard extends JPanel { GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(8, 0, 5, 5), 0, 0)); + splitPane.addComponentListener(new ComponentAdapter() { + @Override + public void componentResized(ComponentEvent e) { + resizePanel(); + } + }); + setAutoMatch(); } + private void resizePanel() { + splitPane.setDividerLocation(0.4); + TableColumnModel columnModel = table.getColumnModel(); + int totalWidth = (int) (getWidth() * 0.6); + columnModel.getColumn(0).setPreferredWidth((int) (totalWidth * 0.1)); + columnModel.getColumn(1).setPreferredWidth((int) (totalWidth * 0.3)); + columnModel.getColumn(2).setPreferredWidth((int) (totalWidth * 0.3)); + columnModel.getColumn(3).setPreferredWidth((int) (totalWidth * 0.1)); + columnModel.getColumn(4).setPreferredWidth((int) (totalWidth * 0.1)); + columnModel.getColumn(5).setPreferredWidth((int) (totalWidth * 0.1)); + } + private static List getHostByList() { return new ArrayList<>(ConfigEntry.globalDataMap.keySet()); } @@ -236,6 +255,7 @@ public class Databoard extends JPanel { dataTabbedPane.removeAll(); dataTabbedPane.setPreferredSize(new Dimension(500,0)); dataTabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT); + dataTabbedPane.removeChangeListener(changeListenerInstance); splitPane.setLeftComponent(dataTabbedPane); if (selectedHost.contains("*")) { @@ -263,10 +283,12 @@ public class Databoard extends JPanel { } if (selectedHost.equals("**")) { + if (currentWorker != null && !currentWorker.isDone()) { + currentWorker.cancel(true); + } for (ConcurrentHashMap.Entry>> entry : dataMap.entrySet()) { JTabbedPane newTabbedPane = new JTabbedPane(); newTabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT); - for (Map.Entry> entrySet : entry.getValue().entrySet()) { currentWorker = new SwingWorker() { @Override @@ -300,8 +322,6 @@ public class Databoard extends JPanel { dataTabbedPane.addChangeListener(changeListenerInstance); } else { - dataTabbedPane.removeChangeListener(changeListenerInstance); - for (Map.Entry> entry : selectedDataMap.entrySet()) { String tabTitle = String.format("%s (%s)", entry.getKey(), entry.getValue().size()); DatatablePanel datatablePanel = new DatatablePanel(entry.getKey(), entry.getValue()); @@ -315,21 +335,7 @@ public class Databoard extends JPanel { this.splitPane.setRightComponent(messageSplitPane); table = this.messagePanel.getTable(); - this.splitPane.addComponentListener(new ComponentAdapter() { - @Override - public void componentResized(ComponentEvent e) { - splitPane.setDividerLocation(0.4); - TableColumnModel columnModel = table.getColumnModel(); - int totalWidth = (int) (getWidth() * 0.6); - columnModel.getColumn(0).setPreferredWidth((int) (totalWidth * 0.1)); - columnModel.getColumn(1).setPreferredWidth((int) (totalWidth * 0.3)); - columnModel.getColumn(2).setPreferredWidth((int) (totalWidth * 0.3)); - columnModel.getColumn(3).setPreferredWidth((int) (totalWidth * 0.1)); - columnModel.getColumn(4).setPreferredWidth((int) (totalWidth * 0.1)); - columnModel.getColumn(5).setPreferredWidth((int) (totalWidth * 0.1)); - } - }); - + resizePanel(); splitPane.setVisible(true); applyHostFilter(selectedHost); diff --git a/src/main/java/burp/ui/board/DatatablePanel.java b/src/main/java/burp/ui/board/DatatablePanel.java index 0817d30..44a5513 100644 --- a/src/main/java/burp/ui/board/DatatablePanel.java +++ b/src/main/java/burp/ui/board/DatatablePanel.java @@ -66,7 +66,9 @@ public class DatatablePanel extends JPanel { idColumn.setMaxWidth(50); for (String item : list) { - addRowToTable(model, new Object[]{item}); + if (!item.isEmpty()) { + addRowToTable(model, new Object[]{item}); + } } String defaultText = "Search"; diff --git a/src/main/java/burp/ui/board/MessagePanel.java b/src/main/java/burp/ui/board/MessagePanel.java index e135aa7..90b693e 100644 --- a/src/main/java/burp/ui/board/MessagePanel.java +++ b/src/main/java/burp/ui/board/MessagePanel.java @@ -16,11 +16,13 @@ import burp.core.utils.StringHelper; import java.net.URL; import java.nio.charset.StandardCharsets; import java.security.NoSuchAlgorithmException; +import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.JTabbedPane; @@ -216,56 +218,61 @@ public class MessagePanel extends AbstractTableModel implements IMessageEditorCo int responseBodyOffset = helpers.analyzeResponse(responseByte).getBodyOffset(); String responseBody = new String(Arrays.copyOfRange(responseByte, responseBodyOffset, responseByte.length), StandardCharsets.UTF_8); - final boolean[] isMatched = {false}; // 标志变量,表示是否满足过滤条件 + // 标志变量,表示是否满足过滤条件 + AtomicBoolean isMatched = new AtomicBoolean(false); ConfigEntry.globalRules.keySet().forEach(i -> { for (Object[] objects : ConfigEntry.globalRules.get(i)) { String name = objects[1].toString(); - String scope = objects[4].toString(); - if (name.contains(tableName)) { - boolean match = false; // 标志变量,表示当前规则是否匹配 + String format = objects[4].toString(); + String scope = objects[6].toString(); - switch (scope) { - case "any": - match = requestString.contains(filterText) || responseString.contains(filterText); - break; - case "request": - match = requestString.contains(filterText); - break; - case "response": - match = responseString.contains(filterText); - break; - case "any header": - match = requestHeaders.contains(filterText) || responseHeaders.contains(filterText); - break; - case "request header": - match = requestHeaders.contains(filterText); - break; - case "response header": - match = responseHeaders.contains(filterText); - break; - case "any body": - match = requestBody.contains(filterText) || responseBody.contains(filterText); - break; - case "request body": - match = requestBody.contains(filterText); - break; - case "response body": - match = responseBody.contains(filterText); - break; - default: - break; - } + // 从注释中查看是否包含当前规则名,包含的再进行查询,有效减少无意义的检索时间 + if (entry.getComment().contains(name)) { + if (name.equals(tableName)) { + // 标志变量,表示当前规则是否匹配 + boolean isMatch = false; - if (match) { - isMatched[0] = true; + switch (scope) { + case "any": + isMatch = matchingString(format, filterText, requestString) || matchingString(format, filterText, responseString); + break; + case "request": + isMatch = matchingString(format, filterText, requestString); + break; + case "response": + isMatch = matchingString(format, filterText, responseString); + break; + case "any header": + isMatch = matchingString(format, filterText, requestHeaders) || matchingString(format, filterText, responseHeaders); + break; + case "request header": + isMatch = matchingString(format, filterText, requestHeaders); + break; + case "response header": + isMatch = matchingString(format, filterText, responseHeaders); + break; + case "any body": + isMatch = matchingString(format, filterText, requestBody) || matchingString(format, filterText, responseBody); + break; + case "request body": + isMatch = matchingString(format, filterText, requestBody); + break; + case "response body": + isMatch = matchingString(format, filterText, responseBody); + break; + default: + break; + } + + isMatched.set(isMatch); break; } } } }); - if (isMatched[0]) { + if (isMatched.get()) { filteredLog.add(entry); } } @@ -273,6 +280,26 @@ public class MessagePanel extends AbstractTableModel implements IMessageEditorCo logTable.lastSelectedIndex = -1; } + private boolean matchingString(String format, String filterText, String target) { + boolean isMatch = true; + + try { + MessageFormat mf = new MessageFormat(format); + Object[] parsedObjects = mf.parse(filterText); + + for (Object parsedObject : parsedObjects) { + if (!target.contains(parsedObject.toString())) { + isMatch = false; + break; + } + } + } catch (Exception e) { + isMatch = false; + } + + return isMatch; + } + public void deleteByHost(String filterText) { filteredLog.clear(); List rowsToRemove = new ArrayList<>(); diff --git a/src/main/java/burp/ui/rule/RulePane.java b/src/main/java/burp/ui/rule/RulePane.java index 4b66be2..6bce47e 100644 --- a/src/main/java/burp/ui/rule/RulePane.java +++ b/src/main/java/burp/ui/rule/RulePane.java @@ -20,7 +20,7 @@ public class RulePane extends JPanel { private DefaultTableModel model = createModel(); private static final int YES_OPTION = JOptionPane.YES_OPTION; private static final String[] TITLE = { - "Loaded", "Name", "Regex", "Color", "Scope", "Engine", "Sensitive" + "Loaded", "Name", "F-Regex", "S-Regex", "Format", "Color", "Scope", "Engine", "Sensitive" }; public RulePane(Object[][] data, JTabbedPane pane) { @@ -44,14 +44,19 @@ public class RulePane extends JPanel { private void updateModel() { model = (DefaultTableModel) ruleTable.getModel(); } + private void ruleAddActionPerformed(ActionEvent e, JTabbedPane pane) { RuleSetting ruleSettingPanel = new RuleSetting(); + ruleSettingPanel.formatTextField.setText("{0}"); + int showState = JOptionPane.showConfirmDialog(null, ruleSettingPanel, "Add Rule", JOptionPane.OK_OPTION); if (showState == YES_OPTION) { Vector ruleData = new Vector<>(); ruleData.add(false); ruleData.add(ruleSettingPanel.ruleNameTextField.getText()); - ruleData.add(ruleSettingPanel.regexTextField.getText()); + ruleData.add(ruleSettingPanel.firstRegexTextField.getText()); + ruleData.add(ruleSettingPanel.secondRegexTextField.getText()); + ruleData.add(ruleSettingPanel.formatTextField.getText()); ruleData.add(ruleSettingPanel.colorComboBox.getSelectedItem().toString()); ruleData.add(ruleSettingPanel.scopeComboBox.getSelectedItem().toString()); ruleData.add(ruleSettingPanel.engineComboBox.getSelectedItem().toString()); @@ -66,13 +71,15 @@ public class RulePane extends JPanel { if (ruleTable.getSelectedRowCount() >= 1){ RuleSetting ruleSettingPanel = new RuleSetting(); ruleSettingPanel.ruleNameTextField.setText(ruleTable.getValueAt(ruleTable.getSelectedRow(), 1).toString()); - ruleSettingPanel.regexTextField.setText(ruleTable.getValueAt(ruleTable.getSelectedRow(), 2).toString()); - ruleSettingPanel.colorComboBox.setSelectedItem(ruleTable.getValueAt(ruleTable.getSelectedRow(), 3).toString()); - ruleSettingPanel.scopeComboBox.setSelectedItem(ruleTable.getValueAt(ruleTable.getSelectedRow(), 4).toString()); - ruleSettingPanel.engineComboBox.setSelectedItem(ruleTable.getValueAt(ruleTable.getSelectedRow(), 5).toString()); - ruleSettingPanel.sensitiveComboBox.setSelectedItem(ruleTable.getValueAt(ruleTable.getSelectedRow(),6)); + ruleSettingPanel.firstRegexTextField.setText(ruleTable.getValueAt(ruleTable.getSelectedRow(), 2).toString()); + ruleSettingPanel.secondRegexTextField.setText(ruleTable.getValueAt(ruleTable.getSelectedRow(), 3).toString()); + ruleSettingPanel.formatTextField.setText(ruleTable.getValueAt(ruleTable.getSelectedRow(), 4).toString()); + ruleSettingPanel.colorComboBox.setSelectedItem(ruleTable.getValueAt(ruleTable.getSelectedRow(), 5).toString()); + ruleSettingPanel.scopeComboBox.setSelectedItem(ruleTable.getValueAt(ruleTable.getSelectedRow(), 6).toString()); + ruleSettingPanel.engineComboBox.setSelectedItem(ruleTable.getValueAt(ruleTable.getSelectedRow(), 7).toString()); + ruleSettingPanel.sensitiveComboBox.setSelectedItem(ruleTable.getValueAt(ruleTable.getSelectedRow(),8)); - ruleSettingPanel.sensitiveComboBox.setEnabled( + ruleSettingPanel.formatTextField.setEnabled( ruleSettingPanel.engineComboBox.getSelectedItem().toString().equals("nfa") ); @@ -80,11 +87,13 @@ public class RulePane extends JPanel { if (showState == 0){ int select = ruleTable.convertRowIndexToModel(ruleTable.getSelectedRow()); model.setValueAt(ruleSettingPanel.ruleNameTextField.getText(), select, 1); - model.setValueAt(ruleSettingPanel.regexTextField.getText(), select, 2); - model.setValueAt(ruleSettingPanel.colorComboBox.getSelectedItem().toString(), select, 3); - model.setValueAt(ruleSettingPanel.scopeComboBox.getSelectedItem().toString(), select, 4); - model.setValueAt(ruleSettingPanel.engineComboBox.getSelectedItem().toString(), select, 5); - model.setValueAt(ruleSettingPanel.sensitiveComboBox.getSelectedItem(), select, 6); + model.setValueAt(ruleSettingPanel.firstRegexTextField.getText(), select, 2); + model.setValueAt(ruleSettingPanel.secondRegexTextField.getText(), select, 3); + model.setValueAt(ruleSettingPanel.formatTextField.getText(), select, 4); + model.setValueAt(ruleSettingPanel.colorComboBox.getSelectedItem().toString(), select, 5); + model.setValueAt(ruleSettingPanel.scopeComboBox.getSelectedItem().toString(), select, 6); + model.setValueAt(ruleSettingPanel.engineComboBox.getSelectedItem().toString(), select, 7); + model.setValueAt(ruleSettingPanel.sensitiveComboBox.getSelectedItem(), select, 8); model = (DefaultTableModel) ruleTable.getModel(); ruleProcessor.changeRule((Vector) model.getDataVector().get(select), select, pane.getTitleAt(pane.getSelectedIndex())); } @@ -93,7 +102,7 @@ public class RulePane extends JPanel { private void ruleRemoveActionPerformed(ActionEvent e, JTabbedPane pane){ if (ruleTable.getSelectedRowCount() >= 1){ - int isOk = JOptionPane.showConfirmDialog(null, "Are your sure?", "Delete Rule", JOptionPane.OK_OPTION); + int isOk = JOptionPane.showConfirmDialog(null, "Are you sure you want to delete this rule?", "Info", JOptionPane.OK_OPTION); if (isOk == 0){ int select = ruleTable.convertRowIndexToModel(ruleTable.getSelectedRow()); model.removeRow(select); diff --git a/src/main/java/burp/ui/rule/RuleSetting.java b/src/main/java/burp/ui/rule/RuleSetting.java index ca52ec3..f647f20 100644 --- a/src/main/java/burp/ui/rule/RuleSetting.java +++ b/src/main/java/burp/ui/rule/RuleSetting.java @@ -9,8 +9,9 @@ import burp.config.ConfigEntry; */ public class RuleSetting extends JPanel { - - public JTextField regexTextField; + public JTextField firstRegexTextField; + public JTextField secondRegexTextField; + public JTextField formatTextField; public JTextField ruleNameTextField; public JComboBox scopeComboBox; public JComboBox engineComboBox; @@ -29,21 +30,31 @@ public class RuleSetting extends JPanel { addLabel("Name:", 0, c); ruleNameTextField = addTextField(0, c); - addLabel("Regex:", 1, c); - regexTextField = addTextField(1, c); + addLabel("F-Regex:", 1, c); + firstRegexTextField = addTextField(1, c); - addLabel("Scope:", 2, c); - scopeComboBox = addComboBox(ConfigEntry.scopeArray, 2, c); + addLabel("S-Regex:", 2, c); + secondRegexTextField = addTextField(2, c); - addLabel("Engine:", 3, c); - engineComboBox = addComboBox(ConfigEntry.engineArray, 3, c); - engineComboBox.addActionListener(e -> sensitiveComboBox.setEnabled("nfa".equals(engineComboBox.getSelectedItem().toString()))); + addLabel("Format:", 3, c); + formatTextField = addTextField(3, c); - addLabel("Color:", 4, c); - colorComboBox = addComboBox(ConfigEntry.colorArray, 4, c); + addLabel("Scope:", 4, c); + scopeComboBox = addComboBox(ConfigEntry.scopeArray, 4, c); - addLabel("Sensitive:", 5, c); - sensitiveComboBox = addComboBox(new Boolean[]{true, false}, 5, c); + addLabel("Engine:", 5, c); + engineComboBox = addComboBox(ConfigEntry.engineArray, 5, c); + engineComboBox.addActionListener(e -> { + boolean isNfa = "nfa".equals(engineComboBox.getSelectedItem().toString()); + formatTextField.setEnabled(isNfa); + formatTextField.setText(isNfa ? formatTextField.getText() : "{0}"); + }); + + addLabel("Color:", 6, c); + colorComboBox = addComboBox(ConfigEntry.colorArray, 6, c); + + addLabel("Sensitive:", 7, c); + sensitiveComboBox = addComboBox(new Boolean[]{true, false}, 7, c); } private void addLabel(String text, int y, GridBagConstraints c) {