From e556abb6f7654d088dfc440a8637e703b6c49a8d Mon Sep 17 00:00:00 2001 From: gh0stkey <24655118+gh0stkey@users.noreply.github.com> Date: Sat, 16 Nov 2024 18:06:49 +0800 Subject: [PATCH] Version: 3.4 Update --- src/main/java/hae/Config.java | 2 + src/main/java/hae/HaE.java | 6 +- src/main/java/hae/component/Config.java | 138 ++++- src/main/java/hae/component/Main.java | 2 +- ...ler.java => HttpMessageActiveHandler.java} | 10 +- .../http/HttpMessagePassiveHandler.java | 97 +++ src/main/java/hae/utils/ConfigLoader.java | 8 + src/main/java/hae/utils/UIEnhancer.java | 26 +- src/main/resources/rules/Rules.yml | 575 +++++++++--------- 9 files changed, 536 insertions(+), 328 deletions(-) rename src/main/java/hae/instances/http/{HttpMessageHandler.java => HttpMessageActiveHandler.java} (94%) create mode 100644 src/main/java/hae/instances/http/HttpMessagePassiveHandler.java diff --git a/src/main/java/hae/Config.java b/src/main/java/hae/Config.java index 2e73e39..3411bac 100644 --- a/src/main/java/hae/Config.java +++ b/src/main/java/hae/Config.java @@ -32,6 +32,8 @@ public class Config { public static String scopeOptions = "Suite|Target|Proxy|Scanner|Intruder|Repeater|Logger|Sequencer|Decoder|Comparer|Extensions|Organizer|Recorded login replayer"; + public static String modeStatus = "true"; + public static String[] ruleFields = { "Loaded", "Name", "F-Regex", "S-Regex", "Format", "Color", "Scope", "Engine", "Sensitive" }; diff --git a/src/main/java/hae/HaE.java b/src/main/java/hae/HaE.java index afd711b..31a85ec 100644 --- a/src/main/java/hae/HaE.java +++ b/src/main/java/hae/HaE.java @@ -10,7 +10,6 @@ import hae.component.board.message.MessageTableModel; import hae.instances.editor.RequestEditor; import hae.instances.editor.ResponseEditor; import hae.instances.editor.WebSocketEditor; -import hae.instances.http.HttpMessageHandler; import hae.instances.websocket.WebSocketMessageHandler; import hae.utils.ConfigLoader; @@ -18,7 +17,7 @@ public class HaE implements BurpExtension { @Override public void initialize(MontoyaApi api) { // 设置扩展名称 - String version = "3.3.4"; + String version = "3.4"; api.extension().setName(String.format("HaE (%s) - Highlighter and Extractor", version)); // 加载扩展后输出的项目信息 @@ -35,9 +34,6 @@ public class HaE implements BurpExtension { // 注册Tab页(用于查询数据) api.userInterface().registerSuiteTab("HaE", new Main(api, configLoader, messageTableModel)); - // 注册HTTP处理器 - api.http().registerHttpHandler(new HttpMessageHandler(api, configLoader, messageTableModel)); - // 注册WebSocket处理器 api.proxy().registerWebSocketCreationHandler(proxyWebSocketCreation -> proxyWebSocketCreation.proxyWebSocket().registerProxyMessageHandler(new WebSocketMessageHandler(api))); diff --git a/src/main/java/hae/component/Config.java b/src/main/java/hae/component/Config.java index 983239c..0266236 100644 --- a/src/main/java/hae/component/Config.java +++ b/src/main/java/hae/component/Config.java @@ -1,7 +1,11 @@ package hae.component; import burp.api.montoya.MontoyaApi; +import burp.api.montoya.core.Registration; +import hae.component.board.message.MessageTableModel; import hae.component.rule.Rules; +import hae.instances.http.HttpMessageActiveHandler; +import hae.instances.http.HttpMessagePassiveHandler; import hae.utils.ConfigLoader; import hae.utils.UIEnhancer; @@ -16,24 +20,29 @@ import javax.swing.table.DefaultTableModel; import java.awt.*; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.DataFlavor; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; +import java.awt.event.*; import java.util.List; import java.util.*; public class Config extends JPanel { private final MontoyaApi api; private final ConfigLoader configLoader; + private final MessageTableModel messageTableModel; private final Rules rules; private final String defaultText = "Enter a new item"; - public Config(MontoyaApi api, ConfigLoader configLoader, Rules rules) { + private Registration activeHandler; + private Registration passiveHandler; + + public Config(MontoyaApi api, ConfigLoader configLoader, MessageTableModel messageTableModel, Rules rules) { this.api = api; this.configLoader = configLoader; + this.messageTableModel = messageTableModel; this.rules = rules; + this.activeHandler = api.http().registerHttpHandler(new HttpMessageActiveHandler(api, configLoader, messageTableModel)); + this.passiveHandler = api.scanner().registerScanCheck(new HttpMessagePassiveHandler(api, configLoader, messageTableModel)); + initComponents(); } @@ -66,12 +75,35 @@ public class Config extends JPanel { constraints.gridx = 1; JTabbedPane configTabbedPanel = new JTabbedPane(); - String[] settingMode = new String[]{"Exclude suffix", "Block host", "Exclude status", "Limit size (MB)"}; + String[] settingMode = new String[]{"Exclude suffix", "Block host", "Exclude status"}; JPanel settingPanel = createConfigTablePanel(settingMode, "Setting"); + + JPanel northPanel = new JPanel(new BorderLayout()); + + JPanel modePanel = getModePanel(); + JScrollPane modeScrollPane = new JScrollPane(modePanel); + modeScrollPane.setBorder(new TitledBorder("Mode")); + + JTextField limitPanel = getLimitPanel(); + JScrollPane limitScrollPane = new JScrollPane(limitPanel); + limitScrollPane.setBorder(new TitledBorder("Limit Size (MB)")); + + JSplitPane northTopPanel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, modeScrollPane, limitScrollPane); + northTopPanel.addComponentListener(new ComponentAdapter() { + @Override + public void componentResized(ComponentEvent e) { + northTopPanel.setDividerLocation(0.5); + } + }); + JPanel scopePanel = getScopePanel(); JScrollPane scopeScrollPane = new JScrollPane(scopePanel); scopeScrollPane.setBorder(new TitledBorder("Scope")); - settingPanel.add(scopeScrollPane, BorderLayout.NORTH); + + northPanel.add(scopeScrollPane, BorderLayout.SOUTH); + northPanel.add(northTopPanel, BorderLayout.NORTH); + settingPanel.add(northPanel, BorderLayout.NORTH); + configTabbedPanel.add("Setting", settingPanel); String[] aiMode = new String[]{"Alibaba", "Moonshot"}; @@ -112,23 +144,67 @@ public class Config extends JPanel { private JPanel getScopePanel() { JPanel scopePanel = new JPanel(); scopePanel.setLayout(new BoxLayout(scopePanel, BoxLayout.X_AXIS)); + scopePanel.setBorder(new EmptyBorder(3, 0, 6, 0)); String[] scopeInit = hae.Config.scopeOptions.split("\\|"); String[] scopeMode = configLoader.getScope().split("\\|"); for (String scope : scopeInit) { JCheckBox checkBox = new JCheckBox(scope); scopePanel.add(checkBox); + checkBox.addActionListener(e -> updateScope(checkBox)); for (String mode : scopeMode) { if (scope.equals(mode)) { checkBox.setSelected(true); } } - - checkBox.addActionListener(e -> updateScope(checkBox)); + updateScope(checkBox); } + return scopePanel; } + private JPanel getModePanel() { + JPanel modePanel = new JPanel(); + modePanel.setLayout(new BoxLayout(modePanel, BoxLayout.X_AXIS)); + + JCheckBox checkBox = new JCheckBox("Enable active http message handler"); + modePanel.add(checkBox); + checkBox.addActionListener(e -> updateModeStatus(checkBox)); + checkBox.setSelected(configLoader.getMode()); + updateModeStatus(checkBox); + + return modePanel; + } + + private JTextField getLimitPanel() { + JTextField limitSizeTextField = new JTextField(); + limitSizeTextField.getDocument().addDocumentListener(new DocumentListener() { + @Override + public void insertUpdate(DocumentEvent e) { + onTextChange(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + onTextChange(); + } + + @Override + public void changedUpdate(DocumentEvent e) { + onTextChange(); + } + + private void onTextChange() { + String limitSizeText = limitSizeTextField.getText(); + configLoader.setLimitSize(limitSizeText); + } + }); + + limitSizeTextField.setText(configLoader.getLimitSize()); + + return limitSizeTextField; + } + private TableModelListener craeteSettingTableModelListener(JComboBox setTypeComboBox, DefaultTableModel model) { return new TableModelListener() { @Override @@ -154,12 +230,6 @@ public class Config extends JPanel { } } - if (selected.contains("Limit size")) { - if (!values.equals(configLoader.getExcludeStatus()) && !values.isEmpty()) { - String[] limit = values.split("\\|"); - configLoader.setLimitSize(limit[limit.length - 1]); - } - } } }; } @@ -182,10 +252,6 @@ public class Config extends JPanel { if (selected.equals("Exclude status")) { addDataToTable(configLoader.getExcludeStatus().replaceAll("\\|", "\r\n"), model); } - - if (selected.contains("Limit size")) { - addDataToTable(configLoader.getLimitSize(), model); - } } }; } @@ -261,12 +327,12 @@ public class Config extends JPanel { JComboBox setTypeComboBox = new JComboBox<>(); setTypeComboBox.setModel(new DefaultComboBoxModel<>(mode)); + model.addTableModelListener(type.equals("AI+") ? craeteAITableModelListener(setTypeComboBox, model) : craeteSettingTableModelListener(setTypeComboBox, model)); + setTypeComboBox.addActionListener(type.equals("AI+") ? createAIActionListener(setTypeComboBox, model) : createSettingActionListener(setTypeComboBox, model)); setTypeComboBox.setSelectedItem(mode[0]); - model.addTableModelListener(type.equals("AI+") ? craeteAITableModelListener(setTypeComboBox, model) : craeteSettingTableModelListener(setTypeComboBox, model)); - constraints.insets = new Insets(0, 0, 3, 0); constraints.gridy = 0; buttonPanel.add(setTypeComboBox, constraints); @@ -305,9 +371,6 @@ public class Config extends JPanel { Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); try { String data = (String) clipboard.getData(DataFlavor.stringFlavor); - if (setTypeComboBox.getSelectedItem().toString().contains("Limit size")) { - model.setRowCount(0); - } if (data != null && !data.isEmpty()) { addDataToTable(data, model); } @@ -324,7 +387,6 @@ public class Config extends JPanel { clearButton.addActionListener(e -> model.setRowCount(0)); - JPanel settingMainPanel = new JPanel(new BorderLayout()); settingMainPanel.setBorder(new EmptyBorder(5, 15, 10, 15)); JScrollPane settingScroller = new JScrollPane(settingPanel); @@ -383,6 +445,29 @@ public class Config extends JPanel { } } + public void updateModeStatus(JCheckBox checkBox) { + boolean selected = checkBox.isSelected(); + configLoader.setMode(selected ? "true" : "false"); + + if (checkBox.isSelected()) { + if (passiveHandler.isRegistered()) { + passiveHandler.deregister(); + } + + if (!activeHandler.isRegistered()) { + activeHandler = api.http().registerHttpHandler(new HttpMessageActiveHandler(api, configLoader, messageTableModel)); + } + } else { + if (!passiveHandler.isRegistered()) { + passiveHandler = api.scanner().registerScanCheck(new HttpMessagePassiveHandler(api, configLoader, messageTableModel)); + } + + if (activeHandler.isRegistered()) { + activeHandler.deregister(); + } + } + } + public void updateScope(JCheckBox checkBox) { String boxText = checkBox.getText(); boolean selected = checkBox.isSelected(); @@ -401,9 +486,6 @@ public class Config extends JPanel { private void addActionPerformed(ActionEvent e, DefaultTableModel model, JTextField addTextField, String comboBoxSelected) { String addTextFieldText = addTextField.getText(); if (addTextField.getForeground().equals(Color.BLACK)) { - if (comboBoxSelected.contains("Limit size")) { - model.setRowCount(0); - } addDataToTable(addTextFieldText, model); addTextField.setText(""); addTextField.requestFocusInWindow(); diff --git a/src/main/java/hae/component/Main.java b/src/main/java/hae/component/Main.java index d558008..307ac93 100644 --- a/src/main/java/hae/component/Main.java +++ b/src/main/java/hae/component/Main.java @@ -57,7 +57,7 @@ public class Main extends JPanel { Rules rules = new Rules(api, configLoader); mainTabbedPane.addTab("Rules", rules); mainTabbedPane.addTab("Databoard", new Databoard(api, configLoader, messageTableModel)); - mainTabbedPane.addTab("Config", new Config(api, configLoader, rules)); + mainTabbedPane.addTab("Config", new Config(api, configLoader, messageTableModel, rules)); } private boolean isDarkBg(JTabbedPane HaETabbedPane) { diff --git a/src/main/java/hae/instances/http/HttpMessageHandler.java b/src/main/java/hae/instances/http/HttpMessageActiveHandler.java similarity index 94% rename from src/main/java/hae/instances/http/HttpMessageHandler.java rename to src/main/java/hae/instances/http/HttpMessageActiveHandler.java index 0fbe48d..df3d323 100644 --- a/src/main/java/hae/instances/http/HttpMessageHandler.java +++ b/src/main/java/hae/instances/http/HttpMessageActiveHandler.java @@ -17,7 +17,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -public class HttpMessageHandler implements HttpHandler { +public class HttpMessageActiveHandler implements HttpHandler { private final MontoyaApi api; private final ConfigLoader configLoader; private final HttpUtils httpUtils; @@ -30,7 +30,7 @@ public class HttpMessageHandler implements HttpHandler { private final ThreadLocal> colorList = ThreadLocal.withInitial(ArrayList::new); private final ThreadLocal> commentList = ThreadLocal.withInitial(ArrayList::new); - public HttpMessageHandler(MontoyaApi api, ConfigLoader configLoader, MessageTableModel messageTableModel) { + public HttpMessageActiveHandler(MontoyaApi api, ConfigLoader configLoader, MessageTableModel messageTableModel) { this.api = api; this.configLoader = configLoader; this.httpUtils = new HttpUtils(api, configLoader); @@ -68,21 +68,19 @@ public class HttpMessageHandler implements HttpHandler { setColorAndCommentList(messageProcessor.processRequest(host.get(), request, true)); setColorAndCommentList(messageProcessor.processResponse(host.get(), httpResponseReceived, true)); - // 设置高亮颜色和注释 if (!colorList.get().isEmpty() && !commentList.get().isEmpty()) { + HttpRequestResponse httpRequestResponse = HttpRequestResponse.httpRequestResponse(request, httpResponseReceived); + String color = messageProcessor.retrieveFinalColor(messageProcessor.retrieveColorIndices(colorList.get())); annotations.setHighlightColor(HighlightColor.highlightColor(color)); String comment = StringProcessor.mergeComment(String.join(", ", commentList.get())); annotations.setNotes(comment); - HttpRequestResponse httpRequestResponse = HttpRequestResponse.httpRequestResponse(request, httpResponseReceived); - String method = request.method(); String url = request.url(); String status = String.valueOf(httpResponseReceived.statusCode()); String length = String.valueOf(httpResponseReceived.toByteArray().length()); - // 后台提交,防止线程阻塞 new SwingWorker() { @Override protected Void doInBackground() { diff --git a/src/main/java/hae/instances/http/HttpMessagePassiveHandler.java b/src/main/java/hae/instances/http/HttpMessagePassiveHandler.java new file mode 100644 index 0000000..2c0cc85 --- /dev/null +++ b/src/main/java/hae/instances/http/HttpMessagePassiveHandler.java @@ -0,0 +1,97 @@ +package hae.instances.http; + +import burp.api.montoya.MontoyaApi; +import burp.api.montoya.http.message.HttpRequestResponse; +import burp.api.montoya.http.message.requests.HttpRequest; +import burp.api.montoya.http.message.responses.HttpResponse; +import burp.api.montoya.scanner.AuditResult; +import burp.api.montoya.scanner.ConsolidationAction; +import burp.api.montoya.scanner.ScanCheck; +import burp.api.montoya.scanner.audit.insertionpoint.AuditInsertionPoint; +import burp.api.montoya.scanner.audit.issues.AuditIssue; +import hae.component.board.message.MessageTableModel; +import hae.instances.http.utils.MessageProcessor; +import hae.utils.ConfigLoader; +import hae.utils.http.HttpUtils; +import hae.utils.string.StringProcessor; + +import javax.swing.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static burp.api.montoya.scanner.AuditResult.auditResult; +import static burp.api.montoya.scanner.ConsolidationAction.KEEP_BOTH; +import static burp.api.montoya.scanner.ConsolidationAction.KEEP_EXISTING; +import static java.util.Collections.emptyList; + +public class HttpMessagePassiveHandler implements ScanCheck { + private final MontoyaApi api; + private final ConfigLoader configLoader; + private final HttpUtils httpUtils; + private final MessageTableModel messageTableModel; + private final MessageProcessor messageProcessor; + + private final List colorList = new ArrayList<>(); + private final List commentList = new ArrayList<>(); + + public HttpMessagePassiveHandler(MontoyaApi api, ConfigLoader configLoader, MessageTableModel messageTableModel) { + this.api = api; + this.configLoader = configLoader; + this.httpUtils = new HttpUtils(api, configLoader); + this.messageTableModel = messageTableModel; + this.messageProcessor = new MessageProcessor(api); + } + + @Override + public AuditResult activeAudit(HttpRequestResponse httpRequestResponse, AuditInsertionPoint auditInsertionPoint) { + return auditResult(emptyList()); + } + + @Override + public AuditResult passiveAudit(HttpRequestResponse httpRequestResponse) { + HttpRequest request = httpRequestResponse.request(); + HttpResponse response = httpRequestResponse.response(); + + boolean matches = httpUtils.verifyHttpRequestResponse(httpRequestResponse, "Proxy"); + + if (!matches) { + try { + String host = StringProcessor.getHostByUrl(request.url()); + setColorAndCommentList(messageProcessor.processRequest(host, request, true)); + setColorAndCommentList(messageProcessor.processResponse(host, response, true)); + + String url = request.url(); + String method = request.method(); + String status = String.valueOf(response.statusCode()); + String color = messageProcessor.retrieveFinalColor(messageProcessor.retrieveColorIndices(colorList)); + String comment = StringProcessor.mergeComment(String.join(", ", commentList)); + String length = String.valueOf(response.toByteArray().length()); + + new SwingWorker() { + @Override + protected Void doInBackground() { + messageTableModel.add(httpRequestResponse, url, method, status, length, comment, color, "", ""); + return null; + } + }.execute(); + } catch (Exception e) { + api.logging().logToError("passiveAudit: " + e.getMessage()); + } + } + + return auditResult(emptyList()); + } + + private void setColorAndCommentList(List> result) { + if (result != null && !result.isEmpty()) { + colorList.add(result.get(0).get("color")); + commentList.add(result.get(1).get("comment")); + } + } + + @Override + public ConsolidationAction consolidateIssues(AuditIssue newIssue, AuditIssue existingIssue) { + return existingIssue.name().equals(newIssue.name()) ? KEEP_EXISTING : KEEP_BOTH; + } +} diff --git a/src/main/java/hae/utils/ConfigLoader.java b/src/main/java/hae/utils/ConfigLoader.java index d1e9bb8..2435367 100644 --- a/src/main/java/hae/utils/ConfigLoader.java +++ b/src/main/java/hae/utils/ConfigLoader.java @@ -169,6 +169,10 @@ public class ConfigLoader { return getValueFromConfig("HaEScope", Config.scopeOptions); } + public boolean getMode() { + return getValueFromConfig("HaEModeStatus", Config.modeStatus).equals("true"); + } + private String getValueFromConfig(String name, String defaultValue) { File yamlSetting = new File(configFilePath); if (!yamlSetting.exists() || !yamlSetting.isFile()) { @@ -219,6 +223,10 @@ public class ConfigLoader { setValueToConfig("HaEScope", scope); } + public void setMode(String mode) { + setValueToConfig("HaEModeStatus", mode); + } + private void setValueToConfig(String name, String value) { Map currentConfig = loadCurrentConfig(); currentConfig.put(name, value); diff --git a/src/main/java/hae/utils/UIEnhancer.java b/src/main/java/hae/utils/UIEnhancer.java index 332a73e..a97482a 100644 --- a/src/main/java/hae/utils/UIEnhancer.java +++ b/src/main/java/hae/utils/UIEnhancer.java @@ -7,24 +7,40 @@ import java.awt.event.FocusListener; public class UIEnhancer { public static void setTextFieldPlaceholder(JTextField textField, String placeholderText) { - textField.setForeground(Color.GRAY); - textField.setText(placeholderText); + // 使用客户端属性来存储占位符文本和占位符状态 + textField.putClientProperty("placeholderText", placeholderText); + textField.putClientProperty("isPlaceholder", true); + + // 设置占位符文本和颜色 + setPlaceholderText(textField); + textField.addFocusListener(new FocusListener() { @Override public void focusGained(FocusEvent e) { - if (textField.getText().equals(placeholderText)) { + // 当获得焦点且文本是占位符时,清除文本并更改颜色 + if ((boolean) textField.getClientProperty("isPlaceholder")) { textField.setText(""); textField.setForeground(Color.BLACK); + textField.putClientProperty("isPlaceholder", false); } } @Override public void focusLost(FocusEvent e) { + // 当失去焦点且文本为空时,设置占位符文本和颜色 if (textField.getText().isEmpty()) { - textField.setForeground(Color.GRAY); - textField.setText(placeholderText); + setPlaceholderText(textField); } } }); } + + private static void setPlaceholderText(JTextField textField) { + String placeholderText = (String) textField.getClientProperty("placeholderText"); + textField.setForeground(Color.GRAY); + textField.setText(placeholderText); + textField.putClientProperty("isPlaceholder", true); + } + + } diff --git a/src/main/resources/rules/Rules.yml b/src/main/resources/rules/Rules.yml index ba5aa16..ac6edc0 100644 --- a/src/main/resources/rules/Rules.yml +++ b/src/main/resources/rules/Rules.yml @@ -1,284 +1,293 @@ rules: - - group: Fingerprint - rule: - - name: Shiro - loaded: true - f_regex: (=deleteMe|rememberMe=) - s_regex: '' - format: '{0}' - color: green - scope: any header - engine: dfa - sensitive: true - - name: JSON Web Token - loaded: true - f_regex: (eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9._-]{10,}|eyJ[A-Za-z0-9_\/+-]{10,}\.[A-Za-z0-9._\/+-]{10,}) - s_regex: '' - format: '{0}' - color: green - scope: any - engine: nfa - sensitive: true - - name: Swagger UI - loaded: true - f_regex: ((swagger-ui.html)|(\"swagger\":)|(Swagger UI)|(swaggerUi)|(swaggerVersion)) - s_regex: '' - format: '{0}' - color: red - scope: response body - engine: dfa - sensitive: false - - name: Ueditor - loaded: true - f_regex: (ueditor\.(config|all)\.js) - s_regex: '' - format: '{0}' - color: green - scope: response body - engine: dfa - sensitive: false - - name: Druid - loaded: true - f_regex: (Druid Stat Index) - s_regex: '' - format: '{0}' - color: orange - scope: response body - engine: dfa - sensitive: false - - group: Maybe Vulnerability - rule: - - name: Java Deserialization - loaded: true - f_regex: (javax\.faces\.ViewState) - s_regex: '' - format: '{0}' - color: yellow - scope: response body - engine: dfa - sensitive: false - - name: Debug Logic Parameters - loaded: true - f_regex: ((access=)|(adm=)|(admin=)|(alter=)|(cfg=)|(clone=)|(config=)|(create=)|(dbg=)|(debug=)|(delete=)|(disable=)|(edit=)|(enable=)|(exec=)|(execute=)|(grant=)|(load=)|(make=)|(modify=)|(rename=)|(reset=)|(root=)|(shell=)|(test=)|(toggl=)) - s_regex: '' - format: '{0}' - color: cyan - scope: request - engine: dfa - sensitive: false - - name: URL As A Value - loaded: true - f_regex: (=(https?)(://|%3a%2f%2f)) - s_regex: '' - format: '{0}' - color: cyan - scope: any - engine: nfa - sensitive: false - - name: Upload Form - loaded: true - f_regex: (type\=\"file\") - s_regex: '' - format: '{0}' - color: yellow - scope: response body - engine: dfa - sensitive: false - - name: DoS Paramters - loaded: true - f_regex: ((size=)|(page=)|(num=)|(limit=)|(start=)|(end=)|(count=)) - s_regex: '' - format: '{0}' - color: cyan - scope: request - engine: dfa - sensitive: false - - group: Basic Information - rule: - - name: Email - loaded: true - f_regex: (([a-z0-9]+[_|\.])*[a-z0-9]+@([a-z0-9]+[-|_|\.])*[a-z0-9]+\.((?!js|css|jpg|jpeg|png|ico)[a-z]{2,5})) - s_regex: '' - format: '{0}' - color: yellow - scope: response - engine: nfa - sensitive: false - - name: Chinese IDCard - loaded: true - f_regex: '[^0-9]((\d{8}(0\d|10|11|12)([0-2]\d|30|31)\d{3}$)|(\d{6}(18|19|20)\d{2}(0[1-9]|10|11|12)([0-2]\d|30|31)\d{3}(\d|X|x)))[^0-9]' - s_regex: '' - format: '{0}' - color: orange - scope: response body - engine: nfa - sensitive: true - - name: Chinese Mobile Number - loaded: true - f_regex: '[^\w]((?:(?:\+|00)86)?1(?:(?:3[\d])|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8[\d])|(?:9[189]))\d{8})[^\w]' - s_regex: '' - format: '{0}' - color: orange - scope: response body - engine: nfa - sensitive: false - - name: Internal IP Address - loaded: true - f_regex: '[^0-9]((127\.0\.0\.1)|(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}))' - s_regex: '' - format: '{0}' - color: cyan - scope: response - engine: nfa - sensitive: true - - name: MAC Address - loaded: true - f_regex: (^([a-fA-F0-9]{2}(:[a-fA-F0-9]{2}){5})|[^a-zA-Z0-9]([a-fA-F0-9]{2}(:[a-fA-F0-9]{2}){5})) - s_regex: '' - format: '{0}' - color: green - scope: response - engine: nfa - sensitive: true - - group: Sensitive Information - rule: - - name: Cloud Key - loaded: true - f_regex: (((access)(|-|_)(key)(|-|_)(id|secret))|(LTAI[a-z0-9]{12,20})) - s_regex: '' - format: '{0}' - color: yellow - scope: any - engine: nfa - sensitive: false - - name: Windows File/Dir Path - loaded: true - f_regex: '[^\w]([a-zA-Z]:\\\\?(?:[^<>:/\\|?*]+\\\\?)*)([^<>:/\\|?*]+(?:\.[^<>:/\\|?*]+)?)' - s_regex: '' - format: '{0}' - color: green - scope: response - engine: nfa - sensitive: true - - name: Password Field - loaded: true - f_regex: ((|'|")(|[\w]{1,10})([p](ass|wd|asswd|assword))(|[\w]{1,10})(|'|")(:|=)( - |)('|")(.*?)('|")(|,)) - s_regex: '' - format: '{0}' - color: yellow - scope: response body - engine: nfa - sensitive: false - - name: Username Field - loaded: true - f_regex: ((|'|")(|[\w]{1,10})(([u](ser|name|sername))|(account)|((((create|update)((d|r)|(by|on|at)))|(creator))))(|[\w]{1,10})(|'|")(:|=)( - |)('|")(.*?)('|")(|,)) - s_regex: '' - format: '{0}' - color: green - scope: response body - engine: nfa - sensitive: false - - name: WeCom Key - loaded: true - f_regex: ((corp)(id|secret)) - s_regex: '' - format: '{0}' - color: green - scope: response body - engine: dfa - sensitive: false - - name: JDBC Connection - loaded: true - f_regex: (jdbc:[a-z:]+://[a-z0-9\.\-_:;=/@?,&]+) - s_regex: '' - format: '{0}' - color: yellow - scope: any - engine: nfa - sensitive: false - - name: Authorization Header - loaded: true - f_regex: ((basic [a-z0-9=:_\+\/-]{5,100})|(bearer [a-z0-9_.=:_\+\/-]{5,100})) - s_regex: '' - format: '{0}' - color: yellow - scope: response body - engine: nfa - sensitive: false - - name: Sensitive Field - loaded: true - f_regex: ((\[)?('|")?([\w]{0,10})((key)|(secret)|(token)|(config)|(auth)|(access)|(admin)|(ticket))([\w]{0,10})('|")?(\])?( - |)(:|=)( |)('|")(.*?)('|")(|,)) - s_regex: '' - format: '{0}' - color: yellow - scope: response - engine: nfa - sensitive: false - - group: Other - rule: - - name: Linkfinder - loaded: true - f_regex: (?:"|')(((?:[a-zA-Z]{1,10}://|//)[^"'/]{1,}\.[a-zA-Z]{2,}[^"']{0,})|((?:/|\.\./|\./)[^"'><,;|*()(%%$^/\\\[\]][^"'><,;|()]{1,})|([a-zA-Z0-9_\-/]{1,}/[a-zA-Z0-9_\-/]{1,}\.(?:[a-zA-Z]{1,4}|action)(?:[\?|#][^"|']{0,}|))|([a-zA-Z0-9_\-/]{1,}/[a-zA-Z0-9_\-/]{3,}(?:[\?|#][^"|']{0,}|))|([a-zA-Z0-9_\-]{1,}\.(?:\w)(?:[\?|#][^"|']{0,}|)))(?:"|') - s_regex: '' - format: '{0}' - color: gray - scope: response body - engine: nfa - sensitive: true - - name: Source Map - loaded: true - f_regex: (\.js\.map) - s_regex: '' - format: '{0}' - color: pink - scope: response body - engine: dfa - sensitive: false - - name: Create Script - loaded: true - f_regex: (\{[^{}]*\}\s*\[[^\s]*\]\s*\+\s*"[^\s]*\.js") - s_regex: '"?([\w].*?)"?:"(.*?)"' - format: '{0}.{1}' - color: green - scope: response body - engine: nfa - sensitive: false - - name: URL Schemes - loaded: true - f_regex: ((?![http]|[https])(([-A-Za-z0-9]{1,20})://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|])) - s_regex: '' - format: '{0}' - color: yellow - scope: response body - engine: nfa - sensitive: false - - name: Router Push - loaded: true - f_regex: (\$router\.push) - s_regex: '' - format: '{0}' - color: magenta - scope: response body - engine: dfa - sensitive: false - - name: All URL - loaded: true - f_regex: (https?://[-A-Za-z0-9+&@#/%?=~_|!:,.;\u4E00-\u9FFF]+[-A-Za-z0-9+&@#/%=~_|]) - s_regex: '' - format: '{0}' - color: gray - scope: response body - engine: nfa - sensitive: true - - name: Request URI - loaded: true - f_regex: ' ((?!.*\.js(\?.*)?$)(.*?[^.js$])) ' - s_regex: '' - format: '{0}' - color: gray - scope: request line - engine: nfa - sensitive: false +- group: Fingerprint + rule: + - name: Shiro + loaded: true + f_regex: (=deleteMe|rememberMe=) + s_regex: '' + format: '{0}' + color: green + scope: any header + engine: dfa + sensitive: true + - name: JSON Web Token + loaded: true + f_regex: (eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9._-]{10,}|eyJ[A-Za-z0-9_\/+-]{10,}\.[A-Za-z0-9._\/+-]{10,}) + s_regex: '' + format: '{0}' + color: green + scope: any + engine: nfa + sensitive: true + - name: Swagger UI + loaded: true + f_regex: ((swagger-ui.html)|(\"swagger\":)|(Swagger UI)|(swaggerUi)|(swaggerVersion)) + s_regex: '' + format: '{0}' + color: red + scope: response body + engine: dfa + sensitive: false + - name: Ueditor + loaded: true + f_regex: (ueditor\.(config|all)\.js) + s_regex: '' + format: '{0}' + color: green + scope: response body + engine: dfa + sensitive: false + - name: Druid + loaded: true + f_regex: (Druid Stat Index) + s_regex: '' + format: '{0}' + color: orange + scope: response body + engine: dfa + sensitive: false +- group: Maybe Vulnerability + rule: + - name: Java Deserialization + loaded: true + f_regex: (javax\.faces\.ViewState) + s_regex: '' + format: '{0}' + color: yellow + scope: response body + engine: dfa + sensitive: false + - name: Debug Logic Parameters + loaded: true + f_regex: ((access=)|(adm=)|(admin=)|(alter=)|(cfg=)|(clone=)|(config=)|(create=)|(dbg=)|(debug=)|(delete=)|(disable=)|(edit=)|(enable=)|(exec=)|(execute=)|(grant=)|(load=)|(make=)|(modify=)|(rename=)|(reset=)|(root=)|(shell=)|(test=)|(toggl=)) + s_regex: '' + format: '{0}' + color: cyan + scope: request + engine: dfa + sensitive: false + - name: URL As A Value + loaded: true + f_regex: (=(https?)(://|%3a%2f%2f)) + s_regex: '' + format: '{0}' + color: cyan + scope: any + engine: nfa + sensitive: false + - name: Upload Form + loaded: true + f_regex: (type\=\"file\") + s_regex: '' + format: '{0}' + color: yellow + scope: response body + engine: dfa + sensitive: false + - name: DoS Paramters + loaded: true + f_regex: ((size=)|(page=)|(num=)|(limit=)|(start=)|(end=)|(count=)) + s_regex: '' + format: '{0}' + color: cyan + scope: request + engine: dfa + sensitive: false +- group: Basic Information + rule: + - name: Email + loaded: true + f_regex: (([a-z0-9]+[_|\.])*[a-z0-9]+@([a-z0-9]+[-|_|\.])*[a-z0-9]+\.((?!js|css|jpg|jpeg|png|ico)[a-z]{2,5})) + s_regex: '' + format: '{0}' + color: yellow + scope: response + engine: nfa + sensitive: false + - name: Chinese IDCard + loaded: true + f_regex: '[^0-9]((\d{8}(0\d|10|11|12)([0-2]\d|30|31)\d{3}$)|(\d{6}(18|19|20)\d{2}(0[1-9]|10|11|12)([0-2]\d|30|31)\d{3}(\d|X|x)))[^0-9]' + s_regex: '' + format: '{0}' + color: orange + scope: response body + engine: nfa + sensitive: true + - name: Chinese Mobile Number + loaded: true + f_regex: '[^\w]((?:(?:\+|00)86)?1(?:(?:3[\d])|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8[\d])|(?:9[189]))\d{8})[^\w]' + s_regex: '' + format: '{0}' + color: orange + scope: response body + engine: nfa + sensitive: false + - name: Internal IP Address + loaded: true + f_regex: '[^0-9]((127\.0\.0\.1)|(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}))' + s_regex: '' + format: '{0}' + color: cyan + scope: response + engine: nfa + sensitive: true + - name: MAC Address + loaded: true + f_regex: (^([a-fA-F0-9]{2}(:[a-fA-F0-9]{2}){5})|[^a-zA-Z0-9]([a-fA-F0-9]{2}(:[a-fA-F0-9]{2}){5})) + s_regex: '' + format: '{0}' + color: green + scope: response + engine: nfa + sensitive: true +- group: Sensitive Information + rule: + - name: Cloud Key + loaded: true + f_regex: (((access)(|-|_)(key)(|-|_)(id|secret))|(LTAI[a-z0-9]{12,20})) + s_regex: '' + format: '{0}' + color: yellow + scope: any + engine: nfa + sensitive: false + - name: Windows File/Dir Path + loaded: true + f_regex: '[^\w]([a-zA-Z]:\\\\?(?:[^<>:/\\|?*]+\\\\?)*)([^<>:/\\|?*]+(?:\.[^<>:/\\|?*]+)?)' + s_regex: '' + format: '{0}' + color: green + scope: response + engine: nfa + sensitive: true + - name: Password Field + loaded: true + f_regex: ((|'|")(|[\w]{1,10})([p](ass|wd|asswd|assword))(|[\w]{1,10})(|'|")(:|=)( + |)('|")(.*?)('|")(|,)) + s_regex: '' + format: '{0}' + color: yellow + scope: response body + engine: nfa + sensitive: false + - name: Username Field + loaded: true + f_regex: ((|'|")(|[\w]{1,10})(([u](ser|name|sername))|(account)|((((create|update)((d|r)|(by|on|at)))|(creator))))(|[\w]{1,10})(|'|")(:|=)( + |)('|")(.*?)('|")(|,)) + s_regex: '' + format: '{0}' + color: green + scope: response body + engine: nfa + sensitive: false + - name: WeCom Key + loaded: true + f_regex: ((corp)(id|secret)) + s_regex: '' + format: '{0}' + color: green + scope: response body + engine: dfa + sensitive: false + - name: JDBC Connection + loaded: true + f_regex: (jdbc:[a-z:]+://[a-z0-9\.\-_:;=/@?,&]+) + s_regex: '' + format: '{0}' + color: yellow + scope: any + engine: nfa + sensitive: false + - name: Authorization Header + loaded: true + f_regex: ((basic [a-z0-9=:_\+\/-]{5,100})|(bearer [a-z0-9_.=:_\+\/-]{5,100})) + s_regex: '' + format: '{0}' + color: yellow + scope: response body + engine: nfa + sensitive: false + - name: Sensitive Field + loaded: true + f_regex: ((\[)?('|")?([\w]{0,10})((key)|(secret)|(token)|(config)|(auth)|(access)|(admin)|(ticket))([\w]{0,10})('|")?(\])?( + |)(:|=)( |)('|")(.*?)('|")(|,)) + s_regex: '' + format: '{0}' + color: yellow + scope: response + engine: nfa + sensitive: false +- group: Other + rule: + - name: Linkfinder + loaded: true + f_regex: (?:"|')(((?:[a-zA-Z]{1,10}://|//)[^"'/]{1,}\.[a-zA-Z]{2,}[^"']{0,})|((?:/|\.\./|\./)[^"'><,;|*()(%%$^/\\\[\]][^"'><,;|()]{1,})|([a-zA-Z0-9_\-/]{1,}/[a-zA-Z0-9_\-/]{1,}\.(?:[a-zA-Z]{1,4}|action)(?:[\?|#][^"|']{0,}|))|([a-zA-Z0-9_\-/]{1,}/[a-zA-Z0-9_\-/]{3,}(?:[\?|#][^"|']{0,}|))|([a-zA-Z0-9_\-]{1,}\.(?:\w)(?:[\?|#][^"|']{0,}|)))(?:"|') + s_regex: '' + format: '{0}' + color: gray + scope: response body + engine: nfa + sensitive: true + - name: Source Map + loaded: true + f_regex: (\.js\.map) + s_regex: '' + format: '{0}' + color: pink + scope: response body + engine: dfa + sensitive: false + - name: Create Script + loaded: true + f_regex: (\{[^{}]*\}\s*\[[^\s]*\]\s*\+\s*"[^\s]*\.js") + s_regex: '"?([\w].*?)"?:"(.*?)"' + format: '{0}.{1}' + color: green + scope: response body + engine: nfa + sensitive: false + - name: URL Schemes + loaded: true + f_regex: (\b(?![\w]{0,10}?https?://)(([-A-Za-z0-9]{1,20})://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|])) + s_regex: '' + format: '{0}' + color: yellow + scope: response body + engine: nfa + sensitive: false + - name: Router Push + loaded: true + f_regex: (\$router\.push) + s_regex: '' + format: '{0}' + color: magenta + scope: response body + engine: dfa + sensitive: false + - name: All URL + loaded: true + f_regex: (https?://[-A-Za-z0-9+&@#/%?=~_|!:,.;\u4E00-\u9FFF]+[-A-Za-z0-9+&@#/%=~_|]) + s_regex: '' + format: '{0}' + color: gray + scope: response body + engine: nfa + sensitive: true + - name: Request URI + loaded: true + f_regex: ' ((?!.*\.js(\?.*)?$)(.*?[^.js$])) ' + s_regex: '' + format: '{0}' + color: gray + scope: request line + engine: nfa + sensitive: false + - name: 302 Location + loaded: true + f_regex: 'Location: (.*?)\n' + s_regex: '' + format: '{0}' + color: gray + scope: response header + engine: nfa + sensitive: false