Merge pull request #4 from gh0stkey/master

HaE 1.4.1
This commit is contained in:
HannahLaw-Portswigger
2020-11-12 11:26:34 +00:00
committed by GitHub
6 changed files with 160 additions and 111 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

View File

@@ -6,13 +6,13 @@ Read Chinese simplified version ([README_zh](README_zh.md)).
## Introduction ## Introduction
**HaE** is used to highlight HTTP requests and extract information from HTTP response messages. **HaE** is used to highlight HTTP requests and extract information from HTTP `response messages` or `request messages`.
![-w1070](images/16000706401522.jpg) ![-w1070](images/16000706401522.jpg)
The plugin can custom regular expression to match HTTP response messages. You can decide for yourself whether the corresponding request that meets the custom regular expression match needs to be highlighted and information extracted. The plugin can custom regular expression to match HTTP response messages. You can decide for yourself whether the corresponding request that meets the custom regular expression match needs to be highlighted and information extracted.
**Note**The use of HaE requires a basic regular expression foundation for testers. Since the Java regular expression library is not as elegant or convenient as Python, when using regular expressions, HaE requires users to use `()` to extract what they need The expression content contains; for example, if you want to match a response message of a Shiro application, the normal matching rule is `rememberMe=delete`, if you want to extract this content, you need to become `(rememberMe=delete)`. **Note**: The use of HaE requires a basic regular expression foundation for testers. Since the Java regular expression library is not as elegant or convenient as Python, when using regular expressions, HaE requires users to use `()` to extract what they need The expression content contains; for example, if you want to match a response message of a Shiro application, the normal matching rule is `rememberMe=delete`, if you want to extract this content, you need to become `(rememberMe=delete)`.
## Instructions ## Instructions
@@ -32,16 +32,16 @@ HaE supports three actions:
2. New: Add a new rule will automatically add a row of table data, click or double-click to modify the data to automatically save; 2. New: Add a new rule will automatically add a row of table data, click or double-click to modify the data to automatically save;
3. Delete: When you click to select a rule, press this button to delete the rule. 3. Delete: When you click to select a rule, press this button to delete the rule.
**Note**`HaE's operations` are based on the form UI, and all operations will be automatically saved. **Note**: `HaE's operations` are based on the form UI, and all operations will be automatically saved.
## Plugin Advantages ## Plugin Advantages
1. Multi-option custom adaptation requirements; 1. Multi-option custom adaptation requirements;
2. Multi-color classification (colors of BurpSuite)`red, orange, yellow, green, cyan, blue, pink, magenta, gray`; 2. Multi-color classification (colors of BurpSuite): `red, orange, yellow, green, cyan, blue, pink, magenta, gray`;
3. Color upgrade algorithm: **Two regulars expression, the colors are both orange, if the request are matched these, it will be upgraded to red.** 3. Color upgrade algorithm: **Two regulars expression, the colors are both orange, if the request are matched these, it will be upgraded to red.**
4. The configuration file format uses JSON format, the format is 4. The configuration file format uses JSON format, the format is
``` ```
{name: {"loaded": isLoaded:,"regex": regexText, "highlight": isHighlight, "extract": isExtract, "color": colorText}} {name: {"loaded": isLoaded,"regex": regexText, "scope": request/response/any, "action": extract/highlight/any, "color": colorText}}
``` ```
5. Built-in simple cache to reduce the stuttering phenomenon in the `multi-regular, big data scenario`. 5. Built-in simple cache to reduce the stuttering phenomenon in the `multi-regular, big data scenario`.
@@ -62,7 +62,7 @@ Some regular expression are not ideal in actual combat application scenarios.
There will be some false positives when regular expression matching mobile phone numbers (pure numbers), the mobile phone number processing can be solved: There will be some false positives when regular expression matching mobile phone numbers (pure numbers), the mobile phone number processing can be solved:
Original regular expression Original regular expression:
``` ```
1[3-9]\d{9} 1[3-9]\d{9}
@@ -79,15 +79,21 @@ The mobile phone number required to be matched cannot be a number from 0-9.
### Include Regular Expression List ### Include Regular Expression List
Chinese ID-NumberFrom: https://github.com/gh0stkey/HaE/issues/3 Chinese ID-Number(From: https://github.com/gh0stkey/HaE/issues/3):
``` ```
[^0-9]([1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx])|([1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{2}[0-9Xx])[^0-9] [^0-9]([1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx])|([1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{2}[0-9Xx])[^0-9]
``` ```
Email Address Email Address:
``` ```
([\w-]+(?:\.[\w-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?) ([\w-]+(?:\.[\w-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?)
``` ```
Elasticsearch Unauthorized Access(From: https://github.com/gh0stkey/HaE/issues/7):
```
("cluster_uuid"\s*:\s*"[A-Za-z0-9_-]{22}")
```

View File

@@ -6,15 +6,15 @@
![-w1070](images/16000706401522.jpg) ![-w1070](images/16000706401522.jpg)
该插件可以通过自定义正则的方式匹配**响应报文**,可以自行决定符合该自定义正则匹配的相应请求是否需要高亮标记、信息提取。 该插件可以通过自定义正则的方式匹配**响应报文或请求报文**,可以自行决定符合该自定义正则匹配的相应请求是否需要高亮标记、信息提取。
**注**`HaE`的使用,对测试人员来说需要基本的正则表达式基础,由于`Java`正则表达式的库并没有`Python`的优雅或方便在使用正则的HaE要求使用者必须使用`()`将所需提取的表达式内容包含;例如你要匹配一个**Shiro应用**的响应报文,正常匹配规则为`rememberMe=delete`,如果你要提取这段内容的话就需要变成`(rememberMe=delete)` **注**: `HaE`的使用,对测试人员来说需要基本的正则表达式基础,由于`Java`正则表达式的库并没有`Python`的优雅或方便在使用正则的HaE要求使用者必须使用`()`将所需提取的表达式内容包含;例如你要匹配一个**Shiro应用**的响应报文,正常匹配规则为`rememberMe=delete`,如果你要提取这段内容的话就需要变成`(rememberMe=delete)`
## 使用方法 ## 使用方法
插件装载`Extender - Extensions - Add - Select File - Next` 插件装载: `Extender - Extensions - Add - Select File - Next`
初次装载`HaE`会初始化配置文件,默认配置文件内置一个正则`Email`,初始化的配置文件会放在与`BurpSuite Jar`包同级目录下。 初次装载`HaE`会初始化配置文件,默认配置文件内置一个正则: `Email`,初始化的配置文件会放在与`BurpSuite Jar`包同级目录下。
![-w330](images/16000708493657.jpg) ![-w330](images/16000708493657.jpg)
@@ -22,28 +22,28 @@
![-w477](images/16000710069404.jpg) ![-w477](images/16000710069404.jpg)
HaE支持三个动作 HaE支持三个动作:
1. 重载规则Reload当你不使用HaE UI界面去修改配置文件内的规则时而是直接基于配置文件进行修改规则时可使用 1. 重载规则Reload: 当你不使用HaE UI界面去修改配置文件内的规则时而是直接基于配置文件进行修改规则时可使用
2. 新建规则New新建规则会自动添加一行表格数据,单击或双击进行修改数据即可自动保存; 2. 新建规则New: 新建规则会自动添加一行表格数据,单击或双击进行修改数据即可自动保存;
3. 删除规则Delete单击选中某条规则时,按下该按钮即可删除规则。 3. 删除规则Delete: 单击选中某条规则时,按下该按钮即可删除规则。
**注**HaE的操作都是基于表单UI的方式操作即会自动保存。 **注**: HaE的操作都是基于表单UI的方式操作即会自动保存。
## 插件优点 ## 插件优点
1. 多选项自定义控制适配需求; 1. 多选项自定义控制适配需求;
2. 多颜色高亮分类将BurpSuite的所有高亮颜色集成`red, orange, yellow, green, cyan, blue, pink, magenta, gray` 2. 多颜色高亮分类将BurpSuite的所有高亮颜色集成: `red, orange, yellow, green, cyan, blue, pink, magenta, gray`
3. 颜色升级算法利用下标的方式进行优先级排序当满足2个同颜色条件则以优先级顺序上升颜色。例如**两个正则,颜色为橘黄色,该请求两个正则都匹配到了,那么将升级为红色** 3. 颜色升级算法: 利用下标的方式进行优先级排序当满足2个同颜色条件则以优先级顺序上升颜色。例如: **两个正则,颜色为橘黄色,该请求两个正则都匹配到了,那么将升级为红色**
4. 简单的配置文件格式选用JSON格式格式为 4. 简单的配置文件格式选用JSON格式格式为
``` ```
{name: {"loaded": isLoaded:,"regex": regexText, "highlight": isHighlight, "extract": isExtract, "color": colorText}} {name: {"loaded": isLoaded,"regex": regexText, "scope": request/response/any, "action": extract/highlight/any, "color": colorText}}
``` ```
5. 内置简单缓存,在“多正则、大数据”的场景下减少卡顿现象。 5. 内置简单缓存,在“多正则、大数据”的场景下减少卡顿现象。
## 实际使用 ## 实际使用
使用 RGPerson 生成测试数据,放入网站根目录文件中 使用 RGPerson 生成测试数据,放入网站根目录文件中:
![-w467](images/16000719723284.jpg) ![-w467](images/16000719723284.jpg)
@@ -56,15 +56,15 @@ HaE支持三个动作
有些正则在实战应用场景中并不理想 有些正则在实战应用场景中并不理想
在正则匹配手机号、身份证号码的时候(纯数字类)会存在一些误报(这里匹配身份证号码无法进行校验,误报率很高),但手机号处理这一块可以解决 在正则匹配手机号、身份证号码的时候(纯数字类)会存在一些误报(这里匹配身份证号码无法进行校验,误报率很高),但手机号处理这一块可以解决:
原正则 原正则:
``` ```
1[3-9]\d{9} 1[3-9]\d{9}
``` ```
误报场景`12315188888888123`,这时候会匹配到`15188888888`,而实际上这一段并不是手机号,所以修改正则为 误报场景: `12315188888888123`,这时候会匹配到`15188888888`,而实际上这一段并不是手机号,所以修改正则为:
``` ```
[^0-9]+(1[3-9]\d{9})[^0-9]+ [^0-9]+(1[3-9]\d{9})[^0-9]+
@@ -74,30 +74,35 @@ HaE支持三个动作
## 实战用法 ## 实战用法
1. CMS指纹识别Discuz正则`(Powered by Discuz!)` 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)` 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})` 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 4. 实战插件关联搭配,漏洞挖掘案例: https://mp.weixin.qq.com/s/5vNn7dMRZBtv0ojPBAHV7Q
...还有诸多使用方法等待大家去发掘。 ...还有诸多使用方法等待大家去发掘。
## 文末 ## 文末
随笔正义感是一个不可丢失的东西。 随笔: 正义感是一个不可丢失的东西。
Github项目地址BUG、需求、正则欢迎提交https://github.com/gh0stkey/HaE Github项目地址BUG、需求、正则欢迎提交: https://github.com/gh0stkey/HaE
### 收录正则列表 ### 收录正则列表
身份证号码来自https://github.com/gh0stkey/HaE/issues/3 身份证号码(来自: https://github.com/gh0stkey/HaE/issues/3):
``` ```
[^0-9]([1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx])|([1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{2}[0-9Xx])[^0-9] [^0-9]([1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx])|([1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{2}[0-9Xx])[^0-9]
``` ```
邮箱地址 邮箱地址:
``` ```
([\w-]+(?:\.[\w-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?) ([\w-]+(?:\.[\w-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?)
``` ```
Elasticsearch未授权访问匹配(来自: https://github.com/gh0stkey/HaE/issues/7):
```
("cluster_uuid"\s*:\s*"[A-Za-z0-9_-]{22}")
```

View File

@@ -38,6 +38,7 @@ import javax.swing.SwingUtilities;
import javax.swing.JLabel; import javax.swing.JLabel;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
public class BurpExtender implements IBurpExtender, IHttpListener, IMessageEditorTabFactory, ITab { public class BurpExtender implements IBurpExtender, IHttpListener, IMessageEditorTabFactory, ITab {
@@ -48,9 +49,11 @@ public class BurpExtender implements IBurpExtender, IHttpListener, IMessageEdito
private IBurpExtenderCallbacks callbacks; private IBurpExtenderCallbacks callbacks;
private static String configFilePath = "config.json"; private static String configFilePath = "config.json";
private static String initFilePath = "init.hae"; private static String initFilePath = "init.hae";
private static String initConfigContent = "{\"Email\":{\"loaded\":true,\"highlight\":true,\"regex\":\"([\\\\w-]+(?:\\\\.[\\\\w-]+)*@(?:[\\\\w](?:[\\\\w-]*[\\\\w])?\\\\.)+[\\\\w](?:[\\\\w-]*[\\\\w])?)\",\"extract\":true,\"color\":\"yellow\"}}"; private static String initConfigContent = "{\"Email\":{\"loaded\":true,\"scope\":\"response\",\"regex\":\"([\\\\w-]+(?:\\\\.[\\\\w-]+)*@(?:[\\\\w](?:[\\\\w-]*[\\\\w])?\\\\.)+[\\\\w](?:[\\\\w-]*[\\\\w])?)\",\"action\":\"any\",\"color\":\"yellow\"}}";
private static String endColor = ""; private static String endColor = "";
private static String[] colorArray = new String[] {"red", "orange", "yellow", "green", "cyan", "blue", "pink", "magenta", "gray"}; private static String[] colorArray = new String[] {"red", "orange", "yellow", "green", "cyan", "blue", "pink", "magenta", "gray"};
private static String[] scopeArray = new String[] {"any", "response", "request"};
private static String[] actionArray = new String[] {"any", "extract", "highight"};
private static IMessageEditorTab HaETab; private static IMessageEditorTab HaETab;
private static PrintWriter stdout; private static PrintWriter stdout;
@@ -58,8 +61,10 @@ public class BurpExtender implements IBurpExtender, IHttpListener, IMessageEdito
public void registerExtenderCallbacks(final IBurpExtenderCallbacks callbacks) public void registerExtenderCallbacks(final IBurpExtenderCallbacks callbacks)
{ {
this.callbacks = callbacks; this.callbacks = callbacks;
// 设置插件名字 // 设置插件名字和版本
callbacks.setExtensionName("HaE - Highlighter and Extractor"); String version = "1.4.1";
callbacks.setExtensionName(String.format("HaE (%s) - Highlighter and Extractor", version));
// 定义输出 // 定义输出
stdout = new PrintWriter(callbacks.getStdout(), true); stdout = new PrintWriter(callbacks.getStdout(), true);
@@ -137,7 +142,7 @@ public class BurpExtender implements IBurpExtender, IHttpListener, IMessageEdito
panel_2.add(panel_1, BorderLayout.NORTH); panel_2.add(panel_1, BorderLayout.NORTH);
panel_1.setBorder(new TitledBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null), "Actions", TitledBorder.LEADING, TitledBorder.TOP, null, new Color(0, 0, 0))); panel_1.setBorder(new TitledBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null), "Actions", TitledBorder.LEADING, TitledBorder.TOP, null, new Color(0, 0, 0)));
JButton btnReloadRule = new JButton("Reload Rule"); JButton btnReloadRule = new JButton("Reload");
btnReloadRule.addActionListener(new ActionListener() { btnReloadRule.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
fillTable(); fillTable();
@@ -145,7 +150,7 @@ public class BurpExtender implements IBurpExtender, IHttpListener, IMessageEdito
}); });
panel_1.add(btnReloadRule); panel_1.add(btnReloadRule);
JButton btnNewRule = new JButton("New Rule"); JButton btnNewRule = new JButton("New");
btnNewRule.addActionListener(new ActionListener() { btnNewRule.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) { public void actionPerformed(ActionEvent arg0) {
DefaultTableModel dtm = (DefaultTableModel) table.getModel(); DefaultTableModel dtm = (DefaultTableModel) table.getModel();
@@ -154,14 +159,14 @@ public class BurpExtender implements IBurpExtender, IHttpListener, IMessageEdito
rules.add("New Rule"); rules.add("New Rule");
rules.add("New Regex"); rules.add("New Regex");
rules.add("red"); rules.add("red");
rules.add(true); rules.add("response");
rules.add(true); rules.add("any");
dtm.addRow(rules); dtm.addRow(rules);
} }
}); });
panel_1.add(btnNewRule); panel_1.add(btnNewRule);
JButton btnDeleteRule = new JButton("Delete Rule"); JButton btnDeleteRule = new JButton("Delete");
btnDeleteRule.addActionListener(new ActionListener() { btnDeleteRule.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
int selectRows = table.getSelectedRows().length; int selectRows = table.getSelectedRows().length;
@@ -188,7 +193,7 @@ public class BurpExtender implements IBurpExtender, IHttpListener, IMessageEdito
new Object[][] { new Object[][] {
}, },
new String[] { new String[] {
"Loaded", "Name", "Regex", "Color", "isExtract", "isHighlight" "Loaded", "Name", "Regex", "Color", "Scope", "Action"
} }
)); ));
scrollPane.setViewportView(table); scrollPane.setViewportView(table);
@@ -196,8 +201,8 @@ public class BurpExtender implements IBurpExtender, IHttpListener, IMessageEdito
table.getColumnModel().getColumn(2).setPreferredWidth(172); table.getColumnModel().getColumn(2).setPreferredWidth(172);
table.getColumnModel().getColumn(3).setCellEditor(new DefaultCellEditor(new JComboBox(colorArray))); table.getColumnModel().getColumn(3).setCellEditor(new DefaultCellEditor(new JComboBox(colorArray)));
table.getColumnModel().getColumn(0).setCellEditor(new DefaultCellEditor(new JCheckBox())); table.getColumnModel().getColumn(0).setCellEditor(new DefaultCellEditor(new JCheckBox()));
table.getColumnModel().getColumn(4).setCellEditor(new DefaultCellEditor(new JCheckBox())); table.getColumnModel().getColumn(4).setCellEditor(new DefaultCellEditor(new JComboBox(scopeArray)));
table.getColumnModel().getColumn(5).setCellEditor(new DefaultCellEditor(new JCheckBox())); table.getColumnModel().getColumn(5).setCellEditor(new DefaultCellEditor(new JComboBox(actionArray)));
JLabel lblNewLabel = new JLabel("@EvilChen Love YuChen."); JLabel lblNewLabel = new JLabel("@EvilChen Love YuChen.");
lblNewLabel.setHorizontalAlignment(SwingConstants.CENTER); lblNewLabel.setHorizontalAlignment(SwingConstants.CENTER);
@@ -217,8 +222,8 @@ public class BurpExtender implements IBurpExtender, IHttpListener, IMessageEdito
jsonObj1.put("loaded", (boolean) dtm.getValueAt(i, 0)); jsonObj1.put("loaded", (boolean) dtm.getValueAt(i, 0));
jsonObj1.put("regex", (String) dtm.getValueAt(i, 2)); jsonObj1.put("regex", (String) dtm.getValueAt(i, 2));
jsonObj1.put("color", (String) dtm.getValueAt(i, 3)); jsonObj1.put("color", (String) dtm.getValueAt(i, 3));
jsonObj1.put("extract", (boolean) dtm.getValueAt(i, 4)); jsonObj1.put("scope", (String) dtm.getValueAt(i, 4));
jsonObj1.put("highlight", (boolean) dtm.getValueAt(i, 5)); jsonObj1.put("action", (String) dtm.getValueAt(i, 5));
// 添加数据 // 添加数据
jsonObj.put((String) dtm.getValueAt(i, 1), jsonObj1); jsonObj.put((String) dtm.getValueAt(i, 1), jsonObj1);
} }
@@ -261,28 +266,34 @@ public class BurpExtender implements IBurpExtender, IHttpListener, IMessageEdito
@Override @Override
public void processHttpMessage(int toolFlag, boolean messageIsRequest, IHttpRequestResponse messageInfo) { public void processHttpMessage(int toolFlag, boolean messageIsRequest, IHttpRequestResponse messageInfo) {
// 判断是否是响应且该代码作用域为REPEATER、INTRUDER、PROXY分别对应toolFlag 64、32、4 // 判断是否是响应且该代码作用域为REPEATER、INTRUDER、PROXY分别对应toolFlag 64、32、4
if (!messageIsRequest && (toolFlag == 64 || toolFlag == 32 || toolFlag == 4)) { if (toolFlag == 64 || toolFlag == 32 || toolFlag == 4) {
byte[] content = messageInfo.getResponse(); JSONObject jsonObj = new JSONObject();
JSONObject jsonObj = matchRegex(content); if (messageIsRequest) {
if (jsonObj.length() > 0) { byte[] content = messageInfo.getRequest();
List<String> colorList = new ArrayList<String>(); try {
Iterator<String> k = jsonObj.keys(); String c = new String(content, "UTF-8").intern();
while (k.hasNext()) { } catch (UnsupportedEncodingException e) {
String name = k.next(); e.printStackTrace();
JSONObject jsonObj2 = new JSONObject(jsonObj.get(name).toString()); }
boolean isHighlight = jsonObj2.getBoolean("highlight"); jsonObj = matchRegex(content, "request", "highlight");
boolean isLoaded = jsonObj2.getBoolean("loaded"); } else {
if (isHighlight && isLoaded) { byte[] content = messageInfo.getResponse();
colorList.add(jsonObj2.getString("color")); try {
} String c = new String(content, "UTF-8").intern();
} } catch (UnsupportedEncodingException e) {
if (colorList.size() != 0) { e.printStackTrace();
colorUpgrade(getColorKeys(colorList)); }
String color = endColor; jsonObj = matchRegex(content, "response", "highlight");
messageInfo.setHighlight(color); }
}
List<String> colorList = highlightList(jsonObj);
if (colorList.size() != 0) {
colorUpgrade(getColorKeys(colorList));
String color = endColor;
messageInfo.setHighlight(color);
} }
} }
} }
class MarkInfoTab implements IMessageEditorTab { class MarkInfoTab implements IMessageEditorTab {
@@ -306,8 +317,9 @@ public class BurpExtender implements IBurpExtender, IHttpListener, IMessageEdito
@Override @Override
public boolean isEnabled(byte[] content, boolean isRequest) { public boolean isEnabled(byte[] content, boolean isRequest) {
// 这里需要过一次正则匹配决定是否开启Tab if (isRequest && matchRegex(content, "request", "extract").length() != 0) {
if (!isRequest && matchRegex(content).length() != 0) { return true;
} else if (!isRequest && matchRegex(content, "response", "extract").length() != 0) {
return true; return true;
} }
return false; return false;
@@ -333,29 +345,54 @@ public class BurpExtender implements IBurpExtender, IHttpListener, IMessageEdito
*/ */
@Override @Override
public void setMessage(byte[] content, boolean isRequest) { public void setMessage(byte[] content, boolean isRequest) {
if (content.length > 0 && !isRequest) { try {
String result = ""; String c = new String(content, "UTF-8").intern();
JSONObject jsonObj = matchRegex(content); } catch (UnsupportedEncodingException e) {
if (jsonObj.length() != 0) { e.printStackTrace();
Iterator<String> k = jsonObj.keys(); }
while (k.hasNext()) { if (content.length > 0) {
String name = k.next(); if (isRequest) {
JSONObject jsonObj1 = new JSONObject(jsonObj.get(name).toString()); JSONObject jsonObj = matchRegex(content, "request", "extract");
boolean isExtract = jsonObj1.getBoolean("extract"); if (jsonObj.length() != 0) {
boolean isLoaded = jsonObj1.getBoolean("loaded"); String result = extractString(jsonObj);
if (isExtract && isLoaded) { markInfoText.setText(result.getBytes());
String tmpStr = String.format("[%s] %s \n", name, jsonObj1.getString("data")).intern(); }
result += tmpStr; } else {
} JSONObject jsonObj = matchRegex(content, "response", "extract");
if (jsonObj.length() != 0) {
String result = extractString(jsonObj);
markInfoText.setText(result.getBytes());
} }
} }
markInfoText.setText(result.getBytes());
} }
currentMessage = content; currentMessage = content;
} }
} }
private JSONObject matchRegex(byte[] content) { private String extractString(JSONObject jsonObj) {
String result = "";
Iterator<String> k = jsonObj.keys();
while (k.hasNext()) {
String name = k.next();
JSONObject jsonObj1 = new JSONObject(jsonObj.get(name).toString());
String tmpStr = String.format("[%s]\n%s\n\n", name, jsonObj1.getString("data")).intern();
result += tmpStr;
}
return result;
}
private List<String> highlightList(JSONObject jsonObj) {
List<String> colorList = new ArrayList<String>();
Iterator<String> k = jsonObj.keys();
while (k.hasNext()) {
String name = k.next();
JSONObject jsonObj2 = new JSONObject(jsonObj.get(name).toString());
colorList.add(jsonObj2.getString("color"));
}
return colorList;
}
private JSONObject matchRegex(byte[] content, String scopeString, String actionString) {
JSONObject tabContent = new JSONObject(); JSONObject tabContent = new JSONObject();
// 正则匹配提取内容 // 正则匹配提取内容
try { try {
@@ -369,33 +406,34 @@ public class BurpExtender implements IBurpExtender, IHttpListener, IMessageEdito
JSONObject jsonObj1 = new JSONObject(jsonObj.get(name).toString()); JSONObject jsonObj1 = new JSONObject(jsonObj.get(name).toString());
JSONObject jsonData = new JSONObject(); JSONObject jsonData = new JSONObject();
String regex = jsonObj1.getString("regex"); String regex = jsonObj1.getString("regex");
boolean isHighligth = jsonObj1.getBoolean("highlight");
boolean isExtract = jsonObj1.getBoolean("extract");
boolean isLoaded = jsonObj1.getBoolean("loaded"); boolean isLoaded = jsonObj1.getBoolean("loaded");
String scope = jsonObj1.getString("scope");
String action = jsonObj1.getString("action");
String color = jsonObj1.getString("color"); String color = jsonObj1.getString("color");
List<String> result = new ArrayList<String>(); List<String> result = new ArrayList<String>();
Pattern pattern = Pattern.compile(regex); if(isLoaded && (scope.equals(scopeString) || scope.equals("any")) && (action.equals(actionString) || action.equals("any"))) {
Matcher matcher = pattern.matcher(contentString); Pattern pattern = Pattern.compile(regex);
while (matcher.find()) { Matcher matcher = pattern.matcher(contentString);
// 添加匹配数据至list while (matcher.find()) {
// 强制用户使用()包裹正则 // 添加匹配数据至list
result.add(matcher.group(1)); // 强制用户使用()包裹正则
} result.add(matcher.group(1));
// 去除重复内容 }
HashSet tmpList = new HashSet(result); // 去除重复内容
result.clear(); HashSet tmpList = new HashSet(result);
result.addAll(tmpList); result.clear();
result.addAll(tmpList);
if (!result.isEmpty()) {
jsonData.put("highlight", isHighligth); if (!result.isEmpty()) {
jsonData.put("extract", isExtract); jsonData.put("color", color);
jsonData.put("color", color); jsonData.put("data", String.join("\n", result));
jsonData.put("data", String.join(",", result)); jsonData.put("loaded", isLoaded);
jsonData.put("loaded", isLoaded); // 初始化格式
// 初始化格式 tabContent.put(name, jsonData);
tabContent.put(name, jsonData); }
} }
} }
return tabContent; return tabContent;
} catch (Exception e) { } catch (Exception e) {
@@ -540,16 +578,16 @@ public class BurpExtender implements IBurpExtender, IHttpListener, IMessageEdito
boolean loaded = jsonObj1.getBoolean("loaded"); boolean loaded = jsonObj1.getBoolean("loaded");
String regex = jsonObj1.getString("regex"); String regex = jsonObj1.getString("regex");
String color = jsonObj1.getString("color"); String color = jsonObj1.getString("color");
boolean isExtract = jsonObj1.getBoolean("extract"); String scope = jsonObj1.getString("scope");
boolean isHighlight = jsonObj1.getBoolean("highlight"); String action = jsonObj1.getString("action");
// 填充数据 // 填充数据
Vector rules = new Vector(); Vector rules = new Vector();
rules.add(loaded); rules.add(loaded);
rules.add(name); rules.add(name);
rules.add(regex); rules.add(regex);
rules.add(color); rules.add(color);
rules.add(isExtract); rules.add(scope);
rules.add(isHighlight); rules.add(action);
dtm.addRow(rules); dtm.addRow(rules);
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 214 KiB

After

Width:  |  Height:  |  Size: 698 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 131 KiB

After

Width:  |  Height:  |  Size: 223 KiB