diff --git a/.gitignore b/.gitignore index a79f4b2..0c507b6 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,4 @@ /.idea /burp-vulners-scanner.iml /target/ -!/target/burp-vulners-scanner-1.1.jar +!/target/burp-vulners-scanner-1.2.jar diff --git a/pom.xml b/pom.xml index 5d3cb89..f3bf2ac 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ burp-vulners-scanner burp-vulners-scanner - 1.1 + 1.2 UTF-8 @@ -22,16 +22,10 @@ - - org.codehaus.jackson - jackson-mapper-asl - 1.9.13 - - com.codemagi burp-suite-utils - 1.0.8 + LATEST @@ -40,17 +34,16 @@ 7.0.3 - - com.mashape.unirest - unirest-java - 1.4.9 - - org.jtwig jtwig-core 5.85.3.RELEASE + + org.json + json + 20160810 + @@ -77,8 +70,8 @@ org.apache.maven.plugins maven-compiler-plugin - 1.7 - 1.7 + 8 + 8 diff --git a/src/main/java/burp/BurpExtender.java b/src/main/java/burp/BurpExtender.java index f75d3e0..6d58edb 100644 --- a/src/main/java/burp/BurpExtender.java +++ b/src/main/java/burp/BurpExtender.java @@ -7,12 +7,17 @@ import com.codemagi.burp.ScannerMatch; import com.monikamorrow.burp.BurpSuiteTab; +import java.io.IOException; import java.net.URL; import java.util.*; +import java.util.regex.Pattern; public class BurpExtender extends PassiveScan { + public static String SETTING_API_KEY_NAME = "SETTING_API_KEY_NAME"; + + private String apiKey = ""; private TabComponent tabComponent; private VulnersService vulnersService; private Map domains = new HashMap<>(); @@ -28,8 +33,15 @@ protected void initPassiveScan() { mTab.addComponent(tabComponent.getRootPanel()); + apiKey = callbacks.loadExtensionSetting(SETTING_API_KEY_NAME); + tabComponent.setAPIKey(apiKey); + vulnersService = new VulnersService(this, callbacks, helpers, domains, tabComponent); - vulnersService.loadRules(); + try { + vulnersService.loadRules(); + } catch (IOException e) { + callbacks.printError("[Vulners]" + e.getMessage()); + } } @Override @@ -69,8 +81,6 @@ protected List processIssues(List matches, IHttpReques String domainName = helpers.analyzeRequest(baseRequestResponse).getUrl().getHost(); List startStop = new ArrayList<>(1); - callbacks.printOutput("[Vulners] Processing issues for: " + domainName); - //get the existing matches for this domain Domain domain = domains.get(domainName); @@ -79,11 +89,23 @@ protected List processIssues(List matches, IHttpReques } Collections.sort(matches); //matches must be in order + ScannerMatch lastMatch = null; for (ScannerMatch match : matches) { + + // do not continue if software wal already found before if (domain.getSoftware().get(match.getType() + match.getMatchGroup()) != null) { continue; } + // Ignore matches that overlapped previous positions. Usually it's the similar rule match + if (lastMatch !=null && (lastMatch.getStart() >= match.getStart() || lastMatch.getEnd() >= match.getEnd())) { + callbacks.printError("[Vulners] Ignore overlapped rule " + domainName + " new issue " + match.getFullMatch()); + continue; + } + lastMatch = match; + + callbacks.printOutput("[Vulners] Processing domain " + domainName + " new issue " + match.getFullMatch()); + Software software = new Software( match.getType() + match.getMatchGroup(), match.getType(), @@ -118,4 +140,21 @@ public VulnersService getVulnersService() { Map> getMatchRules() { return matchRules; } + + public String getApiKey() { + return apiKey; + } + + public void setApiKey(String apiKey) { + apiKey = apiKey.trim(); + Pattern pattern = Pattern.compile("[A-Z0-9]{0,128}"); + + if (pattern.matcher(apiKey).matches()) { + callbacks.printOutput("[Vulners] Set API key " + apiKey); + callbacks.saveExtensionSetting(SETTING_API_KEY_NAME, apiKey); + this.apiKey = apiKey; + } else { + callbacks.printError("[Vulners] Wrong api key provided, should match /[A-Z0-9]{64}/ " + apiKey); + } + } } \ No newline at end of file diff --git a/src/main/java/burp/HttpClient.java b/src/main/java/burp/HttpClient.java index e1570fe..509fd51 100644 --- a/src/main/java/burp/HttpClient.java +++ b/src/main/java/burp/HttpClient.java @@ -1,54 +1,68 @@ package burp; -import com.mashape.unirest.http.Unirest; -import org.apache.http.HttpHost; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.conn.ssl.TrustSelfSignedStrategy; -import org.apache.http.conn.ssl.TrustStrategy; -import org.apache.http.impl.client.BasicCookieStore; -import org.apache.http.impl.nio.client.CloseableHttpAsyncClient; -import org.apache.http.impl.nio.client.HttpAsyncClientBuilder; -import org.apache.http.impl.nio.client.HttpAsyncClients; -import org.apache.http.ssl.SSLContexts; - -import javax.net.ssl.SSLContext; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; - -class HttpClient { - - public static CloseableHttpAsyncClient createSSLClient() { - return createSSLClient(null); +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class HttpClient { + + private static String VULNERS_API_HOST = "vulners.com"; + private static String VULNERS_API_PATH = "/api/v3/burp/"; + + private final IBurpExtenderCallbacks callbacks; + private final IExtensionHelpers helpers; + private final BurpExtender burpExtender; + + HttpClient(IBurpExtenderCallbacks callbacks, IExtensionHelpers helpers, BurpExtender burpExtender) { + this.burpExtender = burpExtender; + this.callbacks = callbacks; + this.helpers = helpers; } - public static CloseableHttpAsyncClient createSSLClient(HttpHost proxy) { - TrustStrategy acceptingTrustStrategy = new TrustStrategy() { + public JSONObject get(String action, Map params) { + List headers = new ArrayList<>(); + headers.add("POST " + VULNERS_API_PATH + action + "/ HTTP/1.1"); + headers.add("Host: " + VULNERS_API_HOST); + headers.add("User-Agent: vulners-burpscanner-v-1.2"); + headers.add("Content-type: application/json"); - @Override - public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { - return true; - } - }; + JSONObject jsonBody = new JSONObject(); - try { - SSLContext sslContext = SSLContexts.custom() - .loadTrustMaterial(null, acceptingTrustStrategy) - .build(); + if (burpExtender.getApiKey() != null) { + jsonBody = jsonBody.put("apiKey", burpExtender.getApiKey()); + } - HttpAsyncClientBuilder client = HttpAsyncClients.custom() - .setDefaultCookieStore(new BasicCookieStore()) - .setSSLContext(sslContext) - .setSSLHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); + for (Map.Entry p: params.entrySet()) { + jsonBody = jsonBody.put(p.getKey(), p.getValue()); + } - if (proxy !=null) { - client.setProxy(proxy); - } + byte[] request = helpers.buildHttpMessage(headers, helpers.stringToBytes(jsonBody.toString())); + byte[] response = callbacks.makeHttpRequest(VULNERS_API_HOST, 443, true, request); + return parseResponse(response); + } + + private JSONObject parseResponse(byte[] response) { + String responseString = helpers.bytesToString(response); + IResponseInfo iResponseInfo = helpers.analyzeResponse(response); + String jsonString = responseString.substring(iResponseInfo.getBodyOffset()); + + JSONObject object = new JSONObject(jsonString); - return client.build(); + try { + if (object.getString("result").equals("OK")) { + return object.getJSONObject("data"); + } else { + callbacks.printOutput("[DEBUG] not OK"); + callbacks.printOutput(jsonString); + return object; + } } catch (Exception e) { - System.out.println("Could not create SSLContext"); - return null; + callbacks.printError("[ERROR]"); + callbacks.printError(jsonString); + return object; } - } + } diff --git a/src/main/java/burp/PathIssue.java b/src/main/java/burp/PathIssue.java index b342857..a902a7a 100644 --- a/src/main/java/burp/PathIssue.java +++ b/src/main/java/burp/PathIssue.java @@ -1,6 +1,5 @@ package burp; -import burp.models.Software; import burp.models.Vulnerability; import com.codemagi.burp.ScanIssueConfidence; import com.codemagi.burp.ScanIssueSeverity; @@ -10,7 +9,6 @@ import java.net.URL; import java.util.Collection; -import java.util.List; import java.util.Set; public class PathIssue implements IScanIssue { @@ -22,7 +20,7 @@ public class PathIssue implements IScanIssue { private final String path; private final Set vulnerabilities; - public PathIssue(IHttpRequestResponse baseRequestResponse, IExtensionHelpers helpers, IBurpExtenderCallbacks callbacks, String path, Set vulnerabilities) { + PathIssue(IHttpRequestResponse baseRequestResponse, IExtensionHelpers helpers, IBurpExtenderCallbacks callbacks, String path, Set vulnerabilities) { this.baseRequestResponse = baseRequestResponse; this.helpers = helpers; this.callbacks = callbacks; diff --git a/src/main/java/burp/SoftwareIssue.java b/src/main/java/burp/SoftwareIssue.java index 75739d7..68939de 100644 --- a/src/main/java/burp/SoftwareIssue.java +++ b/src/main/java/burp/SoftwareIssue.java @@ -5,13 +5,8 @@ import com.codemagi.burp.ScanIssueConfidence; import com.codemagi.burp.ScanIssueSeverity; import com.google.common.base.Function; -import com.google.common.base.Predicates; import com.google.common.collect.Collections2; import com.google.common.collect.Ordering; -import org.jtwig.environment.DefaultEnvironmentConfiguration; -import org.jtwig.environment.Environment; -import org.jtwig.environment.EnvironmentConfiguration; -import org.jtwig.environment.EnvironmentFactory; import java.net.URL; import java.util.Collection; @@ -23,8 +18,8 @@ public class SoftwareIssue implements IScanIssue { private final IExtensionHelpers helpers; private final IBurpExtenderCallbacks callbacks; private final List startStop; - private final Software software; - private final Environment environment; + + private Software software; SoftwareIssue(IHttpRequestResponse baseRequestResponse, IExtensionHelpers helpers, IBurpExtenderCallbacks callbacks, List startStop, Software software) { this.baseRequestResponse = baseRequestResponse; @@ -33,11 +28,6 @@ public class SoftwareIssue implements IScanIssue { this.startStop = startStop; this.software = software; - - // Environment - EnvironmentConfiguration configuration = new DefaultEnvironmentConfiguration(); - EnvironmentFactory environmentFactory = new EnvironmentFactory(); - this.environment = environmentFactory.create(configuration); } @Override @@ -132,17 +122,21 @@ public int getIssueType() { @Override public String getRemediationDetail() { - return null; + return ""; } @Override public String getIssueBackground() { - return null; + return ""; } @Override public String getRemediationBackground() { - return null; + return ""; + } + + public void setSoftware(Software software) { + this.software = software; } private boolean hasVulnerabilities() { diff --git a/src/main/java/burp/Utils.java b/src/main/java/burp/Utils.java index 8b90ab4..3e64cd0 100644 --- a/src/main/java/burp/Utils.java +++ b/src/main/java/burp/Utils.java @@ -4,9 +4,11 @@ import com.google.common.base.Function; import com.google.common.collect.Collections2; import com.google.common.collect.Ordering; +import org.json.JSONArray; +import org.json.JSONObject; import java.util.Collection; -import java.util.List; +import java.util.HashSet; import java.util.Set; /** @@ -44,4 +46,21 @@ public String apply(Vulnerability vulnerability) { } ); } + + + public static Set getVulnerabilities(JSONObject data) { + Set vulnerabilities = new HashSet<>(); + + if (!data.has("search")) { + return vulnerabilities; + } + + JSONArray bulletins = data.getJSONArray("search"); + for (Object bulletin : bulletins) { + vulnerabilities.add( + new Vulnerability(((JSONObject) bulletin).getJSONObject("_source")) + ); + } + return vulnerabilities; + } } diff --git a/src/main/java/burp/VulnersRestCallback.java b/src/main/java/burp/VulnersRestCallback.java deleted file mode 100644 index 2cee2bd..0000000 --- a/src/main/java/burp/VulnersRestCallback.java +++ /dev/null @@ -1,69 +0,0 @@ -package burp; - - -import burp.models.Vulnerability; -import com.mashape.unirest.http.HttpResponse; -import com.mashape.unirest.http.JsonNode; -import com.mashape.unirest.http.async.Callback; -import com.mashape.unirest.http.exceptions.UnirestException; -import org.json.JSONArray; -import org.json.JSONObject; - -import java.util.HashSet; -import java.util.Set; - -abstract class VulnersRestCallback implements Callback { - - - private IBurpExtenderCallbacks callbacks; - - VulnersRestCallback(IBurpExtenderCallbacks callbacks) { - this.callbacks = callbacks; - } - - /** - * Rise with response of success returned list of vulnerabilities - * @param vulnerabilities List of returned vulnerabilities - */ - public void onScannerSuccess(Set vulnerabilities) { - - }; - - public void onSuccess(JSONObject data) { - JSONArray bulletins = data.getJSONArray("search"); - - Set vulnerabilities = new HashSet<>(); - for (Object bulletin : bulletins) { - vulnerabilities.add( - new Vulnerability(((JSONObject) bulletin).getJSONObject("_source")) - ); - } - - onScannerSuccess(vulnerabilities); - } - - /** - * Rise on error returned or no vulnerabilities found - */ - public void onFail(JSONObject responseData) { - callbacks.printError(responseData.getString("error")); - }; - - public void completed(HttpResponse response) { - JSONObject responseBody = response.getBody().getObject(); - - if ("ERROR".equals(responseBody.getString("result"))) { - onFail((JSONObject) responseBody.get("data")); - return; - } - - onSuccess(responseBody.getJSONObject("data")); - } - - public void failed(UnirestException e) { - e.printStackTrace(); - } - - public void cancelled() {} - -} diff --git a/src/main/java/burp/VulnersService.java b/src/main/java/burp/VulnersService.java index cd9d785..a6740f9 100644 --- a/src/main/java/burp/VulnersService.java +++ b/src/main/java/burp/VulnersService.java @@ -5,208 +5,161 @@ import burp.models.Domain; import burp.models.Software; import burp.models.Vulnerability; +import burp.models.VulnersRequest; +import burp.tasks.PathScanTask; +import burp.tasks.SoftwareScanTask; import com.codemagi.burp.MatchRule; import com.codemagi.burp.ScanIssueConfidence; import com.codemagi.burp.ScanIssueSeverity; -import com.google.common.util.concurrent.RateLimiter; -import com.mashape.unirest.http.Unirest; -import com.mashape.unirest.request.HttpRequest; -import org.apache.http.HttpHost; -import org.apache.http.impl.client.BasicCookieStore; -import org.apache.http.impl.nio.client.CloseableHttpAsyncClient; import org.json.JSONObject; import javax.swing.table.DefaultTableModel; +import java.io.IOException; import java.util.*; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; + public class VulnersService { - private static String BURP_API_URL = "https://vulners.com/api/v3/burp/{path}/"; private BurpExtender burpExtender; private final IBurpExtenderCallbacks callbacks; private final IExtensionHelpers helpers; private final TabComponent tabComponent; private Map domains; - private final RateLimiter rateLimiter; - public VulnersService(BurpExtender burpExtender, IBurpExtenderCallbacks callbacks, IExtensionHelpers helpers, Map domains, TabComponent tabComponent) { + private final HttpClient httpClient; + + VulnersService(BurpExtender burpExtender, IBurpExtenderCallbacks callbacks, IExtensionHelpers helpers, Map domains, TabComponent tabComponent) { this.burpExtender = burpExtender; this.callbacks = callbacks; this.helpers = helpers; this.domains = domains; this.tabComponent = tabComponent; - this.rateLimiter = RateLimiter.create(4.0); // Count of max RPS - Unirest.setDefaultHeader("user-agent", "vulners-burpscanner-v-1.1"); - Unirest.setAsyncHttpClient(HttpClient.createSSLClient()); + this.httpClient = new HttpClient(callbacks, helpers, burpExtender); } - /** * Check found software for vulnerabilities using https://vulnes.com/api/v3/burp/software/ - * - * @param domainName - * @param software - * @param baseRequestResponse - * @param startStop */ void checkSoftware(final String domainName, final Software software, final IHttpRequestResponse baseRequestResponse, final List startStop) { - // Limiting requests rate - // TODO make non block MQ - rateLimiter.acquire(); - - final HttpRequest request = Unirest.get(BURP_API_URL) - .routeParam("path", "software") - .queryString("software", software.getAlias()) - .queryString("version", software.getVersion()) - .queryString("type", software.getMatchType()); + SoftwareIssue softwareIssue = new SoftwareIssue( + baseRequestResponse, + helpers, + callbacks, + startStop, + domains.get(domainName).getSoftware().get(software.getKey()) + ); + + // add Information Burp issue + if (software.getVersion() == null) { + callbacks.addScanIssue(softwareIssue); + return; + } - callbacks.printOutput("[Vulners] start check for domain " + domainName + " for software " + software.getName() + "/" + software.getVersion() + " : " + request.getUrl()); + VulnersRequest request = new VulnersRequest(domainName, software, softwareIssue); - request.asJsonAsync(new VulnersRestCallback(callbacks) { + new SoftwareScanTask(request, httpClient, vulnersRequest -> { - @Override - public void onScannerSuccess(Set vulnerabilities) { + Set vulnerabilities = vulnersRequest.getVulnerabilities(); - for (Vulnerability vulnerability : vulnerabilities) { - // update cache - domains.get(domainName) - .getSoftware() - .get(software.getKey()) - .getVulnerabilities() - .add(vulnerability); - } - - // update gui component - tabComponent.getSoftwareTable().refreshTable(domains, tabComponent.getCbxSoftwareShowVuln().isSelected()); - - - // add Burp issue - callbacks.addScanIssue(new SoftwareIssue( - baseRequestResponse, - helpers, - callbacks, - startStop, - domains.get(domainName).getSoftware().get(software.getKey()) - )); + // update cache + for (Vulnerability vulnerability : vulnerabilities) { + domains.get(vulnersRequest.getDomain()) + .getSoftware() + .get(vulnersRequest.getSoftware().getKey()) + .getVulnerabilities() + .add(vulnerability); } - @Override - public void onFail(JSONObject error) { - // update gui component - tabComponent.getSoftwareTable().refreshTable(domains, tabComponent.getCbxSoftwareShowVuln().isSelected()); - - callbacks.addScanIssue(new SoftwareIssue( - baseRequestResponse, - helpers, - callbacks, - startStop, - domains.get(domainName).getSoftware().get(software.getKey()) - )); - } - }); + // update gui component + tabComponent.getSoftwareTable().refreshTable(domains, tabComponent.getCbxSoftwareShowVuln().isSelected()); + + // add Vulnerability Burp issue + vulnersRequest.getSoftwareIssue().setSoftware( + domains.get(vulnersRequest.getDomain()) + .getSoftware() + .get(vulnersRequest.getSoftware().getKey()) + ); + callbacks.addScanIssue(vulnersRequest.getSoftwareIssue()); + }).run(); } /** * Check found software for vulnerabilities using https://vulnes.com/api/v3/burp/path/ - * - * @param domainName - * @param path - * @param baseRequestResponse */ void checkURLPath(final String domainName, final String path, final IHttpRequestResponse baseRequestResponse) { - // Limiting requests rate - // TODO make non block MQ - rateLimiter.acquire(); - - Unirest.get(BURP_API_URL) - .routeParam("path", "path") - .queryString("path", path) - .asJsonAsync(new VulnersRestCallback(callbacks) { - - @Override - public void onScannerSuccess(Set vulnerabilities) { - - // update cache - domains.get(domainName) - .getPaths() - .put(path, vulnerabilities); - - // update gui component - tabComponent.getPathsTable().getDefaultModel().addRow(new Object[]{ - domainName, - path, - Utils.getMaxScore(vulnerabilities), - Utils.getVulnersList(vulnerabilities) - }); - - // add Burp issue - callbacks.addScanIssue(new PathIssue( - baseRequestResponse, - helpers, - callbacks, - path, - vulnerabilities - )); - } - }); + VulnersRequest request = new VulnersRequest(domainName, path, baseRequestResponse); + + new PathScanTask(request, httpClient, vulnersRequest -> { + Set vulnerabilities = vulnersRequest.getVulnerabilities(); + + if (vulnerabilities.isEmpty()) { + return; + } + + // update cache + domains.get(vulnersRequest.getDomain()) + .getPaths() + .put(vulnersRequest.getPath(), vulnerabilities); + + // update gui component + tabComponent.getPathsTable().getDefaultModel().addRow(new Object[]{ + vulnersRequest.getDomain(), + vulnersRequest.getPath(), + Utils.getMaxScore(vulnerabilities), + Utils.getVulnersList(vulnerabilities) + }); + + // add Burp issue + callbacks.addScanIssue(new PathIssue( + vulnersRequest.getBaseRequestResponse(), + helpers, + callbacks, + vulnersRequest.getPath(), + vulnerabilities + )); + }).run(); } /** * Check out rules for matching */ - public void loadRules() { - Unirest.get(BURP_API_URL) - .routeParam("path", "rules") - .asJsonAsync(new VulnersRestCallback(callbacks) { - - @Override - public void onSuccess(JSONObject data) { - JSONObject rules = data.getJSONObject("rules"); - Iterator ruleKeys = rules.keys(); - - DefaultTableModel ruleModel = tabComponent.getRulesTable().getDefaultModel(); - ruleModel.setRowCount(0); //reset table - while (ruleKeys.hasNext()) { - String key = ruleKeys.next(); - final JSONObject v = rules.getJSONObject(key); - - ruleModel.addRow(new Object[]{key, v.getString("regex"), v.getString("alias"), v.getString("type")}); - - try { - Pattern pattern = Pattern.compile(v.getString("regex")); - System.out.println("[NEW] " + pattern); - - burpExtender.getMatchRules().put(key, new HashMap() {{ - put("regex", v.getString("regex")); - put("alias", v.getString("alias")); - put("type", v.getString("type")); - }}); - // Match group 1 - is important - burpExtender.addMatchRule(new MatchRule(pattern, 1, key, ScanIssueSeverity.LOW, ScanIssueConfidence.CERTAIN)); - } catch (PatternSyntaxException pse) { - callbacks.printError("Unable to compile pattern: " + v.getString("regex") + " for: " + key); - burpExtender.printStackTrace(pse); - } - } - - } - }); - } + public void loadRules() throws IOException { + + JSONObject data = httpClient.get("rules", new HashMap()); + + JSONObject rules = data.getJSONObject("rules"); + Iterator ruleKeys = rules.keys(); - public static void buildHttpClient(String host, String port) { - try { - if ("".equals(host) && "".equals(port)) { - Unirest.setAsyncHttpClient(null); - } else { - Unirest.setAsyncHttpClient(HttpClient.createSSLClient(new HttpHost(host, Integer.valueOf(port)))); + DefaultTableModel ruleModel = tabComponent.getRulesTable().getDefaultModel(); + ruleModel.setRowCount(0); //reset table + while (ruleKeys.hasNext()) { + String key = ruleKeys.next(); + final JSONObject v = rules.getJSONObject(key); + + ruleModel.addRow(new Object[]{key, v.getString("regex"), v.getString("alias"), v.getString("type")}); + + try { + Pattern pattern = Pattern.compile(v.getString("regex")); + System.out.println("[NEW] " + pattern); + + burpExtender.getMatchRules().put(key, new HashMap() {{ + put("regex", v.getString("regex")); + put("alias", v.getString("alias")); + put("type", v.getString("type")); + }}); + + // Match group 1 - is important + burpExtender.addMatchRule(new MatchRule(pattern, 1, key, ScanIssueSeverity.LOW, ScanIssueConfidence.CERTAIN)); + } catch (PatternSyntaxException pse) { + callbacks.printError("[Vulners] Unable to compile pattern: " + v.getString("regex") + " for: " + key); + burpExtender.printStackTrace(pse); } - } catch (Exception e) { - System.out.println("[Vulners] can't build HTTP client"); } } + } diff --git a/src/main/java/burp/gui/TabComponent.form b/src/main/java/burp/gui/TabComponent.form index 83fd636..b366f3e 100644 --- a/src/main/java/burp/gui/TabComponent.form +++ b/src/main/java/burp/gui/TabComponent.form @@ -1,7 +1,6 @@
- - + @@ -9,15 +8,13 @@ - - - + - + @@ -25,22 +22,17 @@ - - + + - + - - - - - - + @@ -49,7 +41,7 @@ - + @@ -57,7 +49,7 @@ - + @@ -71,7 +63,7 @@ - + @@ -79,67 +71,156 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + - + + - + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -157,7 +238,9 @@ - + + + @@ -218,7 +301,9 @@ - + + + @@ -232,8 +317,8 @@ - - + + @@ -266,88 +351,14 @@ - - - - - - - - - - - - - - - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/java/burp/gui/TabComponent.java b/src/main/java/burp/gui/TabComponent.java index f5f8726..8414832 100644 --- a/src/main/java/burp/gui/TabComponent.java +++ b/src/main/java/burp/gui/TabComponent.java @@ -1,7 +1,6 @@ package burp.gui; import burp.BurpExtender; -import burp.VulnersService; import burp.IBurpExtenderCallbacks; import burp.gui.path.PathsTable; import burp.gui.rules.RulesTable; @@ -15,11 +14,13 @@ import com.intellij.uiDesigner.core.Spacer; import javax.swing.*; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.io.IOException; +import java.net.URI; import java.util.HashMap; import java.util.Map; import java.util.Set; @@ -42,17 +43,17 @@ public class TabComponent { private JCheckBox cbxSoftwareShowVuln; private JTabbedPane tabbedPane1; private JTextField tbxReqLimit; - private JTextField tbxProxyHost; - private JTextField tbxProxyPort; - private JCheckBox cbxProxyEnabled; private JCheckBox cbxPathScanInScope; + private JTextField txtApi; + private JLabel linkLabel; + private JButton btnApi; private RulesTable rulesTable; private PathsTable pathsTable; private SoftwareTable softwareTable; private final Map domains; - public TabComponent(final BurpExtender burpExtender, IBurpExtenderCallbacks callbacks, final Map domains) { + public TabComponent(final BurpExtender burpExtender, final IBurpExtenderCallbacks callbacks, final Map domains) { this.burpExtender = burpExtender; this.callbacks = callbacks; this.domains = domains; @@ -65,97 +66,48 @@ public TabComponent(final BurpExtender burpExtender, IBurpExtenderCallbacks call final RulesTableListener ruleTableListener = new RulesTableListener(callbacks, this.tblRules, this.rulesTable.getDefaultModel(), burpExtender); this.tblRules.getModel().addTableModelListener(ruleTableListener); - btnRuleAdd.addActionListener(new ActionListener() { - public void actionPerformed(final ActionEvent e) { - new Thread(new Runnable() { - public void run() { - ruleTableListener.onAddButtonClick(e); - } - }).start(); - } - }); - btnRuleRemove.addActionListener(new ActionListener() { - public void actionPerformed(final ActionEvent e) { - new Thread(new Runnable() { - public void run() { - ruleTableListener.onRemoveButtonClick(e); - } - }).start(); - } - }); + btnApi.addActionListener(e -> new Thread(() -> burpExtender.setApiKey(txtApi.getText())).start()); - btnRulesLoad.addActionListener(new ActionListener() { - public void actionPerformed(final ActionEvent e) { - new Thread(new Runnable() { - @Override - public void run() { - burpExtender.getVulnersService().loadRules(); - } - }).start(); - } - }); + btnRuleAdd.addActionListener(e -> new Thread(() -> ruleTableListener.onAddButtonClick(e)).start()); - btnTblPathClear.addActionListener(new ActionListener() { - public void actionPerformed(final ActionEvent e) { - for (Map.Entry d : domains.entrySet()) { - d.getValue().setPaths(new HashMap>()); - } - pathsTable.getDefaultModel().setRowCount(0); - } - }); + btnRuleRemove.addActionListener(e -> new Thread(() -> ruleTableListener.onRemoveButtonClick(e)).start()); - btnTblSoftwareClear.addActionListener(new ActionListener() { - public void actionPerformed(final ActionEvent e) { - for (Map.Entry d : domains.entrySet()) { - d.getValue().setSoftware(new HashMap()); - } - softwareTable.getDefaultModel().setRowCount(0); + btnRulesLoad.addActionListener(e -> new Thread(() -> { + try { + burpExtender.getVulnersService().loadRules(); + } catch (IOException e1) { + callbacks.printError(e1.getMessage()); } - }); + }).start()); - cbxSoftwareShowVuln.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - softwareTable.refreshTable(domains, cbxSoftwareShowVuln.isSelected()); + btnTblPathClear.addActionListener(e -> { + for (Map.Entry d : domains.entrySet()) { + d.getValue().setPaths(new HashMap<>()); } + pathsTable.getDefaultModel().setRowCount(0); }); - tbxProxyHost.getDocument().addDocumentListener(getProxyTextChangeListener()); - tbxProxyPort.getDocument().addDocumentListener(getProxyTextChangeListener()); - cbxProxyEnabled.addActionListener(getProxyChangeListener()); - } - - private ActionListener getProxyChangeListener() { - return new ActionListener() { - public void actionPerformed(ActionEvent e) { - boolean proxyEnabled = cbxProxyEnabled.isSelected(); - VulnersService.buildHttpClient( - proxyEnabled ? tbxProxyHost.getText() : "", - proxyEnabled ? tbxProxyPort.getText() : "" - ); - } - }; - } - - private DocumentListener getProxyTextChangeListener() { - return new DocumentListener() { - @Override - public void insertUpdate(DocumentEvent e) { - changedUpdate(e); + btnTblSoftwareClear.addActionListener(e -> { + for (Map.Entry d : domains.entrySet()) { + d.getValue().setSoftware(new HashMap<>()); } + softwareTable.getDefaultModel().setRowCount(0); + }); - @Override - public void removeUpdate(DocumentEvent e) { - changedUpdate(e); - } + cbxSoftwareShowVuln.addActionListener(e -> softwareTable.refreshTable(domains, cbxSoftwareShowVuln.isSelected())); + linkLabel.addMouseListener(new MouseAdapter() { @Override - public void changedUpdate(DocumentEvent e) { - if (cbxProxyEnabled.isSelected()) { - VulnersService.buildHttpClient(tbxProxyHost.getText(), tbxProxyPort.getText()); + public void mouseClicked(MouseEvent e) { + String vulnersLink = "https://vulners.com/landing#login"; + try { + Desktop.getDesktop().browse(new URI(vulnersLink)); + } catch (Exception e1) { + callbacks.printError("[Vulners] Can not open link, please follow " + vulnersLink + " in your browser"); } } - }; + }); } /** @@ -195,6 +147,12 @@ public RulesTable getRulesTable() { return rulesTable; } + public void setAPIKey(String apiKey) { + if (apiKey != null) { + txtApi.setText(apiKey); + } + } + /** * Method generated by IntelliJ IDEA GUI Designer * >>> IMPORTANT!! <<< @@ -205,140 +163,166 @@ public RulesTable getRulesTable() { private void $$$setupUI$$$() { createUIComponents(); rootPanel = new JPanel(); - rootPanel.setLayout(new GridLayoutManager(5, 19, new Insets(0, 0, 0, 0), -1, -1)); + rootPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5)); tabbedPane1 = new JTabbedPane(); tabbedPane1.setTabPlacement(1); - rootPanel.add(tabbedPane1, new GridConstraints(0, 0, 5, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_VERTICAL, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false)); + rootPanel.add(tabbedPane1); final JPanel panel1 = new JPanel(); - panel1.setLayout(new GridLayoutManager(4, 5, new Insets(0, 0, 0, 0), -1, -1)); + panel1.setLayout(new GridLayoutManager(5, 1, new Insets(0, 0, 0, 0), -1, -1)); tabbedPane1.addTab("Scan rules", panel1); final JPanel panel2 = new JPanel(); - panel2.setLayout(new GridLayoutManager(4, 3, new Insets(0, 0, 0, 0), -1, -1)); - panel1.add(panel2, new GridConstraints(0, 0, 1, 5, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); - final Spacer spacer1 = new Spacer(); - panel2.add(spacer1, new GridConstraints(2, 2, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, 1, null, null, null, 0, false)); + panel2.setLayout(new GridLayoutManager(3, 2, new Insets(10, 0, 0, 0), -1, -1)); + panel1.add(panel2, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); final JLabel label1 = new JLabel(); - label1.setFont(new Font(label1.getFont().getName(), Font.BOLD, 14)); + Font label1Font = this.$$$getFont$$$(null, Font.BOLD, 14, label1.getFont()); + if (label1Font != null) label1.setFont(label1Font); label1.setText("Software vulnerability scanner"); - panel2.add(label1, new GridConstraints(1, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + panel2.add(label1, new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); final JLabel label2 = new JLabel(); label2.setText("Uses vulners.com API to detect vulnerabilities in flagged version of software."); - panel2.add(label2, new GridConstraints(3, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + panel2.add(label2, new GridConstraints(2, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); final JLabel label3 = new JLabel(); - label3.setFont(new Font(label3.getFont().getName(), Font.BOLD, label3.getFont().getSize())); + Font label3Font = this.$$$getFont$$$(null, Font.BOLD, -1, label3.getFont()); + if (label3Font != null) label3.setFont(label3Font); label3.setHorizontalAlignment(2); label3.setIcon(new ImageIcon(getClass().getResource("/logo_small.png"))); label3.setText(""); - panel2.add(label3, new GridConstraints(1, 0, 3, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(-1, 60), new Dimension(-1, 60), 0, false)); + panel2.add(label3, new GridConstraints(0, 0, 3, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(-1, 60), new Dimension(-1, 60), 0, false)); final JLabel label4 = new JLabel(); label4.setText("Match rules use regular expressions to flag software version numbers in server responses. "); - panel2.add(label4, new GridConstraints(2, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + panel2.add(label4, new GridConstraints(1, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + scrlPanel = new JScrollPane(); + panel1.add(scrlPanel, new GridConstraints(3, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false)); + tblRules.setAutoCreateRowSorter(true); + scrlPanel.setViewportView(tblRules); + final JPanel panel3 = new JPanel(); + panel3.setLayout(new GridLayoutManager(3, 4, new Insets(20, 0, 0, 0), -1, -1)); + panel1.add(panel3, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); final JLabel label5 = new JLabel(); - label5.setText("Rules URL"); - panel1.add(label5, new GridConstraints(1, 0, 1, 2, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); - txtRulesURL = new JTextField(); - txtRulesURL.setText("https://vulners.com/api/v3/burp/rules"); - panel1.add(txtRulesURL, new GridConstraints(1, 2, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0, false)); + Font label5Font = this.$$$getFont$$$(null, Font.BOLD, 14, label5.getFont()); + if (label5Font != null) label5.setFont(label5Font); + label5.setText("API Token "); + panel3.add(label5, new GridConstraints(0, 0, 1, 3, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + final JLabel label6 = new JLabel(); + label6.setText("Provide you persanal API token to improve scan speed while using vulners.com api"); + panel3.add(label6, new GridConstraints(1, 0, 1, 2, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + btnApi = new JButton(); + btnApi.setText("Add"); + panel3.add(btnApi, new GridConstraints(2, 3, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, new Dimension(70, 27), new Dimension(70, 27), new Dimension(70, 27), 0, false)); + txtApi = new JTextField(); + txtApi.setText(""); + panel3.add(txtApi, new GridConstraints(2, 0, 1, 3, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0, false)); + linkLabel = new JLabel(); + Font linkLabelFont = this.$$$getFont$$$(null, Font.PLAIN, -1, linkLabel.getFont()); + if (linkLabelFont != null) linkLabel.setFont(linkLabelFont); + linkLabel.setForeground(new Color(-15259748)); + linkLabel.setText("get token..."); + panel3.add(linkLabel, new GridConstraints(1, 2, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + final JPanel panel4 = new JPanel(); + panel4.setLayout(new GridLayoutManager(2, 2, new Insets(20, 0, 0, 0), -1, -1)); + panel1.add(panel4, new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); btnRulesLoad = new JButton(); btnRulesLoad.setText("Load"); - panel1.add(btnRulesLoad, new GridConstraints(1, 3, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, 1, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(51, 27), null, 0, false)); - scrlPanel = new JScrollPane(); - panel1.add(scrlPanel, new GridConstraints(2, 0, 1, 4, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false)); - scrlPanel.setViewportView(tblRules); - btnRuleAdd = new JButton(); - btnRuleAdd.setText("Add"); - panel1.add(btnRuleAdd, new GridConstraints(3, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + panel4.add(btnRulesLoad, new GridConstraints(1, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, new Dimension(70, 27), new Dimension(70, 27), new Dimension(70, 27), 0, false)); + txtRulesURL = new JTextField(); + txtRulesURL.setText("https://vulners.com/api/v3/burp/rules"); + panel4.add(txtRulesURL, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0, false)); + final JLabel label7 = new JLabel(); + Font label7Font = this.$$$getFont$$$(null, Font.BOLD, 14, label7.getFont()); + if (label7Font != null) label7.setFont(label7Font); + label7.setText("Scan Rules"); + panel4.add(label7, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + final JPanel panel5 = new JPanel(); + panel5.setLayout(new GridLayoutManager(1, 3, new Insets(0, 0, 0, 0), -1, -1)); + panel1.add(panel5, new GridConstraints(4, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); btnRuleRemove = new JButton(); btnRuleRemove.setText("Remove"); - panel1.add(btnRuleRemove, new GridConstraints(3, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); - final JPanel panel3 = new JPanel(); - panel3.setLayout(new GridLayoutManager(8, 2, new Insets(0, 0, 0, 0), -1, -1)); - tabbedPane1.addTab("Results", panel3); + panel5.add(btnRuleRemove, new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + btnRuleAdd = new JButton(); + btnRuleAdd.setText("Add"); + panel5.add(btnRuleAdd, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + final Spacer spacer1 = new Spacer(); + panel5.add(spacer1, new GridConstraints(0, 2, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, 1, null, null, null, 0, false)); + final JPanel panel6 = new JPanel(); + panel6.setLayout(new GridLayoutManager(8, 2, new Insets(10, 0, 0, 0), -1, -1)); + tabbedPane1.addTab("Results", panel6); final JScrollPane scrollPane1 = new JScrollPane(); - panel3.add(scrollPane1, new GridConstraints(2, 0, 1, 2, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, null, new Dimension(454, 126), null, 0, false)); + panel6.add(scrollPane1, new GridConstraints(2, 0, 1, 2, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, null, new Dimension(454, 126), null, 0, false)); + tblSoftware.setAutoCreateRowSorter(true); scrollPane1.setViewportView(tblSoftware); btnTblSoftwareClear = new JButton(); btnTblSoftwareClear.setText("Clear"); - panel3.add(btnTblSoftwareClear, new GridConstraints(3, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); - final JLabel label6 = new JLabel(); - label6.setFont(new Font(label6.getFont().getName(), Font.BOLD, label6.getFont().getSize())); - label6.setText("Vulnerable Software"); - panel3.add(label6, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + panel6.add(btnTblSoftwareClear, new GridConstraints(3, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + final JLabel label8 = new JLabel(); + Font label8Font = this.$$$getFont$$$(null, Font.BOLD, -1, label8.getFont()); + if (label8Font != null) label8.setFont(label8Font); + label8.setText("Vulnerable Software"); + panel6.add(label8, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); final Spacer spacer2 = new Spacer(); - panel3.add(spacer2, new GridConstraints(3, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, 1, null, null, null, 0, false)); + panel6.add(spacer2, new GridConstraints(3, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, 1, null, null, null, 0, false)); cbxSoftwareShowVuln = new JCheckBox(); cbxSoftwareShowVuln.setSelected(false); cbxSoftwareShowVuln.setText("Show only vulnerable software"); - panel3.add(cbxSoftwareShowVuln, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + panel6.add(cbxSoftwareShowVuln, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); final JSeparator separator1 = new JSeparator(); - panel3.add(separator1, new GridConstraints(4, 0, 1, 2, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false)); - final JLabel label7 = new JLabel(); - label7.setFont(new Font(label7.getFont().getName(), Font.BOLD, label7.getFont().getSize())); - label7.setText("Possible vulnerable software uses specific paths"); - panel3.add(label7, new GridConstraints(5, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + panel6.add(separator1, new GridConstraints(4, 0, 1, 2, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false)); + final JLabel label9 = new JLabel(); + Font label9Font = this.$$$getFont$$$(null, Font.BOLD, -1, label9.getFont()); + if (label9Font != null) label9.setFont(label9Font); + label9.setText("Possible vulnerable software uses specific paths"); + panel6.add(label9, new GridConstraints(5, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); final JScrollPane scrollPane2 = new JScrollPane(); - panel3.add(scrollPane2, new GridConstraints(6, 0, 1, 2, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, null, new Dimension(454, 126), null, 0, false)); + panel6.add(scrollPane2, new GridConstraints(6, 0, 1, 2, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, null, new Dimension(454, 126), null, 0, false)); + tblPaths.setAutoCreateRowSorter(true); scrollPane2.setViewportView(tblPaths); btnTblPathClear = new JButton(); btnTblPathClear.setText("Clear"); - panel3.add(btnTblPathClear, new GridConstraints(7, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); - final JPanel panel4 = new JPanel(); - panel4.setLayout(new GridLayoutManager(8, 3, new Insets(0, 0, 0, 0), -1, -1)); - tabbedPane1.addTab("Options", panel4); - final JLabel label8 = new JLabel(); - label8.setFont(new Font(label8.getFont().getName(), Font.BOLD, label8.getFont().getSize())); - label8.setText("Scan options"); - panel4.add(label8, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + panel6.add(btnTblPathClear, new GridConstraints(7, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + final JPanel panel7 = new JPanel(); + panel7.setLayout(new GridLayoutManager(4, 2, new Insets(10, 0, 0, 0), -1, -1)); + tabbedPane1.addTab("Options", panel7); + final JLabel label10 = new JLabel(); + Font label10Font = this.$$$getFont$$$(null, Font.BOLD, -1, label10.getFont()); + if (label10Font != null) label10.setFont(label10Font); + label10.setText("Scan options"); + panel7.add(label10, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); cbxPathSearch = new JCheckBox(); cbxPathSearch.setEnabled(true); cbxPathSearch.setSelected(false); cbxPathSearch.setText(""); - panel4.add(cbxPathSearch, new GridConstraints(1, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(51, 20), null, 0, false)); - final JLabel label9 = new JLabel(); - label9.setText("Use scan by locations paths (Experimental)"); - panel4.add(label9, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); - final JLabel label10 = new JLabel(); - label10.setEnabled(true); - label10.setFont(new Font(label10.getFont().getName(), Font.BOLD, label10.getFont().getSize())); - label10.setText("ProxyOptions"); - panel4.add(label10, new GridConstraints(3, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + panel7.add(cbxPathSearch, new GridConstraints(1, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(51, 20), null, 0, false)); final JLabel label11 = new JLabel(); - label11.setEnabled(true); - label11.setText("Host"); - panel4.add(label11, new GridConstraints(5, 0, 1, 1, GridConstraints.ANCHOR_EAST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + label11.setText("Use scan by locations paths"); + panel7.add(label11, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); final Spacer spacer3 = new Spacer(); - panel4.add(spacer3, new GridConstraints(7, 0, 1, 2, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_VERTICAL, 1, GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false)); - tbxProxyHost = new JTextField(); - tbxProxyHost.setEnabled(true); - tbxProxyHost.setText("127.0.0.1"); - panel4.add(tbxProxyHost, new GridConstraints(5, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0, false)); - final Spacer spacer4 = new Spacer(); - panel4.add(spacer4, new GridConstraints(5, 2, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, 1, null, null, null, 0, false)); + panel7.add(spacer3, new GridConstraints(3, 0, 1, 2, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_VERTICAL, 1, GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false)); final JLabel label12 = new JLabel(); - label12.setEnabled(true); - label12.setText("Port"); - panel4.add(label12, new GridConstraints(6, 0, 1, 1, GridConstraints.ANCHOR_EAST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); - tbxProxyPort = new JTextField(); - tbxProxyPort.setEnabled(true); - tbxProxyPort.setText("8888"); - panel4.add(tbxProxyPort, new GridConstraints(6, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0, false)); - final JLabel label13 = new JLabel(); - label13.setEnabled(true); - label13.setText("Proxy enabled"); - panel4.add(label13, new GridConstraints(4, 0, 1, 1, GridConstraints.ANCHOR_EAST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); - cbxProxyEnabled = new JCheckBox(); - cbxProxyEnabled.setEnabled(true); - cbxProxyEnabled.setSelected(false); - cbxProxyEnabled.setText(""); - panel4.add(cbxProxyEnabled, new GridConstraints(4, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); - final JLabel label14 = new JLabel(); - label14.setText("Scope Only"); - panel4.add(label14, new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_EAST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + label12.setText("Scope Only"); + panel7.add(label12, new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_EAST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); cbxPathScanInScope = new JCheckBox(); cbxPathScanInScope.setEnabled(true); cbxPathScanInScope.setSelected(true); cbxPathScanInScope.setText(""); - panel4.add(cbxPathScanInScope, new GridConstraints(2, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(51, 20), null, 0, false)); + panel7.add(cbxPathScanInScope, new GridConstraints(2, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(51, 20), null, 0, false)); + } + + /** + * @noinspection ALL + */ + private Font $$$getFont$$$(String fontName, int style, int size, Font currentFont) { + if (currentFont == null) return null; + String resultName; + if (fontName == null) { + resultName = currentFont.getName(); + } else { + Font testFont = new Font(fontName, Font.PLAIN, 10); + if (testFont.canDisplay('a') && testFont.canDisplay('1')) { + resultName = fontName; + } else { + resultName = currentFont.getName(); + } + } + return new Font(resultName, style >= 0 ? style : currentFont.getStyle(), size >= 0 ? size : currentFont.getSize()); } /** diff --git a/src/main/java/burp/gui/path/PathsTable.java b/src/main/java/burp/gui/path/PathsTable.java index e996864..7598af3 100644 --- a/src/main/java/burp/gui/path/PathsTable.java +++ b/src/main/java/burp/gui/path/PathsTable.java @@ -21,6 +21,7 @@ public boolean isCellEditable(int row, int column) { setModel(model); this.defaultModel = model; + this.setAutoCreateRowSorter(true); } public DefaultTableModel getDefaultModel() { diff --git a/src/main/java/burp/gui/rules/RulesTable.java b/src/main/java/burp/gui/rules/RulesTable.java index a49c2cc..09bdcb5 100644 --- a/src/main/java/burp/gui/rules/RulesTable.java +++ b/src/main/java/burp/gui/rules/RulesTable.java @@ -1,17 +1,7 @@ package burp.gui.rules; -import burp.IBurpExtenderCallbacks; -import com.codemagi.burp.MatchRule; -import com.codemagi.burp.PassiveScan; -import com.codemagi.burp.ScanIssueConfidence; -import com.codemagi.burp.ScanIssueSeverity; - import javax.swing.*; import javax.swing.table.DefaultTableModel; -import java.io.*; -import java.net.URL; -import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; public class RulesTable extends JTable { @@ -26,6 +16,7 @@ public RulesTable() { setModel(model); this.defaultModel = model; + this.setAutoCreateRowSorter(true); } public DefaultTableModel getDefaultModel() { diff --git a/src/main/java/burp/gui/rules/RulesTableListener.java b/src/main/java/burp/gui/rules/RulesTableListener.java index ec9b81c..b973a7b 100644 --- a/src/main/java/burp/gui/rules/RulesTableListener.java +++ b/src/main/java/burp/gui/rules/RulesTableListener.java @@ -1,7 +1,6 @@ package burp.gui.rules; import burp.IBurpExtenderCallbacks; -import burp.VulnersService; import com.codemagi.burp.MatchRule; import com.codemagi.burp.PassiveScan; import com.codemagi.burp.ScanIssueConfidence; @@ -12,10 +11,7 @@ import javax.swing.event.TableModelListener; import javax.swing.table.DefaultTableModel; import java.awt.event.ActionEvent; -import java.io.*; -import java.net.URL; import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; public class RulesTableListener implements TableModelListener { @@ -51,7 +47,7 @@ private void onTableChage(TableModelEvent e) { switch (column) { case 0: - mCallbacks.printOutput("new pattern: " + (String)model.getValueAt(row, column)); + mCallbacks.printOutput("[Vulners] new pattern: " + (String)model.getValueAt(row, column)); rule.setPattern(Pattern.compile((String)model.getValueAt(row, column))); break; case 1: diff --git a/src/main/java/burp/models/Path.java b/src/main/java/burp/models/Path.java index 171b09b..012b125 100644 --- a/src/main/java/burp/models/Path.java +++ b/src/main/java/burp/models/Path.java @@ -1,7 +1,5 @@ package burp.models; -import org.json.JSONObject; - import java.util.Set; public class Path { diff --git a/src/main/java/burp/models/VulnersRequest.java b/src/main/java/burp/models/VulnersRequest.java new file mode 100644 index 0000000..02f0983 --- /dev/null +++ b/src/main/java/burp/models/VulnersRequest.java @@ -0,0 +1,56 @@ +package burp.models; + +import burp.IHttpRequestResponse; +import burp.SoftwareIssue; + +import java.util.Set; + +public class VulnersRequest { + + private String domainName; + private String path; + private Software software; + private SoftwareIssue softwareIssue; + private IHttpRequestResponse baseRequestResponse; + private Set vulnerabilities; + + public VulnersRequest(String domainName, Software software, SoftwareIssue softwareIssue) { + this.software = software; + this.domainName = domainName; + this.softwareIssue = softwareIssue; + } + + public VulnersRequest(String domainName, String path, IHttpRequestResponse baseRequestResponse) { + this.domainName = domainName; + this.path = path; + this.baseRequestResponse = baseRequestResponse; + } + + public IHttpRequestResponse getBaseRequestResponse() { + return baseRequestResponse; + } + + public SoftwareIssue getSoftwareIssue() { + return softwareIssue; + } + + public String getPath() { + return path; + } + + public String getDomain() { + return domainName; + } + + public Software getSoftware() { + return software; + } + + public Set getVulnerabilities() { + return vulnerabilities; + } + + public void setVulnerabilities(Set vulnerabilities) { + this.vulnerabilities = vulnerabilities; + } +} diff --git a/src/main/java/burp/tasks/PathScanTask.java b/src/main/java/burp/tasks/PathScanTask.java new file mode 100644 index 0000000..f727194 --- /dev/null +++ b/src/main/java/burp/tasks/PathScanTask.java @@ -0,0 +1,38 @@ +package burp.tasks; + +import burp.HttpClient; +import burp.Utils; +import burp.models.Vulnerability; +import burp.models.VulnersRequest; +import org.json.JSONObject; + +import java.util.HashMap; +import java.util.Set; +import java.util.function.Consumer; + +public class PathScanTask extends Thread { + + private HttpClient httpClient; + private Consumer callback; + private VulnersRequest vulnersRequest; + + public PathScanTask(VulnersRequest vulnersRequest, HttpClient httpClient, Consumer callback) { + this.httpClient = httpClient; + this.vulnersRequest = vulnersRequest; + this.callback = callback; + } + + @Override + public void run() { + + JSONObject data = httpClient.get("path", new HashMap() {{ + put("path", vulnersRequest.getPath()); + }}); + + Set vulnerabilities = Utils.getVulnerabilities(data); + + vulnersRequest.setVulnerabilities(vulnerabilities); + + callback.accept(vulnersRequest); + } +} diff --git a/src/main/java/burp/tasks/SoftwareScanTask.java b/src/main/java/burp/tasks/SoftwareScanTask.java new file mode 100644 index 0000000..e3e8b6b --- /dev/null +++ b/src/main/java/burp/tasks/SoftwareScanTask.java @@ -0,0 +1,43 @@ +package burp.tasks; + +import burp.Utils; +import burp.HttpClient; +import burp.models.VulnersRequest; +import burp.models.Software; +import burp.models.Vulnerability; +import org.json.JSONObject; + +import java.util.HashMap; +import java.util.Set; +import java.util.function.Consumer; + +public class SoftwareScanTask extends Thread { + + private HttpClient httpClient; + private Consumer callback; + private VulnersRequest vulnersRequest; + + public SoftwareScanTask(VulnersRequest vulnersRequest, HttpClient httpClient, Consumer callback) { + this.httpClient = httpClient; + this.vulnersRequest = vulnersRequest; + this.callback = callback; + } + + @Override + public void run() { + + Software software = vulnersRequest.getSoftware(); + + JSONObject data = httpClient.get("software", new HashMap(){{ + put("software", software.getAlias()); + put("version", software.getVersion()); + put("type", software.getMatchType()); + }}); + + Set vulnerabilities = Utils.getVulnerabilities(data); + + vulnersRequest.setVulnerabilities(vulnerabilities); + + callback.accept(vulnersRequest); + } +} diff --git a/target/burp-vulners-scanner-1.1.jar b/target/burp-vulners-scanner-1.1.jar index e40549c..388318c 100644 Binary files a/target/burp-vulners-scanner-1.1.jar and b/target/burp-vulners-scanner-1.1.jar differ diff --git a/target/burp-vulners-scanner-1.2.jar b/target/burp-vulners-scanner-1.2.jar new file mode 100644 index 0000000..25e1ec2 Binary files /dev/null and b/target/burp-vulners-scanner-1.2.jar differ