diff --git a/README.md b/README.md index 7de5632..c25586f 100644 --- a/README.md +++ b/README.md @@ -1,50 +1,48 @@ -# HaE - Highlighter and Extractor - -核心功能作者: [@EvilChen](https://github.com/gh0stkey)(中孚信息元亨实验室) - -架构作者: [@0chencc](https://github.com/0Chencc) - -## 公共规则 & 打赏 - -公共规则下载地址:https://gh0st.cn/HaE/ - -如果你觉得HaE好用,可以打赏一下作者,给作者持续更新下去的动力! - -
- +
+ +

赋能白帽,高效作战!

+
第一作者: EvilChen(中孚信息元亨实验室), 第二作者: 0chencc(米斯特安全团队)
-## 介绍 -**HaE**是基于 `BurpSuite` 插件 `JavaAPI` 开发的请求高亮标记与信息提取的辅助型插件。 +## 项目介绍 + +**HaE**是基于 `BurpSuite Java插件API` 开发的请求高亮标记与信息提取的辅助型框架式插件,该插件可以通过自定义正则的方式匹配响应报文或请求报文,并对满足正则匹配的请求进行信息高亮与提取。 ![-w1070](images/16000706401522.jpg) -该插件可以通过自定义正则的方式匹配**响应报文或请求报文**,可以自行决定符合该自定义正则匹配的相应请求是否需要高亮标记、信息提取。 +现代化Web应用走上前后端分离开发模式,这就导致在日常测试时候会有许多的请求流量,如果你想要尽可能全面的对一个Web应用进行测试评估,将花费大量精力浪费在无用的请求上;**HaE的出现正是为了解决这一类似场景**,借助HaE你可以有效的减少测试的时间,将更多的精力放在**有价值、有意义**的请求上,**大幅度**的减少无效测试时间,**提高漏洞挖掘效率**。 -**注**: `HaE`的使用,对测试人员来说需要基本的正则表达式基础,由于`Java`正则表达式的库并没有`Python`的优雅或方便,在使用正则的,HaE要求使用者必须使用`()`将所需提取的表达式内容包含;例如你要匹配一个**Shiro应用**的响应报文,正常匹配规则为`rememberMe=delete`,如果你要提取这段内容的话就需要变成`(rememberMe=delete)`。 +**注**: 要想灵活的使用`HaE`,你需要掌握正则表达式阅读、编写、修改能力;由于`Java`正则表达式的库并没有`Python`的优雅或方便,在使用正则的,HaE要求使用者必须使用`()`将所需提取的表达式内容包含;例如你要匹配一个**Shiro应用**的响应报文,正常匹配规则为`rememberMe=delete`,如果你要提取这段内容的话就需要变成`(rememberMe=delete)`。 ## 使用方法 插件装载: `Extender - Extensions - Add - Select File - Next` -初次装载`HaE`会初始化配置文件,默认配置文件内置一个正则: `Email`,初始化的配置文件会放在与`BurpSuite Jar`包同级目录下。 +初次装载`HaE`会初始化配置文件,默认配置文件内置一个正则: `Email`,初始化的配置文件会放在的`/用户根目录/.config/HaE/`目录下。 -除了初始化的配置文件外,还有`Setting.yml`,该文件用于存储配置文件路径;`HaE`支持自定义配置文件路径,你可以通过点击`Select File`按钮进行选择自定义配置文件。 +![-w477](images/show_config.png) -![-w477](images/16000710069404.jpg) +除了初始化的配置文件外,还有`Setting.yml`,该文件用于存储配置文件路径与排除后缀名;`HaE`支持自定义配置文件路径,你可以通过点击`Select File`按钮进行选择自定义配置文件。 -## 插件优点 +## 优势特点 + +1. **精细化配置项**:高自由度配置更适配精细化场景需求; +2. **简洁可视界面**:简洁的可视化界面让你更加清晰了解HaE的各项配置,操作更轻松,使用更简单; +3. **颜色升级算法**:内置颜色升级算法,避免“屠龙者终成恶龙”场景,突出最具价值的请求; +4. **标签化规则项**:标签化你的正则规则,让规则可分类,让管理更轻松; +5. **数据集合面板**:将所有匹配数据集合到Databoard中,使得测试、梳理更高效; +6. **高亮标记一体**:在Proxy - History页面你可以通过颜色高亮与Comment判断请求价值; +7. **实战化官方库**:基于实战化场景、案例进行输出的官方规则库,提升测试实战性; +8. **配置文件易读**:配置文件使用YAML格式存储,更加便于阅读与修改。 + +| 界面名称 | 界面展示 | +| ------------------------- | ----------------------------------------------------- | +| Rules(规则信息管理) | | +| Config(配置信息管理) | | +| Databoard(数据集合面板) | | -1. 多选项自定义控制适配需求 -2. 多颜色高亮分类,将BurpSuite的所有高亮颜色集成: `red, orange, yellow, green, cyan, blue, pink, magenta, gray` -3. **颜色升级算法**: 利用下标的方式进行优先级排序,当满足2个同颜色条件则以优先级顺序上升颜色(例如: **两个正则,颜色为橘黄色,该请求两个正则都匹配到了,那么将升级为红色**) -4. 配置文件采用YAML格式存储,更加便于阅读和修改 -5. 内置简单缓存,在“多正则、大数据”的场景下减少卡顿现象 -6. **支持标签分页**,点击`...`即可添加新的标签页,对着标签页右键即可删除 -7. 高亮信息添加的同时添加Comment,便于查找请求 -![-w477](images/16000720732851.jpg) ## 实际使用 @@ -56,41 +54,15 @@ ![-w1047](images/16000720732854.png) +## 文末随笔 -## 正则优化 +正义感是一个不可丢失的东西。 -有些正则在实战应用场景中并不理想 +如果你觉得HaE好用,可以打赏一下作者,给作者持续更新下去的动力! -在正则匹配手机号、身份证号码的时候(纯数字类)会存在一些误报(这里匹配身份证号码无法进行校验,误报率很高),但手机号处理这一块可以解决: - -原正则: - -``` -1[3-9]\d{9} -``` - -误报场景: `12315188888888123`,这时候会匹配到`15188888888`,而实际上这一段并不是手机号,所以修改正则为: - -``` -[^0-9]+(1[3-9]\d{9})[^0-9]+ -``` - -也就是要求匹配的手机号前后不能为0-9的数字。 - -## 实战用法 - -1. CMS指纹识别,Discuz正则: `(Powered by Discuz!)` -2. OSS对象存储信息泄露,正则: `([A|a]ccess[K|k]ey[I|i]d|[A|a]ccess[K|k]ey[S|s]ecret)` -3. 内网地址信息提取,正则: `(?:10\.\d{1,3}\.\d{1,3}\.\d{1,3})|(?:172\.(?:(?:1[6-9])|(?:2\d)|(?:3[01]))\.\d{1,3}\.\d{1,3})|(?:192\.168\.\d{1,3}\.\d{1,3})` -4. 实战插件关联搭配,漏洞挖掘案例: https://mp.weixin.qq.com/s/5vNn7dMRZBtv0ojPBAHV7Q - -...还有诸多使用方法等待大家去发掘。 - -## 文末 - -随笔: 正义感是一个不可丢失的东西。 - -Github项目地址(BUG、需求、正则欢迎提交): https://github.com/gh0stkey/HaE +
+ +
## 404StarLink 2.0 - Galaxy diff --git a/images/16000710069404.jpg b/images/16000710069404.jpg deleted file mode 100644 index 94a75ae..0000000 Binary files a/images/16000710069404.jpg and /dev/null differ diff --git a/images/16000720732851.jpg b/images/16000720732851.jpg deleted file mode 100644 index 67d2675..0000000 Binary files a/images/16000720732851.jpg and /dev/null differ diff --git a/images/config.png b/images/config.png new file mode 100644 index 0000000..b1a0c20 Binary files /dev/null and b/images/config.png differ diff --git a/images/databoard.png b/images/databoard.png new file mode 100644 index 0000000..9b76c60 Binary files /dev/null and b/images/databoard.png differ diff --git a/images/logo.png b/images/logo.png new file mode 100644 index 0000000..db79428 Binary files /dev/null and b/images/logo.png differ diff --git a/images/rules.png b/images/rules.png new file mode 100644 index 0000000..5cf7e09 Binary files /dev/null and b/images/rules.png differ diff --git a/images/show_config.png b/images/show_config.png new file mode 100644 index 0000000..1a44e1b Binary files /dev/null and b/images/show_config.png differ diff --git a/src/main/java/burp/BurpExtender.java b/src/main/java/burp/BurpExtender.java index 9de4c1c..d1be700 100644 --- a/src/main/java/burp/BurpExtender.java +++ b/src/main/java/burp/BurpExtender.java @@ -19,7 +19,8 @@ import javax.swing.event.ChangeListener; public class BurpExtender implements IBurpExtender, IHttpListener, IMessageEditorTabFactory, ITab { private final MainUI main = new MainUI(); - private static PrintWriter stdout; + // stdout变成公开属性,便于其他类调用输出调试信息 + public static PrintWriter stdout; private IBurpExtenderCallbacks callbacks; private static IExtensionHelpers helpers; GetColorKey gck = new GetColorKey(); @@ -32,7 +33,7 @@ public class BurpExtender implements IBurpExtender, IHttpListener, IMessageEdito this.callbacks = callbacks; BurpExtender.helpers = callbacks.getHelpers(); - String version = "2.3"; + String version = "2.4"; callbacks.setExtensionName(String.format("HaE (%s) - Highlighter and Extractor", version)); // 定义输出 stdout = new PrintWriter(callbacks.getStdout(), true); @@ -75,15 +76,27 @@ public class BurpExtender implements IBurpExtender, IHttpListener, IMessageEdito content = messageInfo.getResponse(); } + IHttpService iHttpService = null; + try { + iHttpService = messageInfo.getHttpService(); + } catch (Exception ignored) { + } + // 获取请求主机信息 + assert iHttpService != null; + String host = iHttpService.getHost(); + String c = new String(content, StandardCharsets.UTF_8).intern(); - List> result = pm.processMessageByContent(helpers, content, messageIsRequest, true); + + List> result = pm.processMessageByContent(helpers, content, messageIsRequest, true, host); if (result != null && !result.isEmpty() && result.size() > 0) { String originalColor = messageInfo.getHighlight(); String originalComment = messageInfo.getComment(); List colorList = new ArrayList<>(); + if (originalColor != null) { colorList.add(originalColor); } + colorList.add(result.get(0).get("color")); String color = uc.getEndColor(gck.getColorKeys(colorList)); @@ -126,7 +139,7 @@ public class BurpExtender implements IBurpExtender, IHttpListener, IMessageEdito @Override public boolean isEnabled(byte[] content, boolean isRequest) { String c = new String(content, StandardCharsets.UTF_8).intern(); - List> result = pm.processMessageByContent(helpers, content, isRequest, false); + List> result = pm.processMessageByContent(helpers, content, isRequest, false, ""); if (result != null && !result.isEmpty()) { Map dataMap = result.get(0); if (isRequest) { @@ -189,7 +202,7 @@ public class BurpExtender implements IBurpExtender, IHttpListener, IMessageEdito Object[][] data = new Object[extractData.length][1]; for (int x = 0; x < extractData.length; x++) { data[x][0] = extractData[x]; - stdout.println(extractData[x]); + // stdout.println(extractData[x]); } int indexOfTab = this.jTabbedPane.indexOfTab(i); JScrollPane jScrollPane = new JScrollPane(new JTable(data, new Object[] {"Information"})); @@ -202,8 +215,6 @@ public class BurpExtender implements IBurpExtender, IHttpListener, IMessageEdito } } - - @Override public IMessageEditorTab createNewInstance(IMessageEditorController controller, boolean editable) { return new MarkInfoTab(controller, editable); diff --git a/src/main/java/burp/Config.java b/src/main/java/burp/Config.java index ab6ea6c..a86685a 100644 --- a/src/main/java/burp/Config.java +++ b/src/main/java/burp/Config.java @@ -4,6 +4,8 @@ package burp; * @author EvilChen */ +import java.util.HashMap; +import java.util.List; import java.util.Map; public class Config { @@ -37,4 +39,6 @@ public class Config { }; public static Map ruleConfig = null; + + public static Map>> globalDataMap = new HashMap<>(); } \ No newline at end of file diff --git a/src/main/java/burp/action/DoAction.java b/src/main/java/burp/action/DoAction.java index 3b9f8c6..89d2f87 100644 --- a/src/main/java/burp/action/DoAction.java +++ b/src/main/java/burp/action/DoAction.java @@ -1,8 +1,8 @@ package burp.action; +import burp.BurpExtender; import java.util.HashMap; import java.util.Map; -import burp.Config; import java.util.ArrayList; import java.util.List; @@ -12,11 +12,11 @@ import java.util.List; public class DoAction { public Map extractString(Map> obj) { - Map resultMap = new HashMap(); + Map resultMap = new HashMap<>(); obj.keySet().forEach(i->{ Map tmpMap = obj.get(i); String data = tmpMap.get("data").toString(); - resultMap.put(i, String.format("%s\n", data).intern()); + resultMap.put(i, data); }); return resultMap; } diff --git a/src/main/java/burp/action/ExtractContent.java b/src/main/java/burp/action/ExtractContent.java index 7044125..48a0dc1 100644 --- a/src/main/java/burp/action/ExtractContent.java +++ b/src/main/java/burp/action/ExtractContent.java @@ -2,7 +2,6 @@ package burp.action; import java.nio.charset.StandardCharsets; import java.util.*; - import burp.Config; import dk.brics.automaton.Automaton; import dk.brics.automaton.AutomatonMatcher; @@ -17,7 +16,7 @@ import jregex.Pattern; public class ExtractContent { - public Map> matchRegex(byte[] content, String headers, byte[] body, String scopeString) { + public Map> matchRegex(byte[] content, String headers, byte[] body, String scopeString, String host) { Map> map = new HashMap<>(); // 最终返回的结果 Config.ruleConfig.keySet().forEach(i -> { String matchContent = ""; @@ -61,6 +60,7 @@ public class ExtractContent { } else { pattern = new Pattern(regex, Pattern.IGNORE_CASE); } + Matcher matcher = pattern.matcher(matchContent); while (matcher.find()) { // 添加匹配数据至list @@ -94,6 +94,38 @@ public class ExtractContent { } }); + // host: {Name, List} + if (!host.isEmpty()) { + map.keySet().forEach(i -> { + Map tmpMap = map.get(i); + List dataList = Arrays.asList(tmpMap.get("data").toString().split("\n")); + // 判断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<>(); + // 合并两个List + mergeDataList.addAll(gDataList); + mergeDataList.addAll(dataList); + // 去重操作 + HashSet tmpList = new HashSet(mergeDataList); + mergeDataList.clear(); + mergeDataList.addAll(tmpList); + // 替换操作 + gRuleMap.replace(i, gDataList, mergeDataList); + } else { + gRuleMap.put(i, dataList); + } + } else { + Map> ruleMap = new HashMap<>(); + ruleMap.put(i, dataList); + Config.globalDataMap.put(host, ruleMap); + } + }); + } + return map; } } diff --git a/src/main/java/burp/action/ProcessMessage.java b/src/main/java/burp/action/ProcessMessage.java index b66320b..558c257 100644 --- a/src/main/java/burp/action/ProcessMessage.java +++ b/src/main/java/burp/action/ProcessMessage.java @@ -1,8 +1,6 @@ package burp.action; import burp.IExtensionHelpers; -import burp.IHttpService; - import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -16,7 +14,7 @@ public class ProcessMessage { GetColorKey gck = new GetColorKey(); UpgradeColor uc = new UpgradeColor(); - public List> processMessageByContent(IExtensionHelpers helpers, byte[] content, boolean isRequest, boolean messageInfo) { + public List> processMessageByContent(IExtensionHelpers helpers, byte[] content, boolean isRequest, boolean messageInfo, String host) { List> result = new ArrayList<>();; Map> obj; @@ -44,7 +42,7 @@ public class ProcessMessage { int requestBodyOffset = helpers.analyzeRequest(content).getBodyOffset(); byte[] requestBody = Arrays.copyOfRange(content, requestBodyOffset, content.length); - obj = ec.matchRegex(content, requestHeaders, requestBody, "request"); + obj = ec.matchRegex(content, requestHeaders, requestBody, "request", host); } else { try { // 流量清洗 @@ -65,26 +63,26 @@ public class ProcessMessage { int responseBodyOffset = helpers.analyzeResponse(content).getBodyOffset(); byte[] responseBody = Arrays.copyOfRange(content, responseBodyOffset, content.length); - obj = ec.matchRegex(content, responseHeaders, responseBody, "response"); + obj = ec.matchRegex(content, responseHeaders, responseBody, "response", host); } - if (messageInfo) { - List> resultList = da.highlightAndComment(obj); - List colorList = resultList.get(0); - List commentList = resultList.get(1); - if (colorList.size() != 0 && commentList.size() != 0) { - String color = uc.getEndColor(gck.getColorKeys(colorList)); - Map colorMap = new HashMap(){{ - put("color", color); - }}; - Map commentMap = new HashMap(){{ - put("comment", String.join(", ", commentList)); - }}; - result.add(colorMap); - result.add(commentMap); - } - } else { - if (obj.size() > 0) { + if (obj.size() > 0) { + if (messageInfo) { + List> resultList = da.highlightAndComment(obj); + List colorList = resultList.get(0); + List commentList = resultList.get(1); + if (colorList.size() != 0 && commentList.size() != 0) { + String color = uc.getEndColor(gck.getColorKeys(colorList)); + Map colorMap = new HashMap(){{ + put("color", color); + }}; + Map commentMap = new HashMap(){{ + put("comment", String.join(", ", commentList)); + }}; + result.add(colorMap); + result.add(commentMap); + } + } else { result.add(da.extractString(obj)); } } diff --git a/src/main/java/burp/ui/Databoard.java b/src/main/java/burp/ui/Databoard.java new file mode 100644 index 0000000..c45908c --- /dev/null +++ b/src/main/java/burp/ui/Databoard.java @@ -0,0 +1,190 @@ +package burp.ui; + +import burp.Config; +import java.util.List; +import javax.swing.table.DefaultTableModel; +import org.jetbrains.annotations.NotNull; + +import java.awt.*; +import java.awt.event.*; +import java.util.ArrayList; +import java.util.Map; +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; + +/** + * @author LinChen + */ + +public class Databoard extends JPanel { + public Databoard() { + initComponents(); + } + + private void initComponents() { + // JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents + hostLabel = new JLabel(); + hostTextField = new JTextField(); + dataTabbedPane = new JTabbedPane(); + + //======== this ======== + setLayout(new GridBagLayout()); + ((GridBagLayout)getLayout()).columnWidths = new int[] {25, 0, 0, 0, 20, 0}; + ((GridBagLayout)getLayout()).rowHeights = new int[] {0, 65, 20, 0}; + ((GridBagLayout)getLayout()).columnWeights = new double[] {0.0, 0.0, 1.0, 0.0, 0.0, 1.0E-4}; + ((GridBagLayout)getLayout()).rowWeights = new double[] {0.0, 1.0, 0.0, 1.0E-4}; + + //---- hostLabel ---- + hostLabel.setText("Host:"); + add(hostLabel, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, + GridBagConstraints.CENTER, GridBagConstraints.BOTH, + new Insets(8, 0, 5, 5), 0, 0)); + add(hostTextField, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0, + GridBagConstraints.CENTER, GridBagConstraints.BOTH, + new Insets(8, 0, 5, 5), 0, 0)); + + add(dataTabbedPane, new GridBagConstraints(1, 1, 3, 2, 0.0, 0.0, + GridBagConstraints.CENTER, GridBagConstraints.BOTH, + new Insets(8, 0, 0, 5), 0, 0)); + + setAutoMatch(hostTextField, dataTabbedPane); + } + + /** + * 获取Host列表 + */ + private static List getHostByList(){ + List hostList = new ArrayList<>(); + Config.globalDataMap.keySet().forEach(i -> { + hostList.add(i); + }); + return hostList; + } + + /** + * 设置输入自动匹配 + */ + public static void setAutoMatch(JTextField textField, JTabbedPane tabbedPane) { + final DefaultComboBoxModel comboBoxModel = new DefaultComboBoxModel(); + + final JComboBox hostComboBox = new JComboBox(comboBoxModel) { + @Override + public Dimension getPreferredSize() { + return new Dimension(super.getPreferredSize().width, 0); + } + }; + + isMatchHost = false; + + for (String host : getHostByList()) { + comboBoxModel.addElement(host); + } + + hostComboBox.setSelectedItem(null); + + hostComboBox.addActionListener(e -> { + if (!isMatchHost) { + if (hostComboBox.getSelectedItem() != null) { + textField.setText(hostComboBox.getSelectedItem().toString()); + getInfoByHost(hostComboBox, tabbedPane, textField); + } + } + }); + + // 事件监听 + textField.addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + isMatchHost = true; + if (e.getKeyCode() == KeyEvent.VK_SPACE) { + if (hostComboBox.isPopupVisible()) { + e.setKeyCode(KeyEvent.VK_ENTER); + } + } + if (e.getKeyCode() == KeyEvent.VK_ENTER + || e.getKeyCode() == KeyEvent.VK_UP + || e.getKeyCode() == KeyEvent.VK_DOWN) { + e.setSource(hostComboBox); + hostComboBox.dispatchEvent(e); + if (e.getKeyCode() == KeyEvent.VK_ENTER) { + textField.setText(hostComboBox.getSelectedItem().toString()); + getInfoByHost(hostComboBox, tabbedPane, textField); + hostComboBox.setPopupVisible(false); + } + } + if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { + hostComboBox.setPopupVisible(false); + } + isMatchHost = false; + } + }); + + textField.getDocument().addDocumentListener(new DocumentListener() { + @Override + public void insertUpdate(DocumentEvent e) { + updateList(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + updateList(); + } + + @Override + public void changedUpdate(DocumentEvent e) { + updateList(); + } + + private void updateList() { + isMatchHost = true; + comboBoxModel.removeAllElements(); + String input = textField.getText(); + if (!input.isEmpty()){ + for (String host : getHostByList()) { + if (host.toLowerCase().contains(input.toLowerCase())) { + comboBoxModel.addElement(host); + } + } + } + hostComboBox.setPopupVisible(comboBoxModel.getSize() > 0); + isMatchHost = false; + } + }); + + textField.setLayout(new BorderLayout()); + textField.add(hostComboBox, BorderLayout.SOUTH); + } + + private static void getInfoByHost(@NotNull JComboBox hostComboBox, JTabbedPane tabbedPane, JTextField textField) { + if (hostComboBox.getSelectedItem() != null) { + Map>> ruleMap = Config.globalDataMap; + Map> selectUrl = ruleMap.get(hostComboBox.getSelectedItem()); + tabbedPane.removeAll(); + for(Map.Entry> entry: selectUrl.entrySet()){ + tabbedPane.addTab(entry.getKey(), new JScrollPane(new HitRuleDataList(entry.getValue()))); + } + textField.setText(hostComboBox.getSelectedItem().toString()); + } + } + + // JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables + private JLabel hostLabel; + private JTextField hostTextField; + private JTabbedPane dataTabbedPane; + // JFormDesigner - End of variables declaration //GEN-END:variables + + // 是否自动匹配Host + private static Boolean isMatchHost = false; +} +class HitRuleDataList extends JTable { + public HitRuleDataList(List list){ + DefaultTableModel model = new DefaultTableModel(); + Object[][] data = new Object[list.size()][1]; + for (int x = 0; x < list.size(); x++) { + data[x][0] = list.get(x); + } + model.setDataVector(data, new Object[]{"Information"}); + this.setModel(model); + } +} diff --git a/src/main/java/burp/ui/MainUI.java b/src/main/java/burp/ui/MainUI.java index 2c025c6..bee2247 100644 --- a/src/main/java/burp/ui/MainUI.java +++ b/src/main/java/burp/ui/MainUI.java @@ -79,7 +79,7 @@ public class MainUI extends JPanel{ loadCon.setExcludeSuffix(excludeSuffixTextField.getText()); } private void initComponents() { - rulesTabbedPane = new JTabbedPane(); + mainTabbedPane = new JTabbedPane(); ruleTabbedPane = new JTabbedPane(); rulePanel = new JPanel(); configTextField = new JTextField(); @@ -97,7 +97,7 @@ public class MainUI extends JPanel{ ((GridBagLayout)getLayout()).rowWeights = new double[] {1.0, 1.0E-4}; { - rulesTabbedPane.addTab("Rules", ruleTabbedPane); + mainTabbedPane.addTab("Rules", ruleTabbedPane); { rulePanel.setLayout(new GridBagLayout()); @@ -158,9 +158,10 @@ public class MainUI extends JPanel{ GridBagConstraints.SOUTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 5), 0, 0)); } - rulesTabbedPane.addTab("Config", rulePanel); + mainTabbedPane.addTab("Config", rulePanel); + mainTabbedPane.addTab("Databoard", databoardPanel); } - add(rulesTabbedPane, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, + add(mainTabbedPane, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); @@ -178,7 +179,7 @@ public class MainUI extends JPanel{ tabMenu.add(closeTabMenuItem); } - private JTabbedPane rulesTabbedPane; + private JTabbedPane mainTabbedPane; private JTabbedPane ruleTabbedPane; private JPanel rulePanel; private JTextField configTextField; @@ -188,7 +189,7 @@ public class MainUI extends JPanel{ private JLabel excludeSuffixLabel; private JTextField excludeSuffixTextField; private JButton excludeSuffixSaveButton; - + private Databoard databoardPanel = new Databoard(); protected static JPopupMenu tabMenu = new JPopupMenu(); private JMenuItem closeTabMenuItem = new JMenuItem("Delete"); private TabTitleEditListener ruleSwitch; diff --git a/src/main/java/burp/ui/RulePane.java b/src/main/java/burp/ui/RulePane.java index be894d8..bfe26cb 100644 --- a/src/main/java/burp/ui/RulePane.java +++ b/src/main/java/burp/ui/RulePane.java @@ -50,7 +50,7 @@ public class RulePane extends JPanel { 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).toString()); + ruleSettingPanel.sensitiveComboBox.setSelectedItem(ruleTable.getValueAt(ruleTable.getSelectedRow(),6)); ruleSettingPanel.sensitiveComboBox.setEnabled( ruleSettingPanel.engineComboBox.getSelectedItem().toString().equals("nfa") diff --git a/src/main/java/burp/yaml/LoadConfig.java b/src/main/java/burp/yaml/LoadConfig.java index a35d405..68cc52f 100644 --- a/src/main/java/burp/yaml/LoadConfig.java +++ b/src/main/java/burp/yaml/LoadConfig.java @@ -17,19 +17,27 @@ import org.yaml.snakeyaml.nodes.Tag; public class LoadConfig { private static final Yaml yaml = new Yaml(); - private static final String SettingPath = "Setting.yml"; - private static final String ConfigPath = "Config.yml"; + private static String HaEConfigPath = String.format("%s/.config/HaE", System.getProperty("user.home")); + private static String SettingPath = String.format("%s/%s", HaEConfigPath, "Setting.yml"); + private static String ConfigPath = String.format("%s/%s", HaEConfigPath, "Config.yml"); public LoadConfig() { // 构造函数,初始化配置 - File yamlSetting = new File(SettingPath); - if (!(yamlSetting.exists() && yamlSetting.isFile())) { + + File HaEConfigPathFile = new File(HaEConfigPath); + if (!(HaEConfigPathFile.exists() && HaEConfigPathFile.isDirectory())) { + HaEConfigPathFile.mkdirs(); + } + + File settingPathFile = new File(SettingPath); + if (!(settingPathFile.exists() && settingPathFile.isFile())) { initSetting(); initRules(); } Config.ruleConfig = LoadConfig.getRules(); } + // 初始化设置信息 public void initSetting() { Map r = new HashMap<>();