urlOpt = config.getOption(Config.URL);
38 | if(!urlOpt.isPresent()) {
39 | return;
40 | }
41 |
42 | scan(urlOpt.get());
43 |
44 | while(Duration.between(lastActivityTime, Instant.now()).getSeconds() < TIMEOUT) {
45 | pause(500);
46 | }
47 |
48 | report();
49 |
50 | if(!config.hasOption(Config.DO_NOT_SHUTDOWN)) {
51 | callbacks.exitSuite(false);
52 | }
53 | }
54 |
55 | /**
56 | * Pause thread for specified amount of time.
57 | * @param timeout in millis
58 | */
59 | private void pause(long timeout) {
60 | try {
61 | TimeUnit.MILLISECONDS.sleep(timeout);
62 | } catch (InterruptedException e) {}
63 | }
64 |
65 | /**
66 | * Writes report to a file.
67 | */
68 | private void report() {
69 | System.out.println("Generating report...");
70 | IScanIssue[] issues = scannerListener.getIssues();
71 | String format = config.getOption(Config.FORMAT).orElse("");
72 | format = format.toUpperCase();
73 |
74 | if(!format.equals(FORMAT_HTML) && !format.equals(FORMAT_XML)) {
75 | format = FORMAT_HTML;
76 | }
77 |
78 | // default filename
79 | String filename = String.format("%d_burp_report.%s", System.currentTimeMillis(), format.toLowerCase());
80 | filename = config.getOption(Config.REPORT).orElse(filename);
81 |
82 | callbacks.generateScanReport(format, issues, new File(filename));
83 | }
84 |
85 | /**
86 | * Creates config instance.
87 | */
88 | private void createConfig() {
89 | try {
90 | config = new Config(callbacks.getCommandLineArguments());
91 | } catch (ParseException e) {
92 | System.err.println(e.getMessage());
93 | config.printHelp();
94 | callbacks.exitSuite(false);
95 | }
96 | }
97 |
98 | /**
99 | * Choose appropriate scanning method and starts it.
100 | * @param url
101 | */
102 | private void scan(String url) {
103 | try {
104 | URL startURL = new URL(url);
105 |
106 | // if no spider just scan provided url
107 | callbacks.registerScannerListener(scannerListener);
108 | if(config.hasOption(Config.NO_SPIDER)) {
109 | doScan(startURL);
110 | } else {
111 | callbacks.registerHttpListener(this);
112 | doSpider(startURL);
113 | }
114 | } catch (MalformedURLException e) {
115 | System.err.println("Provided Url is invalid.");
116 | System.err.println(e.getMessage());
117 | callbacks.exitSuite(false);
118 | }
119 | }
120 |
121 | /**
122 | * Make passive or active scan based on {@link #scanType}.
123 | * @param url
124 | */
125 | private void doScan(URL url) {
126 | System.out.println("Scanning URL: " + url);
127 | String host = url.getHost();
128 | int port = url.getPort() > 0 ? url.getPort() : 80;
129 | String protocol = url.getProtocol();
130 | byte[] request = helpers.buildHttpRequest(url);
131 | doScan(host, port, protocol, request, null);
132 | }
133 |
134 | /**
135 | * Make passive or active scan based on {@link #scanType}
136 | * @param host
137 | * @param port
138 | * @param protocol
139 | * @param request
140 | * @param response
141 | */
142 | private void doScan(String host, int port, String protocol, byte[] request, byte[] response) {
143 | boolean isHttps = protocol.equalsIgnoreCase("https");
144 | if(config.hasOption(Config.ACTIVE)) {
145 | doActiveScan(host, port, isHttps, request);
146 | } else {
147 | doPassiveScan(host, port, isHttps, request, response);
148 | }
149 | }
150 |
151 | /**
152 | * Performs active scan
153 | * @param host
154 | * @param port
155 | * @param isHttps
156 | * @param request
157 | */
158 | private void doActiveScan(String host, int port, boolean isHttps, byte[] request) {
159 | callbacks.doActiveScan(host, port, isHttps, request);
160 | }
161 |
162 | /**
163 | * Performs passive scan
164 | * @param host
165 | * @param port
166 | * @param isHttps
167 | * @param request
168 | * @param response
169 | */
170 | private void doPassiveScan(String host, int port, boolean isHttps, byte[] request, byte[] response) {
171 | if(response == null) {
172 | response = callbacks.makeHttpRequest(host, port, isHttps, request);
173 | }
174 | callbacks.doPassiveScan(host, port, isHttps, request, response);
175 | }
176 |
177 | /**
178 | * Spider site using given url as a starting point.
179 | * @param url
180 | */
181 | private void doSpider(URL url) {
182 | if(!callbacks.isInScope(url)) {
183 | callbacks.includeInScope(getBaseUrl(url));
184 | }
185 | callbacks.sendToSpider(url);
186 | }
187 |
188 | /**
189 | * Strip path out of url, so for example for given URL:
190 | * http://example.com/this/is/the/example
191 | * it will return
192 | * http://example.com/
193 | *
194 | * @param url
195 | * @return
196 | */
197 | private URL getBaseUrl(URL url){
198 | try {
199 | return new URL(url, "/");
200 | } catch (MalformedURLException e) {
201 | // will not happen
202 | }
203 | return url;
204 | }
205 |
206 | /**
207 | * {@inheritDoc}
208 | *
209 | *
210 | * This implementation sends urls found by spider to scanner.
211 | *
212 | */
213 | public void processHttpMessage(int toolFlag, boolean messageIsRequest, IHttpRequestResponse messageInfo) {
214 | lastActivityTime = Instant.now();
215 | if(toolFlag == IBurpExtenderCallbacks.TOOL_SPIDER && !messageIsRequest) {
216 | String host = messageInfo.getHttpService().getHost();
217 | int port = messageInfo.getHttpService().getPort();
218 | String protocol = messageInfo.getHttpService().getProtocol();
219 | doScan(host, port, protocol, messageInfo.getRequest(), messageInfo.getResponse());
220 | }
221 | }
222 |
223 | }
224 |
--------------------------------------------------------------------------------
/src/main/java/burp/Config.java:
--------------------------------------------------------------------------------
1 | package burp;
2 |
3 | import java.util.Optional;
4 |
5 | import org.apache.commons.cli.CommandLine;
6 | import org.apache.commons.cli.CommandLineParser;
7 | import org.apache.commons.cli.DefaultParser;
8 | import org.apache.commons.cli.HelpFormatter;
9 | import org.apache.commons.cli.Options;
10 | import org.apache.commons.cli.ParseException;
11 |
12 | public final class Config {
13 |
14 | public static final String URL = "url";
15 | public static final String ACTIVE = "active";
16 | public static final String PASSIVE = "passive";
17 | public static final String NO_SPIDER = "no-spider";
18 | public static final String DO_NOT_SHUTDOWN = "do-not-shutdown";
19 | public static final String FORMAT = "format";
20 | public static final String REPORT = "report";
21 |
22 | private Options opts;
23 | private HelpFormatter formatter = new HelpFormatter();
24 |
25 | /**
26 | * Stores options provided as command line arguments
27 | */
28 | private CommandLine cmd;
29 |
30 | /**
31 | * Creates new config based on commandLineArguments
32 | * @param commandLineArguments
33 | * @throws ParseException
34 | */
35 | public Config(String[] commandLineArguments) throws ParseException {
36 | opts = createOptions();
37 | cmd = doParseArgs(opts, commandLineArguments);
38 | }
39 |
40 | /**
41 | * Returns true if requested option was set and false otherwise.
42 | * @param option
43 | * @return
44 | */
45 | public boolean hasOption(String option) {
46 | return cmd.hasOption(option);
47 | }
48 |
49 | /**
50 | * Returns value of requested option.
51 | * @param option
52 | * @return
53 | */
54 | public Optional getOption(String option) {
55 | return Optional.ofNullable(cmd.getOptionValue(option));
56 | }
57 |
58 | /**
59 | * Prints help message.
60 | */
61 | public void printHelp() {
62 | formatter.printHelp("java -jar ", opts);
63 | }
64 |
65 | /**
66 | * Parsing arguments using predefined options.
67 | * @param opts
68 | * @param commandLineArguments
69 | * @return
70 | * @throws ParseException
71 | */
72 | private CommandLine doParseArgs(Options opts, String[] commandLineArguments) throws ParseException {
73 | CommandLineParser parser = new DefaultParser();
74 | return parser.parse(opts, commandLineArguments);
75 | }
76 |
77 | /**
78 | * Creates command line options.
79 | * @return
80 | */
81 | private Options createOptions() {
82 | Options opts = new Options();
83 | opts.addOption("u", URL, true, "Starting point for spider and / or scanning.");
84 | opts.addOption("a", ACTIVE, false, "Run active scan against target. Take precedence over passive.");
85 | opts.addOption("p", PASSIVE, false, "Run passive scan against target. This is default.");
86 | opts.addOption("s", NO_SPIDER, false, "Disables spidering so only scan for provided URL will be made.");
87 | opts.addOption("k", DO_NOT_SHUTDOWN, false, "Disables shutting down at the end of execution");
88 | opts.addOption("f", FORMAT, true, "Format of report. Available values are HTML and XML.");
89 | opts.addOption("r", REPORT, true, "Path where report should be stored.");
90 | return opts;
91 | }
92 |
93 | }
94 |
--------------------------------------------------------------------------------
/src/main/java/burp/ScannerListenerImpl.java:
--------------------------------------------------------------------------------
1 | package burp;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | public class ScannerListenerImpl implements IScannerListener {
7 |
8 | List issues = new ArrayList<>();
9 |
10 | public void newScanIssue(IScanIssue issue) {
11 | issues.add(issue);
12 | }
13 |
14 | public IScanIssue[] getIssues() {
15 | return issues.toArray(new IScanIssue[0]);
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------