This extension lets you configure multiple scan profiles, such as "XSS only" or "Quick scan".
2 | When sending items to be scanned, you can select which profile to use from the context menu.
3 |
4 |
The plugin will automatically manage the new queue and run scans with the different configuration.
5 |
6 |
Please note that when using this plugin you should NOT use the normal active scanner nor modify Burp scanning configuration.
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/BappManifest.bmf:
--------------------------------------------------------------------------------
1 | Uuid: a019ad8b3cea46ac9032d279440f5372
2 | ExtensionType: 1
3 | Name: Attack Selector
4 | RepoName: attack-selector
5 | ScreenVersion: 0.1
6 | SerialVersion: 1
7 | MinPlatformVersion: 0
8 | ProOnly: True
9 | Author: Maurizio Agazzini
10 | ShortDescription: Allows you to create multiple scan profiles and select the one to use from the context menu.
11 | EntryPoint: target/AttackSelector-0.1-jar-with-dependencies.jar
12 | BuildCommand: mvn package -DskipTests=true -Dmaven.javadoc.skip=true -B
13 |
--------------------------------------------------------------------------------
/src/main/java/burp/ConfigurationTableModel.java:
--------------------------------------------------------------------------------
1 | package burp;
2 |
3 | import java.util.List;
4 | import javax.swing.table.AbstractTableModel;
5 |
6 | public class ConfigurationTableModel extends AbstractTableModel {
7 |
8 | private final List configurationList;
9 |
10 | private static final long serialVersionUID = 1L;
11 |
12 | private final String[] columnNames = new String[] { "Enabled", "Name" };
13 |
14 | private final Class>[] columnClass = new Class>[] { Boolean.class, String.class };
15 |
16 | public ConfigurationTableModel(List configurationList) {
17 | this.configurationList = configurationList;
18 | }
19 |
20 | @Override
21 | public String getColumnName(int column) {
22 | return columnNames[column];
23 | }
24 |
25 | @Override
26 | public Class> getColumnClass(int columnIndex) {
27 | return columnClass[columnIndex];
28 | }
29 |
30 | @Override
31 | public int getColumnCount() {
32 | return columnNames.length;
33 | }
34 |
35 | @Override
36 | public int getRowCount() {
37 | return configurationList.size();
38 | }
39 |
40 | @Override
41 | public Object getValueAt(int rowIndex, int columnIndex) {
42 | Configuration row = configurationList.get(rowIndex);
43 | if (0 == columnIndex) {
44 | return row.getEnabled();
45 | } else if (1 == columnIndex) {
46 | return row.getName();
47 | }
48 |
49 | return null;
50 | }
51 |
52 | @Override
53 | public void setValueAt(Object value, int rowIndex, int colIndex) {
54 | Configuration row = configurationList.get(rowIndex);
55 | switch (colIndex) {
56 | case 0:
57 | row.setEnabled((Boolean) value);
58 | break;
59 | case 1:
60 | row.setName(value.toString());
61 | break;
62 | }
63 | fireTableRowsUpdated(rowIndex, colIndex);
64 | }
65 |
66 | @Override
67 | public boolean isCellEditable(int rowIndex, int columnIndex) {
68 | if( rowIndex == 0 )
69 | return false;
70 |
71 | return true;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | burp
6 | AttackSelector
7 | 0.1
8 | jar
9 |
10 | Burp Suite Attack Selector Plugin
11 |
12 |
13 | UTF-8
14 |
15 |
16 |
17 |
18 |
19 | org.json
20 | json
21 | 20170516
22 |
23 |
24 |
25 | net.portswigger.burp.extender
26 | burp-extender-api
27 | 1.7.22
28 |
29 |
30 |
31 |
32 |
33 | org.apache.maven.plugins
34 | maven-compiler-plugin
35 |
36 | 1.7
37 | 1.7
38 |
39 | jar-with-dependencies
40 |
41 |
42 |
43 |
44 | maven-assembly-plugin
45 | 3.1.0
46 |
47 |
48 | jar-with-dependencies
49 |
50 |
51 |
52 |
53 | make-assembly
54 | package
55 |
56 | single
57 |
58 |
59 |
60 |
61 |
62 |
63 | https://github.com/inode-/AttackSelector
64 |
65 |
--------------------------------------------------------------------------------
/src/main/java/burp/PluginQueue.java:
--------------------------------------------------------------------------------
1 | /*****************************************************************************
2 | * PluginQueue.java part of AttackSelector Burp Plugin *
3 | * *
4 | * Copyright (c) 2017, Agazzini Maurizio - inode@mediaservice.net *
5 | * All rights reserved. *
6 | * *
7 | * Redistribution and use in source and binary forms, with or without *
8 | * modification, are permitted provided that the following conditions *
9 | * are met: *
10 | * * Redistributions of source code must retain the above copyright *
11 | * notice, this list of conditions and the following disclaimer. *
12 | * * Redistributions in binary form must reproduce the above copyright *
13 | * notice, this list of conditions and the following disclaimer in *
14 | * the documentation and/or other materials provided with the *
15 | * distribution. *
16 | * * Neither the name of @ Mediaservice.net nor the names of its *
17 | * contributors may be used to endorse or promote products derived *
18 | * from this software without specific prior written permission. *
19 | * *
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *
22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR *
23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT *
24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *
25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED *
26 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
27 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
28 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
29 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
30 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
31 | *****************************************************************************/
32 |
33 | package burp;
34 |
35 | public class PluginQueue {
36 |
37 | private int queueNumber;
38 | private IHttpRequestResponse message;
39 | private int configuration;
40 | private int status;
41 | private IScanQueueItem burp_queue;
42 | private boolean intruder;
43 |
44 | public int getQueueNumber() {
45 | return queueNumber;
46 | }
47 |
48 | public IHttpRequestResponse getMessage() {
49 | return message;
50 | }
51 |
52 | public int getConfiguration() {
53 | return configuration;
54 | }
55 |
56 | public int getStatus() {
57 | return status;
58 | }
59 |
60 | public boolean getIntruder() {
61 | return intruder;
62 | }
63 |
64 | public IScanQueueItem getBurpQueue() {
65 | return burp_queue;
66 | }
67 |
68 | public void setQueueNumber(int i) {
69 | queueNumber = i;
70 | }
71 |
72 | public void setIntruder(boolean i) {
73 | intruder = i;
74 | }
75 |
76 | public void setMessage(IHttpRequestResponse msg) {
77 | message = msg;
78 | }
79 |
80 | public void setConfiguration(int i) {
81 | configuration = i;
82 | }
83 |
84 | public void setStatus(int i) {
85 | status = i;
86 | }
87 |
88 | public void setBurpQueue(IScanQueueItem burp_queue) {
89 | this.burp_queue = burp_queue;
90 | }
91 |
92 | }
93 |
--------------------------------------------------------------------------------
/src/main/java/burp/Configuration.java:
--------------------------------------------------------------------------------
1 | /*****************************************************************************
2 | * Configuration.java part of AttackSelector Burp Plugin *
3 | * *
4 | * Copyright (c) 2017, Agazzini Maurizio - inode@mediaservice.net *
5 | * All rights reserved. *
6 | * *
7 | * Redistribution and use in source and binary forms, with or without *
8 | * modification, are permitted provided that the following conditions *
9 | * are met: *
10 | * * Redistributions of source code must retain the above copyright *
11 | * notice, this list of conditions and the following disclaimer. *
12 | * * Redistributions in binary form must reproduce the above copyright *
13 | * notice, this list of conditions and the following disclaimer in *
14 | * the documentation and/or other materials provided with the *
15 | * distribution. *
16 | * * Neither the name of @ Mediaservice.net nor the names of its *
17 | * contributors may be used to endorse or promote products derived *
18 | * from this software without specific prior written permission. *
19 | * *
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *
22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR *
23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT *
24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *
25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED *
26 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
27 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
28 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
29 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
30 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
31 | *****************************************************************************/
32 |
33 | package burp;
34 |
35 | import org.json.JSONObject;
36 |
37 | public class Configuration {
38 |
39 | private Boolean enabled;
40 | private String name;
41 | private JSONObject configuration;
42 |
43 | public Configuration() {
44 |
45 | }
46 |
47 | public Configuration(Boolean enabled, String name, String conf) {
48 |
49 | this.enabled = enabled;
50 | this.name = name;
51 | configuration = new JSONObject(conf);
52 | }
53 |
54 | public String getName() {
55 | return name;
56 | }
57 |
58 | public Boolean getEnabled() {
59 | return enabled;
60 | }
61 |
62 | public JSONObject getConfiguration() {
63 | return configuration;
64 | }
65 |
66 | public void setName(String name) {
67 | this.name = name;
68 | }
69 |
70 | public void setEnabled(Boolean enabled) {
71 | this.enabled = enabled;
72 | }
73 |
74 | public void setConfiguration(String conf) {
75 | configuration = new JSONObject(conf);
76 | }
77 |
78 | public JSONObject exportToJson() {
79 | JSONObject obj;
80 |
81 | obj = new JSONObject();
82 |
83 | obj.put("name", name);
84 | obj.put("enabled", enabled);
85 | obj.put("configuration", configuration);
86 |
87 | return obj;
88 | }
89 |
90 | public void importFromJson(String conf) {
91 | JSONObject obj = new JSONObject(conf);
92 |
93 | setName((String) obj.get("name"));
94 | setEnabled((Boolean) obj.get("enabled"));
95 |
96 | configuration = new JSONObject(obj.getJSONObject("configuration").toString());
97 |
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Burp Attack Selector Plugin
2 |
3 | During latest years Burp Suite scanner checks has been expanded a lot, but unfortunately the need of a scan time compromise has limited notably the checks executed during the scans with "Intelligent check" enabled. The current standard configuration will allow you to find the main issues but will not identify some kinds of problem. Also by modifiing the Burp configuration you will not be able to manage correctly the scans due [some actual Burp limitations](https://support.portswigger.net/customer/portal/questions/17025859-active-scan-configuration-taken-when-scan-request-insered-into-the-queue-and-not-when-scan-start).
4 |
5 | This plugin will let you to configure different settings for Burp active scanner and create some custom scanner configuration that can be launched via menu. The plugin will automatically manage the new queue and run scans with the different configuration.
6 |
7 | **Please note that when using this plugin you should NOT use the normal active scanner nor modify Burp scanning configuration**, by default the scanner will use the current configuration, so will execute only the tests configured in the running scan of this plugin. For this purpose we created a "default" scan configuration in this plugin that will allow you "simulate" the standard active scan, but it will be managed inside of the plugin so will be compatible with our others scans.
8 |
9 | During last week I discovered that [Burp Developers are planning to add some new features](https://support.portswigger.net/customer/portal/questions/17162032-my-letter-to-santa-burp-team-2-17-extender-api-enhancements-) like the queue management, maybe in some month my plugin will be unuseful ;)
10 |
11 | I have to thank [Federico Dotta](https://github.com/federicodotta/) for introducing me in Burp plugin programming and for the help given during the writing of this plugin.
12 |
13 | ## Usage
14 |
15 | When the plugin is added to Burp Suite a new tab will apper. This tab will allow you to see the plugin queue and configure your custom scanner configuration. After that you will able to launch the scan with that configuration via the content menu created.
16 |
17 | 
18 |
19 | 
20 |
21 | 
22 |
23 | 
24 |
25 | ## License
26 |
27 | Copyright (c) 2017, Agazzini Maurizio - inode@mediaservice.net
28 | All rights reserved.
29 |
30 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
31 |
32 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
33 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
34 | * Neither the name of @ Mediaservice.net nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
35 |
36 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
/src/main/java/burp/PluginQueueTableModel.java:
--------------------------------------------------------------------------------
1 | /*****************************************************************************
2 | * PluginQueueTableModel.java part of AttackSelector Burp Plugin *
3 | * *
4 | * Copyright (c) 2017, Agazzini Maurizio - inode@mediaservice.net *
5 | * All rights reserved. *
6 | * *
7 | * Redistribution and use in source and binary forms, with or without *
8 | * modification, are permitted provided that the following conditions *
9 | * are met: *
10 | * * Redistributions of source code must retain the above copyright *
11 | * notice, this list of conditions and the following disclaimer. *
12 | * * Redistributions in binary form must reproduce the above copyright *
13 | * notice, this list of conditions and the following disclaimer in *
14 | * the documentation and/or other materials provided with the *
15 | * distribution. *
16 | * * Neither the name of @ Mediaservice.net nor the names of its *
17 | * contributors may be used to endorse or promote products derived *
18 | * from this software without specific prior written permission. *
19 | * *
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *
22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR *
23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT *
24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *
25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED *
26 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
27 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
28 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
29 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
30 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
31 | *****************************************************************************/
32 |
33 | package burp;
34 |
35 | import java.util.List;
36 | import java.net.URL;
37 |
38 | import javax.swing.table.AbstractTableModel;
39 |
40 | public class PluginQueueTableModel extends AbstractTableModel {
41 |
42 | private final List queueList;
43 | private List configurationList;
44 |
45 | private static final long serialVersionUID = 1L;
46 |
47 | private final String[] columnNames = new String[] { "#", "Host", "Url", "Configuration", "Status" };
48 |
49 | private IExtensionHelpers helpers;
50 |
51 | private final Class>[] columnClass = new Class>[] { Integer.class, String.class, String.class, String.class,
52 | String.class };
53 |
54 | public PluginQueueTableModel(List queueList, List configurationList,
55 | IExtensionHelpers helpers) {
56 | this.queueList = queueList;
57 | this.helpers = helpers;
58 | this.configurationList = configurationList;
59 | }
60 |
61 | @Override
62 | public String getColumnName(int column) {
63 |
64 | return columnNames[column];
65 | }
66 |
67 | @Override
68 | public Class> getColumnClass(int columnIndex) {
69 | return columnClass[columnIndex];
70 | }
71 |
72 | @Override
73 | public int getColumnCount() {
74 | return columnNames.length;
75 | }
76 |
77 | @Override
78 | public int getRowCount() {
79 | return queueList.size();
80 | }
81 |
82 | @Override
83 | public Object getValueAt(int rowIndex, int columnIndex) {
84 |
85 | PluginQueue row = queueList.get(rowIndex);
86 | if (0 == columnIndex) {
87 | return row.getQueueNumber();
88 | } else if (1 == columnIndex) {
89 | return row.getMessage().getHttpService().getProtocol() + "://" + row.getMessage().getHttpService().getHost()
90 | + ":" + row.getMessage().getHttpService().getPort();
91 | } else if (2 == columnIndex) {
92 |
93 | IRequestInfo request_info = helpers.analyzeRequest(row.getMessage());
94 | URL requestUrl = request_info.getUrl();
95 |
96 | String urlPath = requestUrl.getPath();
97 |
98 | if ((requestUrl.getQuery() != null) && (!requestUrl.getQuery().isEmpty())) {
99 | urlPath.concat("?");
100 | urlPath.concat(requestUrl.getQuery());
101 | }
102 |
103 | return urlPath;
104 |
105 | } else if (3 == columnIndex) {
106 | return configurationList.get(row.getConfiguration()).getName();
107 | } else if (4 == columnIndex) {
108 |
109 | switch (row.getStatus()) {
110 |
111 | case 0:
112 | return "queued";
113 | case 1:
114 | return "scanning";
115 | case 2:
116 | return "finished";
117 | case 3:
118 | return "cancelled";
119 | }
120 |
121 | return "";
122 | }
123 |
124 | return null;
125 | }
126 |
127 | @Override
128 | public boolean isCellEditable(int rowIndex, int columnIndex) {
129 |
130 | return false;
131 | }
132 |
133 | }
134 |
--------------------------------------------------------------------------------
/src/main/java/burp/ScannerThread.java:
--------------------------------------------------------------------------------
1 | /*****************************************************************************
2 | * ScannerThread.java part of AttackSelector Burp Plugin *
3 | * *
4 | * Copyright (c) 2017, Agazzini Maurizio - inode@mediaservice.net *
5 | * All rights reserved. *
6 | * *
7 | * Redistribution and use in source and binary forms, with or without *
8 | * modification, are permitted provided that the following conditions *
9 | * are met: *
10 | * * Redistributions of source code must retain the above copyright *
11 | * notice, this list of conditions and the following disclaimer. *
12 | * * Redistributions in binary form must reproduce the above copyright *
13 | * notice, this list of conditions and the following disclaimer in *
14 | * the documentation and/or other materials provided with the *
15 | * distribution. *
16 | * * Neither the name of @ Mediaservice.net nor the names of its *
17 | * contributors may be used to endorse or promote products derived *
18 | * from this software without specific prior written permission. *
19 | * *
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *
22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR *
23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT *
24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *
25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED *
26 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
27 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
28 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
29 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
30 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
31 | *****************************************************************************/
32 |
33 | package burp;
34 |
35 | import java.io.PrintWriter;
36 | import java.util.List;
37 | import java.util.concurrent.locks.ReentrantLock;
38 |
39 | import org.json.JSONObject;
40 |
41 | public class ScannerThread implements Runnable {
42 |
43 | BurpExtender burp_plugin;
44 |
45 | private List queueList;
46 | private ReentrantLock lock;
47 | private static PrintWriter stdout;
48 |
49 | // Thread will check new work every X milliseconds
50 | private int check_every = 2000;
51 |
52 | private volatile boolean running = true;
53 |
54 | private IBurpExtenderCallbacks callbacks;
55 |
56 | public ScannerThread(BurpExtender plugin_ref) {
57 |
58 | burp_plugin = plugin_ref;
59 |
60 | queueList = burp_plugin.getqueueList();
61 | lock = burp_plugin.getLock();
62 | stdout = burp_plugin.getStdout();
63 | callbacks = burp_plugin.getCallbacks();
64 | }
65 |
66 | public void terminate() {
67 | running = false;
68 | }
69 |
70 | @Override
71 | public void run() {
72 |
73 | int maxThreads;
74 |
75 | while (running) {
76 |
77 | try {
78 |
79 | // Get current maximum of threads
80 | String jsonConfig = callbacks.saveConfigAsJson();
81 | JSONObject obj = new JSONObject(jsonConfig);
82 | maxThreads = obj.getJSONObject("scanner").getJSONObject("active_scanning_engine")
83 | .getInt("number_of_threads");
84 |
85 | lock.lock();
86 | try {
87 |
88 | int currentThreads = 0;
89 | int configuration = -1;
90 | int thread_change = -1;
91 |
92 | // Removed unused threads
93 | for (int i = 0; i < queueList.size(); i++) {
94 |
95 | if (queueList.get(i).getStatus() == 1) {
96 |
97 | if (queueList.get(i).getBurpQueue().getStatus().contains("complete")) {
98 |
99 | // Save current running configuration
100 | configuration = queueList.get(i).getConfiguration();
101 | currentThreads++;
102 |
103 | } else if (queueList.get(i).getBurpQueue().getStatus().contains("finished")) {
104 | queueList.get(i).setStatus(2);
105 | thread_change = 0;
106 | }
107 |
108 | else if (queueList.get(i).getBurpQueue().getStatus().contains("cancelled")) {
109 | queueList.get(i).setStatus(3);
110 | thread_change = 0;
111 | }
112 |
113 | }
114 | }
115 |
116 | // Revert configuration to default when all scan has been
117 | // finished
118 | if (thread_change == 0)
119 | burp_plugin.updateScannerConfig(queueList.get(0).getConfiguration());
120 |
121 | // Add same configuration works
122 | for (int i = 0; i < queueList.size(); i++) {
123 |
124 | // If threads are full just skip
125 | if (currentThreads > maxThreads)
126 | break;
127 |
128 | if (queueList.get(i).getStatus() == 0) {
129 |
130 | if (queueList.get(i).getStatus() == 0
131 | && configuration == queueList.get(i).getConfiguration()) {
132 |
133 | if (currentThreads < maxThreads) {
134 |
135 | stdout.println("Add same configuration");
136 |
137 | // Update to running
138 | queueList.get(i).setStatus(1);
139 |
140 | // Request to burp to scan the URL and
141 | // save the scan queue
142 | queueList.get(i).setBurpQueue(burp_plugin.scanVuln(queueList.get(i).getMessage(),
143 | queueList.get(i).getIntruder()));
144 |
145 | currentThreads++;
146 |
147 | stdout.println("Added a new URL to SCAN");
148 |
149 | }
150 | }
151 | }
152 | }
153 |
154 | // Add new work if all threads are free
155 | for (int i = 0; i < queueList.size(); i++) {
156 |
157 | // If threads are full just skip
158 | if (currentThreads > maxThreads)
159 | break;
160 |
161 | if (queueList.get(i).getStatus() == 0) {
162 |
163 | if (configuration == -1) {
164 |
165 | configuration = queueList.get(i).getConfiguration();
166 | burp_plugin.updateScannerConfig(configuration);
167 |
168 | } else if (configuration != queueList.get(i).getConfiguration())
169 | continue;
170 |
171 | if (currentThreads < maxThreads) {
172 |
173 | // Update to running
174 | queueList.get(i).setStatus(1);
175 |
176 | // Request to burp to scan the URL and save the
177 | // scan queue
178 | queueList.get(i).setBurpQueue(burp_plugin.scanVuln(queueList.get(i).getMessage(),
179 | queueList.get(i).getIntruder()));
180 |
181 | currentThreads++;
182 | }
183 |
184 | }
185 | }
186 |
187 | } finally {
188 | lock.unlock();
189 | }
190 |
191 | // wait sometimes, we do not want to use 100% of the CPU
192 | Thread.sleep(check_every);
193 |
194 | } catch (InterruptedException e) {
195 |
196 | stdout.println("Thread interrupted");
197 | }
198 | }
199 |
200 | stdout.println("Thread ended.");
201 | }
202 | }
203 |
--------------------------------------------------------------------------------
/src/main/java/burp/BurpExtender.java:
--------------------------------------------------------------------------------
1 | /*****************************************************************************
2 | * BurpExtender.java part of AttackSelector Burp Plugin *
3 | * *
4 | * Copyright (c) 2017, Agazzini Maurizio - inode@mediaservice.net *
5 | * All rights reserved. *
6 | * *
7 | * Redistribution and use in source and binary forms, with or without *
8 | * modification, are permitted provided that the following conditions *
9 | * are met: *
10 | * * Redistributions of source code must retain the above copyright *
11 | * notice, this list of conditions and the following disclaimer. *
12 | * * Redistributions in binary form must reproduce the above copyright *
13 | * notice, this list of conditions and the following disclaimer in *
14 | * the documentation and/or other materials provided with the *
15 | * distribution. *
16 | * * Neither the name of @ Mediaservice.net nor the names of its *
17 | * contributors may be used to endorse or promote products derived *
18 | * from this software without specific prior written permission. *
19 | * *
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *
22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR *
23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT *
24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *
25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED *
26 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
27 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
28 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
29 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
30 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
31 | *****************************************************************************/
32 |
33 | package burp;
34 |
35 | import java.awt.event.ActionEvent;
36 | import java.awt.event.ActionListener;
37 | import java.io.PrintWriter;
38 | import java.lang.reflect.InvocationTargetException;
39 | import java.util.ArrayList;
40 | import java.util.Iterator;
41 | import java.util.List;
42 | import java.util.concurrent.locks.ReentrantLock;
43 | import javax.swing.JPanel;
44 | import javax.swing.SwingUtilities;
45 | import javax.swing.JMenuItem;
46 | import org.json.JSONObject;
47 |
48 | import java.awt.Component;
49 | import javax.swing.JMenu;
50 | import javax.swing.JCheckBox;
51 | import javax.swing.JComboBox;
52 |
53 | public class BurpExtender implements IBurpExtender, IContextMenuFactory, ActionListener, ITab, IExtensionStateListener {
54 |
55 | private IBurpExtenderCallbacks callbacks;
56 | private IExtensionHelpers helpers;
57 |
58 | private PrintWriter stdout;
59 | private PrintWriter stderr;
60 |
61 | IHttpRequestResponse[] selectedMessage;
62 | static char insertionPointChar;
63 |
64 | PluginGUI pluginGUI;
65 |
66 | JPanel configurationPanel;
67 |
68 | // JTable lists
69 | private List ConfigurationList;
70 | private List queueList;
71 | private PluginQueueTableModel queueModel;
72 | private ConfigurationTableModel configurationModel;
73 |
74 | // Threads objects
75 | private ReentrantLock lock;
76 | private Thread running_thread;
77 | private ScannerThread scannerThread = null;
78 |
79 | // Default burp configuration
80 | String json_configuration = new String(
81 | "{\"scanner\":{ \"active_scanning_areas\":{ \"csrf\":true, \"link_manipulation\":true, \"external_interaction\":true, \"file_path_traversal\":true, \"header_manipulation\":true, \"http_header_injection\":true, \"input_retrieval_reflected\":false, \"input_retrieval_stored\":false, \"ldap_injection\":true, \"open_redirection\":true, \"os_command_injection\":{ \"blind_checks\":true, \"enabled\":true, \"informed_checks\":true }, \"reflected_dom_issues\":true, \"reflected_xss\":false, \"server_level_issues\":true, \"server_side_code_injection\":true, \"server_side_template_injection\":true, \"smtp_header_injection\":true, \"sql_injection\":{ \"boolean_condition_checks\":true, \"enabled\":true, \"error_based_checks\":true, \"mssql_checks\":true, \"mysql_checks\":true, \"oracle_checks\":true, \"time_delay_checks\":true }, \"stored_dom_issues\":true, \"stored_xss\":true, \"suspicious_input_transformation\":true, \"xml_soap_injection\":true }, \"active_scanning_optimization\":{ \"intelligent_attack_selection\":true, \"scan_accuracy\":\"normal\", \"scan_speed\":\"normal\" }}}");
82 |
83 | /**
84 | * @wbp.parser.entryPoint
85 | */
86 | @Override
87 | public void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks) {
88 |
89 | // Keep a reference to our callbacks object
90 | this.callbacks = callbacks;
91 |
92 | // Obtain an extension helpers object
93 | helpers = callbacks.getHelpers();
94 |
95 | // Set our extension name
96 | callbacks.setExtensionName("Attack Selector");
97 |
98 | // register to produce options for the context menu
99 | callbacks.registerContextMenuFactory(this);
100 |
101 | callbacks.registerExtensionStateListener(this);
102 |
103 | // Initialize stdout and stderr
104 | stdout = new PrintWriter(callbacks.getStdout(), true);
105 | stderr = new PrintWriter(callbacks.getStderr(), true);
106 |
107 | stdout.println("Plugin loading...");
108 |
109 | ConfigurationList = new ArrayList();
110 | queueList = new ArrayList();
111 |
112 | insertionPointChar = (char) 167;
113 |
114 | lock = new ReentrantLock();
115 |
116 | queueModel = new PluginQueueTableModel(queueList, ConfigurationList, helpers);
117 | configurationModel = new ConfigurationTableModel(ConfigurationList);
118 |
119 | pluginGUI = new PluginGUI(callbacks, helpers, this, queueModel, configurationModel, ConfigurationList,
120 | queueList, stdout, stderr);
121 |
122 | try {
123 | SwingUtilities.invokeAndWait(pluginGUI);
124 | } catch (InvocationTargetException | InterruptedException e) {
125 | e.printStackTrace();
126 | }
127 |
128 | callbacks.customizeUiComponent(pluginGUI.scannerPanel);
129 | callbacks.addSuiteTab(BurpExtender.this);
130 |
131 | // Start queue manager thread
132 | scannerThread = new ScannerThread(this);
133 | running_thread = new Thread(scannerThread);
134 | running_thread.start();
135 |
136 | stdout.println("Attack selector loaded successfully.");
137 |
138 | // Used only for debugging purpose
139 | /*
140 | * String jsonConfig = this.callbacks.saveConfigAsJson(); JSONObject obj
141 | * = new JSONObject(jsonConfig);
142 | * stdout.println(obj.getJSONObject("scanner").toString());
143 | */
144 |
145 | }
146 |
147 | /**
148 | * Save the configuration of the plugin to burp preferences
149 | */
150 | public void save_configuration_to_preferences() {
151 | JSONObject all_conf = new JSONObject();
152 |
153 | for (int i = 0; i < ConfigurationList.size(); i++) {
154 | all_conf.put(Integer.toString(i), ConfigurationList.get(i).exportToJson());
155 | }
156 |
157 | callbacks.saveExtensionSetting("configuration_list", all_conf.toString());
158 |
159 | }
160 |
161 | /**
162 | * Load plugin configuration from burp preferences
163 | */
164 | public void load_configuration_from_preferences() {
165 |
166 | JSONObject all_conf = new JSONObject(callbacks.loadExtensionSetting("configuration_list"));
167 |
168 | Iterator> keys = all_conf.keys();
169 |
170 | while (keys.hasNext()) {
171 | String key = (String) keys.next();
172 |
173 | Configuration row1 = new Configuration();
174 | row1.importFromJson(all_conf.getJSONObject(key).toString());
175 | ConfigurationList.add(row1);
176 |
177 | }
178 |
179 | stdout.println("Configuration loaded.");
180 |
181 | }
182 |
183 | /**
184 | * Create the JSON containings the values from the UI
185 | */
186 | public JSONObject build_json_from_ui() {
187 |
188 | Component[] allComponents = pluginGUI.panel_2.getComponents();
189 | JSONObject obj = new JSONObject(json_configuration);
190 |
191 | // Parse active scanning optimization section
192 | JSONObject active_scanning_optimization = obj.getJSONObject("scanner")
193 | .getJSONObject("active_scanning_optimization");
194 |
195 | for (int i = 0; i < allComponents.length; i++) {
196 | if (allComponents[i].getName() == null)
197 | continue;
198 |
199 | if (allComponents[i].getName().equals("intelligent_attack_selection")) {
200 |
201 | JCheckBox button22 = (JCheckBox) allComponents[i];
202 |
203 | active_scanning_optimization.put("intelligent_attack_selection", button22.isSelected());
204 |
205 | } else if (allComponents[i].getName().equals("scan_accuracy")) {
206 |
207 | JComboBox> pluto = (JComboBox>) allComponents[i];
208 |
209 | switch (pluto.getSelectedIndex()) {
210 | case 0:
211 | active_scanning_optimization.put("scan_accuracy", "minimise_false_negatives");
212 | break;
213 | case 1:
214 | active_scanning_optimization.put("scan_accuracy", "normal");
215 | pluto.setSelectedIndex(1);
216 | break;
217 | case 2:
218 | active_scanning_optimization.put("scan_accuracy", "minimise_false_positives");
219 | pluto.setSelectedIndex(2);
220 | break;
221 | }
222 |
223 | } else if (allComponents[i].getName().equals("scan_speed")) {
224 | JComboBox> pluto = (JComboBox>) allComponents[i];
225 |
226 | switch (pluto.getSelectedIndex()) {
227 | case 0:
228 | active_scanning_optimization.put("scan_speed", "fast");
229 | break;
230 | case 1:
231 | active_scanning_optimization.put("scan_speed", "normal");
232 | break;
233 | case 2:
234 | active_scanning_optimization.put("scan_speed", "thorough");
235 | break;
236 | }
237 |
238 | }
239 | }
240 |
241 | // Parse active scanning areas section
242 | JSONObject attackInsertionPoitnsObject = obj.getJSONObject("scanner").getJSONObject("active_scanning_areas");
243 |
244 | Iterator> keys = attackInsertionPoitnsObject.keys();
245 |
246 | while (keys.hasNext()) {
247 | String key = (String) keys.next();
248 |
249 | if (attackInsertionPoitnsObject.get(key) instanceof JSONObject) {
250 | JSONObject child = (JSONObject) (attackInsertionPoitnsObject.get(key));
251 | Iterator> keys1 = child.keys();
252 | while (keys1.hasNext()) {
253 | String key1 = (String) keys1.next();
254 |
255 | for (int i = 0; i < allComponents.length; i++) {
256 |
257 | if (allComponents[i].getName() == null)
258 | continue;
259 |
260 | if (allComponents[i].getName().equals(key + '+' + key1)) {
261 |
262 | if (allComponents[i] instanceof JCheckBox) {
263 | JCheckBox button22 = (JCheckBox) allComponents[i];
264 | child.put(key1, button22.isSelected());
265 |
266 | }
267 | }
268 | }
269 |
270 | }
271 |
272 | } else {
273 |
274 | for (int i = 0; i < allComponents.length; i++) {
275 |
276 | if (allComponents[i].getName() == null)
277 | continue;
278 |
279 | if (allComponents[i].getName().equals(key)) {
280 |
281 | if (allComponents[i] instanceof JCheckBox) {
282 | JCheckBox button22 = (JCheckBox) allComponents[i];
283 | attackInsertionPoitnsObject.put(key, button22.isSelected());
284 | }
285 | }
286 | }
287 | }
288 | }
289 |
290 | return obj;
291 | }
292 |
293 | /**
294 | * Update UI from a JSON containing the configuration
295 | */
296 | public void update_ui_from_json(String json) {
297 |
298 | Component[] allComponents = pluginGUI.panel_2.getComponents();
299 |
300 | JSONObject obj = new JSONObject(json);
301 |
302 | JSONObject active_scanning_optimization = obj.getJSONObject("scanner")
303 | .getJSONObject("active_scanning_optimization");
304 |
305 | for (int i = 0; i < allComponents.length; i++) {
306 | if (allComponents[i].getName() == null)
307 | continue;
308 |
309 | if (allComponents[i].getName().equals("intelligent_attack_selection")) {
310 |
311 | JCheckBox button22 = (JCheckBox) allComponents[i];
312 | button22.setSelected((boolean) active_scanning_optimization.get("intelligent_attack_selection"));
313 |
314 | } else if (allComponents[i].getName().equals("scan_accuracy")) {
315 |
316 | JComboBox> pluto = (JComboBox>) allComponents[i];
317 |
318 | switch (active_scanning_optimization.get("scan_accuracy").toString()) {
319 | case "minimise_false_negatives":
320 | pluto.setSelectedIndex(0);
321 | break;
322 | case "normal":
323 | pluto.setSelectedIndex(1);
324 | break;
325 | case "minimise_false_positives":
326 | pluto.setSelectedIndex(2);
327 | break;
328 | }
329 |
330 | } else if (allComponents[i].getName().equals("scan_speed")) {
331 | JComboBox> pluto = (JComboBox>) allComponents[i];
332 |
333 | switch (active_scanning_optimization.get("scan_speed").toString()) {
334 | case "fast":
335 | pluto.setSelectedIndex(0);
336 | break;
337 | case "normal":
338 | pluto.setSelectedIndex(1);
339 | break;
340 | case "thorough":
341 | pluto.setSelectedIndex(2);
342 | break;
343 | }
344 |
345 | }
346 | }
347 |
348 | JSONObject attackInsertionPoitnsObject = obj.getJSONObject("scanner").getJSONObject("active_scanning_areas");
349 |
350 | Iterator> keys = attackInsertionPoitnsObject.keys();
351 |
352 | while (keys.hasNext()) {
353 | String key = (String) keys.next();
354 |
355 | if (attackInsertionPoitnsObject.get(key) instanceof JSONObject) {
356 | JSONObject child = (JSONObject) (attackInsertionPoitnsObject.get(key));
357 | Iterator> keys1 = child.keys();
358 | while (keys1.hasNext()) {
359 | String key1 = (String) keys1.next();
360 |
361 | for (int i = 0; i < allComponents.length; i++) {
362 |
363 | if (allComponents[i].getName() == null)
364 | continue;
365 |
366 | if (allComponents[i].getName().equals(key + '+' + key1)) {
367 | if (allComponents[i] instanceof JCheckBox) {
368 | JCheckBox button22 = (JCheckBox) allComponents[i];
369 | button22.setSelected((boolean) child.get(key1));
370 | }
371 | }
372 | }
373 |
374 | }
375 |
376 | } else {
377 |
378 | for (int i = 0; i < allComponents.length; i++) {
379 |
380 | if (allComponents[i].getName() == null)
381 | continue;
382 |
383 | if (allComponents[i].getName().equals(key)) {
384 | if (allComponents[i] instanceof JCheckBox) {
385 | JCheckBox button22 = (JCheckBox) allComponents[i];
386 | button22.setSelected((boolean) attackInsertionPoitnsObject.get(key));
387 | }
388 | }
389 | }
390 | }
391 | }
392 |
393 | }
394 |
395 | @Override
396 | public List createMenuItems(IContextMenuInvocation invocation) {
397 |
398 | // Add custom content menu
399 | if (invocation.getInvocationContext() == IContextMenuInvocation.CONTEXT_MESSAGE_EDITOR_REQUEST
400 | || invocation.getInvocationContext() == IContextMenuInvocation.CONTEXT_MESSAGE_VIEWER_REQUEST
401 | || invocation.getInvocationContext() == IContextMenuInvocation.CONTEXT_INTRUDER_PAYLOAD_POSITIONS
402 | || invocation.getInvocationContext() == IContextMenuInvocation.CONTEXT_PROXY_HISTORY) {
403 |
404 | selectedMessage = invocation.getSelectedMessages();
405 |
406 | List menu = new ArrayList();
407 |
408 | JMenu main_menu = new JMenu("Attack selector");
409 |
410 | for (int i = 0; i < ConfigurationList.size(); i++) {
411 | if (ConfigurationList.get(i).getEnabled() == true) {
412 | JMenuItem men_item = new JMenuItem(ConfigurationList.get(i).getName());
413 |
414 | men_item.setActionCommand(Integer.toString(i + 1000));
415 | men_item.addActionListener(this);
416 |
417 | main_menu.add(men_item);
418 | }
419 | }
420 |
421 | menu.add(main_menu);
422 |
423 | return menu;
424 |
425 | } else {
426 |
427 | return null;
428 | }
429 |
430 | }
431 |
432 | /**
433 | * Update burp scanner configuration with our needed option
434 | *
435 | * @param configurationIndex
436 | */
437 | public void updateScannerConfig(int configurationIndex) {
438 |
439 | // Read Burp config
440 | String jsonConfig = callbacks.saveConfigAsJson();
441 |
442 | // Parse Burp config and update the value of scanner parameters
443 | JSONObject obj = new JSONObject(jsonConfig);
444 |
445 | JSONObject current_config = obj.getJSONObject("scanner");
446 |
447 | // Update the configuration with our options
448 | current_config.put("active_scanning_areas", ConfigurationList.get(configurationIndex).exportToJson()
449 | .getJSONObject("configuration").getJSONObject("scanner").getJSONObject("active_scanning_areas"));
450 | current_config.put("active_scanning_optimization", ConfigurationList.get(configurationIndex).exportToJson()
451 | .getJSONObject("configuration").getJSONObject("scanner").getJSONObject("active_scanning_optimization"));
452 |
453 | // Load updated config
454 | callbacks.loadConfigFromJson(obj.toString());
455 |
456 | }
457 |
458 | /**
459 | * Add to burp active scan by Federico Dotta
460 | *
461 | * @param message
462 | * @param intruder
463 | * @return
464 | */
465 | public IScanQueueItem scanVuln(IHttpRequestResponse message, boolean intruder) {
466 |
467 | IScanQueueItem ret;
468 |
469 | String requestString = new String(message.getRequest());
470 |
471 | List insertionPointCoupledIndexes = new ArrayList();
472 | int[] currentCouple = new int[2];
473 |
474 | if (intruder == true) {
475 | boolean first = true;
476 | int currentIndex = requestString.indexOf(insertionPointChar);
477 | if (currentIndex != -1) {
478 | currentCouple[0] = currentIndex;
479 | requestString = deleteCharAt(requestString, currentIndex);
480 | first = false;
481 | }
482 | while (currentIndex >= 0) {
483 | currentIndex = requestString.indexOf(insertionPointChar);
484 | if (currentIndex != -1 && first) {
485 | requestString = deleteCharAt(requestString, currentIndex);
486 | currentCouple[0] = currentIndex;
487 | first = false;
488 | } else if (currentIndex != -1 && !first) {
489 | requestString = deleteCharAt(requestString, currentIndex);
490 | currentCouple[1] = currentIndex - 1;
491 | first = true;
492 | insertionPointCoupledIndexes.add(currentCouple);
493 | currentCouple = new int[2];
494 | }
495 |
496 | }
497 | }
498 |
499 | if (intruder == true && insertionPointCoupledIndexes.size() > 0) {
500 |
501 | // Do active scan on selected insertion points
502 | ret = callbacks.doActiveScan(message.getHttpService().getHost(), message.getHttpService().getPort(),
503 | (message.getHttpService().getProtocol().equals("http") ? false : true), requestString.getBytes(),
504 | insertionPointCoupledIndexes);
505 |
506 | } else {
507 |
508 | // Do active scan on every insertion points
509 | ret = callbacks.doActiveScan(message.getHttpService().getHost(), message.getHttpService().getPort(),
510 | (message.getHttpService().getProtocol().equals("http") ? false : true), requestString.getBytes());
511 |
512 | }
513 |
514 | return ret;
515 |
516 | }
517 |
518 | public static String deleteCharAt(String s, int index) {
519 |
520 | StringBuilder sb = new StringBuilder(s);
521 | sb.deleteCharAt(index);
522 | return sb.toString();
523 |
524 | }
525 |
526 | @Override
527 | public void actionPerformed(ActionEvent event) {
528 |
529 | String command = event.getActionCommand();
530 |
531 | PluginQueue obj = new PluginQueue();
532 | obj.setMessage(selectedMessage[0]);
533 |
534 | obj.setQueueNumber(queueList.size());
535 | obj.setStatus(0);
536 |
537 | if (Integer.parseInt(command) >= 1000) {
538 | obj.setConfiguration(Integer.parseInt(command) - 1000);
539 | obj.setIntruder(false);
540 | } else {
541 | obj.setConfiguration(Integer.parseInt(command));
542 | obj.setIntruder(true);
543 | }
544 |
545 | lock.lock();
546 | try {
547 | queueList.add(obj);
548 | } finally {
549 | lock.unlock();
550 | }
551 |
552 | javax.swing.SwingUtilities.invokeLater(new Runnable() {
553 | public void run() {
554 | pluginGUI.update_scanner_table("insert", queueList.size() - 1, queueList.size() - 1);
555 | }
556 | });
557 |
558 | }
559 |
560 | public List getqueueList() {
561 | return queueList;
562 | }
563 |
564 | public ReentrantLock getLock() {
565 | return lock;
566 |
567 | }
568 |
569 | public PrintWriter getStdout() {
570 | return stdout;
571 |
572 | }
573 |
574 | public IBurpExtenderCallbacks getCallbacks() {
575 | return callbacks;
576 | }
577 |
578 | /*
579 | * This method return the name of the created tab
580 | */
581 | @Override
582 | public String getTabCaption() {
583 |
584 | return "Attack selector";
585 |
586 | }
587 |
588 | /*
589 | * This method return the panel that will be included in Burp Suite
590 | */
591 | @Override
592 | public Component getUiComponent() {
593 |
594 | return pluginGUI.mainPanel;
595 | }
596 |
597 | @Override
598 | public void extensionUnloaded() {
599 |
600 | // Request to stop the thread in case of extension unload
601 | scannerThread.terminate();
602 |
603 | }
604 | }
605 |
--------------------------------------------------------------------------------
/src/main/java/burp/PluginGUI.java:
--------------------------------------------------------------------------------
1 | /*****************************************************************************
2 | * PluginGUI.java part of AttackSelector Burp Plugin *
3 | * *
4 | * Copyright (c) 2017, Agazzini Maurizio - inode@mediaservice.net *
5 | * All rights reserved. *
6 | * *
7 | * Redistribution and use in source and binary forms, with or without *
8 | * modification, are permitted provided that the following conditions *
9 | * are met: *
10 | * * Redistributions of source code must retain the above copyright *
11 | * notice, this list of conditions and the following disclaimer. *
12 | * * Redistributions in binary form must reproduce the above copyright *
13 | * notice, this list of conditions and the following disclaimer in *
14 | * the documentation and/or other materials provided with the *
15 | * distribution. *
16 | * * Neither the name of @ Mediaservice.net nor the names of its *
17 | * contributors may be used to endorse or promote products derived *
18 | * from this software without specific prior written permission. *
19 | * *
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *
22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR *
23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT *
24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *
25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED *
26 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
27 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
28 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
29 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
30 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
31 | *****************************************************************************/
32 |
33 | package burp;
34 |
35 | import java.awt.BorderLayout;
36 | import java.awt.Color;
37 | import java.awt.Component;
38 | import java.awt.Font;
39 | import java.awt.event.ActionEvent;
40 | import java.awt.event.ActionListener;
41 | import java.awt.event.ItemEvent;
42 | import java.awt.event.ItemListener;
43 | import java.io.File;
44 | import java.io.FileInputStream;
45 | import java.io.FileWriter;
46 | import java.io.IOException;
47 | import java.io.PrintWriter;
48 | import java.util.Iterator;
49 | import java.util.List;
50 |
51 | import javax.swing.GroupLayout;
52 | import javax.swing.GroupLayout.Alignment;
53 | import javax.swing.JButton;
54 | import javax.swing.JCheckBox;
55 | import javax.swing.JComboBox;
56 | import javax.swing.JFileChooser;
57 | import javax.swing.JFrame;
58 | import javax.swing.JLabel;
59 | import javax.swing.JPanel;
60 | import javax.swing.JScrollPane;
61 | import javax.swing.JSplitPane;
62 | import javax.swing.JTabbedPane;
63 | import javax.swing.JTable;
64 | import javax.swing.LayoutStyle.ComponentPlacement;
65 | import javax.swing.ListSelectionModel;
66 | import javax.swing.event.ListSelectionEvent;
67 | import javax.swing.event.ListSelectionListener;
68 |
69 | import org.json.JSONObject;
70 |
71 | /**
72 | * This class create the GUI components of the plugin
73 | *
74 | */
75 | public class PluginGUI implements Runnable, ActionListener, ListSelectionListener, ItemListener {
76 |
77 | JPanel configurationPanel;
78 | private JTable table;
79 | JTabbedPane mainPanel;
80 | private JPanel scan_profiles_panel;
81 | private JButton buttonAdd;
82 | private JButton buttonDelete;
83 | private JScrollPane scrollPane;
84 | private JTable scan_profile_table;
85 | private JPanel active_configurator_panel;
86 | private JLabel lblNewLabel;
87 | private JLabel label_1;
88 | private JLabel label_2;
89 | private JLabel label_3;
90 | private JPanel left_panel;
91 | private JButton buttonCancel;
92 | private JPanel main_panel;
93 | private JSplitPane splitPane;
94 | private JPanel button_panel;
95 | private JButton buttonExport;
96 | private JButton buttonImport;
97 | private JPanel jtable_panel;
98 | private JPanel header_panel;
99 | private JLabel lblNewLabel_1;
100 | private JScrollPane scrollPane_1;
101 | private JCheckBox chckbxNewCheckBox;
102 | private JComboBox