├── HostScan
├── .gitignore
├── .idea
│ ├── .gitignore
│ ├── artifacts
│ │ └── HostScan_jar.xml
│ ├── encodings.xml
│ └── misc.xml
├── out
│ └── artifacts
│ │ └── HostScan_jar
│ │ └── HostScan.jar
├── pom.xml
└── src
│ └── main
│ └── java
│ └── example
│ └── customscanchecks
│ ├── BurpExtender.java
│ ├── ScanCheck.java
│ ├── TestModel.java
│ ├── UI
│ ├── ConfigUi.java
│ ├── Menu.java
│ └── TableTemplate.java
│ └── Utils.java
├── LICENSE
├── README.md
└── images
├── 78170bb6529f16e2d29c42e764c5142.png
├── a5fff58bf98e935270f22d19e2dce85.png
├── b2a7c9ad2138e025550f49b9dd0377d.png
├── ceaab9b923e2758cb57e885d6d1b500.png
├── install.png
├── install1.png
├── install2.png
├── operate.png
└── show.png
/HostScan/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 | !**/src/main/**/target/
4 | !**/src/test/**/target/
5 |
6 | ### IntelliJ IDEA ###
7 | .idea/modules.xml
8 | .idea/jarRepositories.xml
9 | .idea/compiler.xml
10 | .idea/libraries/
11 | *.iws
12 | *.iml
13 | *.ipr
14 |
15 | ### Eclipse ###
16 | .apt_generated
17 | .classpath
18 | .factorypath
19 | .project
20 | .settings
21 | .springBeans
22 | .sts4-cache
23 |
24 | ### NetBeans ###
25 | /nbproject/private/
26 | /nbbuild/
27 | /dist/
28 | /nbdist/
29 | /.nb-gradle/
30 | build/
31 | !**/src/main/**/build/
32 | !**/src/test/**/build/
33 |
34 | ### VS Code ###
35 | .vscode/
36 |
37 | ### Mac OS ###
38 | .DS_Store
--------------------------------------------------------------------------------
/HostScan/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Editor-based HTTP Client requests
5 | /httpRequests/
6 | # Datasource local storage ignored files
7 | /dataSources/
8 | /dataSources.local.xml
9 |
--------------------------------------------------------------------------------
/HostScan/.idea/artifacts/HostScan_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | $PROJECT_DIR$/out/artifacts/HostScan_jar
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/HostScan/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/HostScan/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/HostScan/out/artifacts/HostScan_jar/HostScan.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hy0jer/HostScan/9e5b2ccb9625ee38d56a8a561b80d7e7093a94c2/HostScan/out/artifacts/HostScan_jar/HostScan.jar
--------------------------------------------------------------------------------
/HostScan/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | org.example
8 | HostScan
9 | 1.0-SNAPSHOT
10 |
11 |
12 | 17
13 | 17
14 | UTF-8
15 |
16 |
17 |
18 | net.portswigger.burp.extensions
19 | montoya-api
20 | 2023.10.4
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/HostScan/src/main/java/example/customscanchecks/BurpExtender.java:
--------------------------------------------------------------------------------
1 | package example.customscanchecks;
2 |
3 | import burp.api.montoya.BurpExtension;
4 | import burp.api.montoya.MontoyaApi;
5 | import burp.api.montoya.http.message.HttpRequestResponse;
6 | import burp.api.montoya.logging.Logging;
7 | import burp.api.montoya.ui.UserInterface;
8 | import burp.api.montoya.ui.editor.HttpRequestEditor;
9 | import burp.api.montoya.ui.editor.HttpResponseEditor;
10 | import example.customscanchecks.UI.ConfigUi;
11 | import example.customscanchecks.UI.Menu;
12 | import example.customscanchecks.UI.TableTemplate;
13 |
14 | import javax.swing.*;
15 | import java.awt.*;
16 |
17 | import static burp.api.montoya.ui.editor.EditorOptions.READ_ONLY;
18 |
19 |
20 | public class BurpExtender implements BurpExtension {
21 | private MontoyaApi api;
22 |
23 | @Override
24 | public void initialize(MontoyaApi api) {
25 | Logging logging = api.logging();
26 | logging.logToOutput("""
27 | ===================================
28 | HostScan v2.1 load success!
29 | Author: hy0jer
30 | ===================================""");
31 | this.api = api;
32 | TableTemplate tableModel = new TableTemplate();
33 | ConfigUi config = new ConfigUi();
34 | api.extension().setName("HostScan");
35 | api.userInterface().registerSuiteTab("HostScan", constructLoggerTab(tableModel, config));
36 | api.userInterface().registerContextMenuItemsProvider(new Menu(api, tableModel));
37 | api.scanner().registerScanCheck(new ScanCheck(api, tableModel, config));
38 | }
39 |
40 | private Component constructLoggerTab(TableTemplate tableModel, ConfigUi config) {
41 | JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
42 | JSplitPane downSplitPane = new JSplitPane();
43 | downSplitPane.setResizeWeight(0.5D);
44 |
45 | JTabbedPane tabs = new JTabbedPane();
46 | JTabbedPane tabx = new JTabbedPane();
47 |
48 | UserInterface userInterface = api.userInterface();
49 |
50 | HttpRequestEditor requestViewer = userInterface.createHttpRequestEditor(READ_ONLY);
51 | HttpResponseEditor responseViewer = userInterface.createHttpResponseEditor(READ_ONLY);
52 |
53 | tabs.addTab("Request", requestViewer.uiComponent());
54 | tabx.addTab("Response", responseViewer.uiComponent());
55 |
56 | downSplitPane.add(tabs, "left");
57 | downSplitPane.add(tabx, "right");
58 |
59 | splitPane.setRightComponent(downSplitPane);
60 |
61 | JTable table = new JTable(tableModel) {
62 | @Override
63 | public void changeSelection(int rowIndex, int columnIndex, boolean toggle, boolean extend) {
64 | HttpRequestResponse responseReceived = tableModel.get(rowIndex);
65 | requestViewer.setRequest(responseReceived.request());
66 | responseViewer.setResponse(responseReceived.response());
67 | super.changeSelection(rowIndex, columnIndex, toggle, extend);
68 | }
69 | };
70 |
71 | JSplitPane upSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
72 | upSplitPane.setEnabled(false);
73 | upSplitPane.add(config, "left");
74 |
75 | JScrollPane scrollPane = new JScrollPane(table);
76 | upSplitPane.add(scrollPane, "right");
77 | splitPane.setLeftComponent(upSplitPane);
78 |
79 | return splitPane;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/HostScan/src/main/java/example/customscanchecks/ScanCheck.java:
--------------------------------------------------------------------------------
1 | package example.customscanchecks;
2 |
3 | import burp.api.montoya.MontoyaApi;
4 | import burp.api.montoya.http.message.HttpRequestResponse;
5 | import burp.api.montoya.scanner.AuditResult;
6 | import burp.api.montoya.scanner.ConsolidationAction;
7 | import burp.api.montoya.scanner.audit.insertionpoint.AuditInsertionPoint;
8 | import burp.api.montoya.scanner.audit.issues.AuditIssue;
9 | import burp.api.montoya.scanner.audit.issues.AuditIssueConfidence;
10 | import burp.api.montoya.scanner.audit.issues.AuditIssueSeverity;
11 | import example.customscanchecks.UI.ConfigUi;
12 | import example.customscanchecks.UI.TableTemplate;
13 |
14 | import java.util.ArrayList;
15 | import java.util.List;
16 |
17 | import static burp.api.montoya.scanner.AuditResult.auditResult;
18 | import static burp.api.montoya.scanner.ConsolidationAction.KEEP_BOTH;
19 | import static burp.api.montoya.scanner.ConsolidationAction.KEEP_EXISTING;
20 | import static burp.api.montoya.scanner.audit.issues.AuditIssue.auditIssue;
21 | import static java.util.Collections.emptyList;
22 | import static java.util.Collections.singletonList;
23 |
24 |
25 | class ScanCheck implements burp.api.montoya.scanner.ScanCheck {
26 | private final TableTemplate tableModel;
27 | private static final String GREP_STRING = "www.test.com";
28 | private final MontoyaApi api;
29 | public ConfigUi configUi;
30 |
31 | ScanCheck(MontoyaApi api, TableTemplate tableModel, ConfigUi configUi) {
32 | this.tableModel = tableModel;
33 | this.api = api;
34 | this.configUi = configUi;
35 |
36 | }
37 |
38 | @Override
39 | public AuditResult activeAudit(HttpRequestResponse baseRequestResponse, AuditInsertionPoint auditInsertionPoint) {
40 | return null;
41 | }
42 |
43 | @Override
44 | public AuditResult passiveAudit(HttpRequestResponse baseRequestResponse) {
45 | List auditIssueList = new ArrayList<>();
46 | if (!this.configUi.getAutoSendRequest()) {
47 | return auditResult(auditIssueList);
48 | }
49 | TestModel model = new TestModel(this.api, baseRequestResponse);
50 | HttpRequestResponse result_package = model.test_engine(this.api, baseRequestResponse, this.tableModel);
51 | if (result_package != null) {
52 | auditIssueList = singletonList(
53 | auditIssue(
54 | "Host header attack",
55 | "This response packet contains incorrect host field information: " + GREP_STRING,
56 | "Web applications should use SERVER_NAME instead of host header",
57 | result_package.request().url(),
58 | AuditIssueSeverity.LOW,
59 | AuditIssueConfidence.CERTAIN,
60 | null,
61 | null,
62 | AuditIssueSeverity.LOW,
63 | result_package));
64 | } else {
65 | auditIssueList = emptyList();
66 | }
67 | return auditResult(auditIssueList);
68 | }
69 |
70 | @Override
71 | public ConsolidationAction consolidateIssues(AuditIssue newIssue, AuditIssue existingIssue) {
72 | return existingIssue.name().equals(newIssue.name()) ? KEEP_EXISTING : KEEP_BOTH;
73 | }
74 | }
--------------------------------------------------------------------------------
/HostScan/src/main/java/example/customscanchecks/TestModel.java:
--------------------------------------------------------------------------------
1 | package example.customscanchecks;
2 |
3 | import burp.api.montoya.MontoyaApi;
4 | import burp.api.montoya.http.message.HttpHeader;
5 | import burp.api.montoya.logging.Logging;
6 | import burp.api.montoya.http.message.HttpRequestResponse;
7 | import burp.api.montoya.http.message.requests.HttpRequest;
8 | import example.customscanchecks.UI.TableTemplate;
9 |
10 | import java.util.List;
11 | import java.util.Objects;
12 |
13 |
14 | public class TestModel {
15 | public MontoyaApi api;
16 | public HttpRequestResponse baseRequestResponse;
17 |
18 | public TestModel(MontoyaApi api, HttpRequestResponse baseRequestResponse) {
19 | this.api = api;
20 | this.baseRequestResponse = baseRequestResponse;
21 | }
22 |
23 | public HttpRequestResponse test_engine(MontoyaApi api, HttpRequestResponse baseRequestResponse, TableTemplate tableModel) {
24 | HttpRequest send_package = baseRequestResponse.request();
25 | Logging logging = api.logging();
26 | logging.logToOutput("Scanning " + send_package.url());
27 | HttpRequestResponse later_package = this.api.http().sendRequest(send_package);
28 | String path = later_package.request().path();
29 | int statusCode = later_package.response().statusCode();
30 | if (statusCode < 300 && statusCode >= 200) {
31 | if (Utils.count_string(path, '/') != 0) {
32 | StringBuilder sb = new StringBuilder(path);
33 | sb.delete(Utils.count_string(path, '/'), sb.length());
34 | String test_path = sb.toString();
35 | return poc_sender(api, baseRequestResponse, test_path, tableModel);
36 | }
37 | } else if (statusCode < 400 && statusCode >= 300) {
38 | return poc_sender(api, baseRequestResponse, path, tableModel);
39 | }
40 | return null;
41 | }
42 |
43 | public HttpRequestResponse poc_sender(MontoyaApi api, HttpRequestResponse baseRequestResponse, String path, TableTemplate tableModel) {
44 | HttpRequest request_package = baseRequestResponse.request().withUpdatedHeader("host", "test.com.cn").withPath(path);
45 | HttpRequestResponse later_package = this.api.http().sendRequest(request_package);
46 | //该分支判断回包是否为空
47 | if (later_package.response() == null) {
48 | return null;
49 | }
50 | if (later_package.response().statusCode() / 100 == 3) {
51 | List headers = later_package.response().headers();
52 | for (HttpHeader item : headers) {
53 | if (Objects.equals(item.name(), "Location") && item.value().contains("test")) {
54 | tableModel.add(later_package);
55 | return later_package;
56 | }
57 | }
58 | }
59 | return null;
60 | }
61 | }
62 |
63 |
--------------------------------------------------------------------------------
/HostScan/src/main/java/example/customscanchecks/UI/ConfigUi.java:
--------------------------------------------------------------------------------
1 | package example.customscanchecks.UI;
2 |
3 | import javax.swing.*;
4 |
5 |
6 | public class ConfigUi extends JToolBar {
7 | public JCheckBox autoSendRequestCheckBox;
8 |
9 | public ConfigUi() {
10 | this.autoSendRequestCheckBox = new JCheckBox("Auto sending");
11 | // 默认发送
12 | this.autoSendRequestCheckBox.setSelected(true);
13 | // 不可悬浮
14 | this.setFloatable(false);
15 | this.add(autoSendRequestCheckBox);
16 | }
17 |
18 | public Boolean getAutoSendRequest() {
19 | return this.autoSendRequestCheckBox.isSelected();
20 | }
21 | }
--------------------------------------------------------------------------------
/HostScan/src/main/java/example/customscanchecks/UI/Menu.java:
--------------------------------------------------------------------------------
1 | package example.customscanchecks.UI;
2 |
3 | import burp.api.montoya.MontoyaApi;
4 | import burp.api.montoya.http.message.HttpRequestResponse;
5 | import burp.api.montoya.ui.contextmenu.ContextMenuEvent;
6 | import burp.api.montoya.ui.contextmenu.ContextMenuItemsProvider;
7 | import example.customscanchecks.TestModel;
8 |
9 | import javax.swing.*;
10 | import java.awt.*;
11 | import java.awt.event.ActionEvent;
12 | import java.awt.event.ActionListener;
13 | import java.util.ArrayList;
14 | import java.util.List;
15 | import java.util.concurrent.CompletableFuture;
16 |
17 |
18 | public class Menu implements ContextMenuItemsProvider {
19 | public final MontoyaApi api;
20 | public TableTemplate tableModel;
21 |
22 | public Menu(MontoyaApi api, TableTemplate tableModel) {
23 | this.api = api;
24 | this.tableModel = tableModel;
25 |
26 | }
27 |
28 | public List provideMenuItems(ContextMenuEvent event) {
29 | ArrayList menuItemList = new ArrayList<>();
30 | JMenuItem menuItem = new JMenuItem("Do Host attack scan");
31 | menuItem.addActionListener(new ContextMenuActionListener(event, api, tableModel));
32 | menuItemList.add(menuItem);
33 | return menuItemList;
34 | }
35 |
36 | static class ContextMenuActionListener implements ActionListener {
37 | ContextMenuEvent invocation;
38 | public MontoyaApi api;
39 | public TableTemplate tableModel;
40 |
41 | public ContextMenuActionListener(ContextMenuEvent event, MontoyaApi api, TableTemplate tableModel) {
42 | this.invocation = event;
43 | this.api = api;
44 | this.tableModel = tableModel;
45 | }
46 |
47 | @Override
48 | public void actionPerformed(ActionEvent actionEvent) {
49 | CompletableFuture.supplyAsync(() -> {
50 | List httpRequestResponses = invocation.selectedRequestResponses();
51 | for (HttpRequestResponse baseRequestResponse : httpRequestResponses) {
52 | TestModel model = new TestModel(this.api, baseRequestResponse);
53 | HttpRequestResponse result_package = model.test_engine(this.api, baseRequestResponse, this.tableModel);
54 | }
55 | return null;
56 | });
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/HostScan/src/main/java/example/customscanchecks/UI/TableTemplate.java:
--------------------------------------------------------------------------------
1 | package example.customscanchecks.UI;
2 |
3 | import burp.api.montoya.http.message.HttpRequestResponse;
4 |
5 | import javax.swing.table.AbstractTableModel;
6 | import java.util.ArrayList;
7 | import java.util.List;
8 |
9 |
10 | public class TableTemplate extends AbstractTableModel {
11 | private final List log;
12 |
13 | public TableTemplate() {
14 | this.log = new ArrayList<>();
15 | }
16 |
17 | @Override
18 | public synchronized int getRowCount() {
19 | return log.size();
20 | }
21 |
22 | @Override
23 | public int getColumnCount() {
24 | return 2;
25 | }
26 |
27 | @Override
28 | public String getColumnName(int column) {
29 | return switch (column) {
30 | case 0 -> "Status";
31 | case 1 -> "URL";
32 | default -> "";
33 | };
34 | }
35 |
36 | @Override
37 | public synchronized Object getValueAt(int rowIndex, int columnIndex) {
38 | HttpRequestResponse responseReceived = log.get(rowIndex);
39 | return switch (columnIndex) {
40 | case 0 -> responseReceived.response().statusCode();
41 | case 1 -> responseReceived.request().url();
42 | default -> "";
43 | };
44 | }
45 |
46 | public synchronized void add(HttpRequestResponse responseReceived) {
47 | int index = log.size();
48 | log.add(responseReceived);
49 | fireTableRowsInserted(index, index);
50 | }
51 |
52 | public synchronized HttpRequestResponse get(int rowIndex) {
53 | return log.get(rowIndex);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/HostScan/src/main/java/example/customscanchecks/Utils.java:
--------------------------------------------------------------------------------
1 | package example.customscanchecks;
2 |
3 | public class Utils {
4 | public static int count_string(String string, char find_string) {
5 | int[] count = new int[2];
6 | for (int i = 0; i < string.length(); i++) {
7 | if (string.charAt(i) == find_string) {
8 | count[0]++;
9 | if (count[0] >= 2) {
10 | count[1] = i;
11 | }
12 | }
13 | }
14 | return count[1];
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 hy0jer
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## 前言
2 |
3 | 该BP插件是在工作之余编写出来的,设计初衷是实现对host头攻击的全自动检测,这是作者第一次尝试编写bp插件,可以说是个Demo项目,如果有任何使用问题或者其他好的idea,可提交issues
4 |
5 | ## 简介
6 |
7 | 该插件支持对host头攻击的全自动检测和主动扫描
8 |
9 | #注意该BP插件使用MontoyaApi编写,不兼容旧版burp suite
10 |
11 | ## 安装流程
12 |
13 | 在burp suite的Extensions选项页面添加HostScan插件
14 |
15 | 
16 |
17 | 正常安装完毕后是如下页面显示
18 |
19 | 
20 |
21 | 
22 |
23 | ### 使用说明
24 |
25 | 该插件支持两种运行方式,手动选择进行扫描以及自动扫描
26 |
27 | ### 自动扫描
28 |
29 | 安装后该插件初始状态默认设置自动扫描,即经过burp suite的流量都会进行扫描,如果检测到存在host头攻击会在Target选项页面以及HostScan插件详情页面显示具体情况,如下图所示
30 |
31 | 
32 |
33 | 
34 |
35 |
36 |
37 | 如果不想使用自动扫描,可点击该框关闭,如下所示
38 |
39 | 
40 |
41 | 
42 |
43 | ### 主动扫描
44 |
45 | 右键选择需要检测的请求包通过extensions选项进行扫描
46 |
47 | 
48 |
49 | 如果检测出安全问题,会在详情页面显示
50 |
51 | 
52 |
--------------------------------------------------------------------------------
/images/78170bb6529f16e2d29c42e764c5142.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hy0jer/HostScan/9e5b2ccb9625ee38d56a8a561b80d7e7093a94c2/images/78170bb6529f16e2d29c42e764c5142.png
--------------------------------------------------------------------------------
/images/a5fff58bf98e935270f22d19e2dce85.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hy0jer/HostScan/9e5b2ccb9625ee38d56a8a561b80d7e7093a94c2/images/a5fff58bf98e935270f22d19e2dce85.png
--------------------------------------------------------------------------------
/images/b2a7c9ad2138e025550f49b9dd0377d.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hy0jer/HostScan/9e5b2ccb9625ee38d56a8a561b80d7e7093a94c2/images/b2a7c9ad2138e025550f49b9dd0377d.png
--------------------------------------------------------------------------------
/images/ceaab9b923e2758cb57e885d6d1b500.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hy0jer/HostScan/9e5b2ccb9625ee38d56a8a561b80d7e7093a94c2/images/ceaab9b923e2758cb57e885d6d1b500.png
--------------------------------------------------------------------------------
/images/install.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hy0jer/HostScan/9e5b2ccb9625ee38d56a8a561b80d7e7093a94c2/images/install.png
--------------------------------------------------------------------------------
/images/install1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hy0jer/HostScan/9e5b2ccb9625ee38d56a8a561b80d7e7093a94c2/images/install1.png
--------------------------------------------------------------------------------
/images/install2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hy0jer/HostScan/9e5b2ccb9625ee38d56a8a561b80d7e7093a94c2/images/install2.png
--------------------------------------------------------------------------------
/images/operate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hy0jer/HostScan/9e5b2ccb9625ee38d56a8a561b80d7e7093a94c2/images/operate.png
--------------------------------------------------------------------------------
/images/show.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hy0jer/HostScan/9e5b2ccb9625ee38d56a8a561b80d7e7093a94c2/images/show.png
--------------------------------------------------------------------------------