@Override
 protected String doInBackground() throws Exception {
   publish("Starting...");
   IExtensionHelpers helpers = callbacks.getHelpers();
   publish(0);
   IHttpRequestResponse[] messages = callbacks.getProxyHistory();
   if (messages.length == 0) {
     publish(100);
   } else {
     firstPass(helpers, messages);
     parameterFormatAnalysis();
     // secondPass(helpers);  This is just too darn slow as it is now... need to rethink it.
   }
   return "";
 }
 @Override
 protected void done() {
   super.done();
   try {
     this.get();
     listener.done();
   } catch (InterruptedException e) {
     listener.setStatus("Interrupted Exception: " + e.getMessage());
     e.printStackTrace(new PrintStream(callbacks.getStderr()));
   } catch (ExecutionException e) {
     listener.setStatus("Execution Exception: " + e.getMessage());
     e.printStackTrace(new PrintStream(callbacks.getStderr()));
   } catch (Throwable e) {
     listener.setStatus(e.getMessage());
     e.printStackTrace(new PrintStream(callbacks.getStderr()));
   }
 }
  public static void analyzeWEBXML(
      byte[] webxmlFile, IBurpExtenderCallbacks cb, IHttpRequestResponse baseRequestResponse) {

    IExtensionHelpers helpers = cb.getHelpers();

    PrintWriter stderr = new PrintWriter(cb.getStderr(), true);

    Pattern pattern =
        Pattern.compile("(<web-app.*?</web-app>)", Pattern.DOTALL | Pattern.MULTILINE);
    String webxml = helpers.bytesToString(webxmlFile);

    Matcher matcher = pattern.matcher(webxml);

    if (matcher.find()) {

      try {

        String webxmlContent = matcher.group(1);

        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder dBuilder;

        dBuilder = dbFactory.newDocumentBuilder();
        InputSource is = new InputSource(new StringReader(webxmlContent));
        Document doc = dBuilder.parse(is);

        /**
         * HTTP VERB Tampering
         *
         * <p>http://docs.oracle.com/cd/E14571_01/web.1111/e13712/web_xml.htm#WBAPP502
         * https://weblogs.java.net/blog/swchan2/archive/2013/04/19/deny-uncovered-http-methods-servlet-31
         * http-method should not be defined, to restrict access to a resources using HTTP verbs In
         * Servlet 3.1 spec, the attribute "deny-uncovered-http-methods" could be used to deny
         * uncovered HTTP verbs
         */
        try {
          NodeList httpMethods = doc.getElementsByTagName("http-method");

          if ((httpMethods != null) && (httpMethods.getLength() >= 1)) {
            cb.addScanIssue(
                new CustomScanIssue(
                    baseRequestResponse.getHttpService(),
                    helpers.analyzeRequest(baseRequestResponse).getUrl(),
                    baseRequestResponse,
                    "Compliance Checks - web.xml - HTTP Verb Tampering",
                    "J2EEScan identified a potential HTTP Verb Tampering vulnerability inspecting"
                        + " the remote web.xml resource.<br /><br />"
                        + "One or more resources defined into the web.xml uses some definitions to restrict "
                        + "access based on the HTTP Verb used with requests; based on this context, in some scenarios "
                        + "it's possible to bypass these resctrictions providing a different HTTP verb to access to the remote resource."
                        + "<br /> This allows the attacker to access data that should otherwise be protected."
                        + "<br /><br />An example of vulnerable configuration that could lead to Authentication Bypass vulnerabilities:<br /><br />"
                        + "<div style=\"font: courier;\"><pre>"
                        + "&lt;security-constraint&gt;\n"
                        + "    &lt;display-name&gt;\n"
                        + "        Protect GET only, leave all other methods unprotected\n"
                        + "    &lt;/display-name&gt;\n"
                        + "    &lt;web-resource-collection&gt;\n"
                        + "        &lt;url-pattern&gt;/company/*&lt;/url-pattern&gt;\n"
                        + "        &lt;http-method&gt;GET&lt;/http-method&gt;\n"
                        + "    &lt;/web-resource-collection&gt;\n"
                        + "    &lt;auth-constraint&gt;\n"
                        + "        &lt;role-name&gt;sales&lt;/role-name&gt;\n"
                        + "    &lt;/auth-constraint&gt;\n"
                        + "&lt;/security-constraint&gt;"
                        + "</pre></div> "
                        + "<br />"
                        + "<br /><b>References:</b><br />"
                        + "https://www.owasp.org/index.php/Testing_for_HTTP_Verb_Tampering_(OTG-INPVAL-003)<br />"
                        + "http://www.aspectsecurity.com/research-presentations/bypassing-vbaac-with-http-verb-tampering<br />"
                        + "http://capec.mitre.org/data/definitions/274.html<br />"
                        + "http://jeremiahgrossman.blogspot.it/2008/06/what-you-need-to-know-about-http-verb.html",
                    "Remove <i>http-method</i> elements to avoid possible HTTP Verb Tampering attacks",
                    Risk.Medium,
                    Confidence.Tentative));
          }

        } catch (Exception ex) {
          ex.printStackTrace(stderr);
        }

        /**
         * URL Parameters for Session Tracking
         * http://docs.oracle.com/javaee/6/api/javax/servlet/SessionTrackingMode.html
         */
        try {

          NodeList sessionTracking = doc.getElementsByTagName("tracking-mode");

          if ((sessionTracking != null) && (sessionTracking.getLength() >= 1)) {
            String value = sessionTracking.item(0).getTextContent();
            if (value.equalsIgnoreCase("URL")) {

              cb.addScanIssue(
                  new CustomScanIssue(
                      baseRequestResponse.getHttpService(),
                      helpers.analyzeRequest(baseRequestResponse).getUrl(),
                      baseRequestResponse,
                      "Compliance Checks- web.xml - URL Parameters for Session Tracking",
                      "J2EEScan identified a potential Information Disclosure vulnerabilitiy inspecting"
                          + " the remote web.xml resource.<br /><br />"
                          + "The remote applications seems to put the JSESSIONID into the URL using the directive <i>tracking-mode</i> with the URL value;<br />"
                          + "the tracking-mode element in the Servlet 3.0 specification allows to define whether the JSESSIONID should be stored in a cookie or in a URL parameter. <br />"
                          + "If the session id is stored in a URL parameter it could lead to and Information Disclosure vulnerability, because the URLs could be inadvertently "
                          + "saved in browser history, proxy server logs, referrer logs etc. <br />"
                          + "<br /><b>References:</b><br />"
                          + "http://software-security.sans.org/blog/2010/08/11/security-misconfigurations-java-webxml-files<br />",
                      "Change the <i>tracking-mode</i> value to avoid possible Information Disclosure vulnerabilities",
                      Risk.Low,
                      Confidence.Tentative));
            }
          }
        } catch (Exception ex) {
          ex.printStackTrace(stderr);
        }

        /**
         * Incomplete Error Handling
         *
         * <p>https://blog.whitehatsec.com/error-handling-in-java-web-xml/
         * http://software-security.sans.org/blog/2010/08/11/security-misconfigurations-java-webxml-files
         * http://www.jtmelton.com/2010/06/02/the-owasp-top-ten-and-esapi-part-7-information-leakage-and-improper-error-handling/
         */
        try {

          NodeList exceptionType = doc.getElementsByTagName("exception-type");
          Boolean incompleteErrorHandling = true;
          int excTypeLen = exceptionType.getLength();

          for (int i = 0; i < excTypeLen; i++) {
            Node s = exceptionType.item(i);
            String value = s.getTextContent();

            if (value.equalsIgnoreCase("java.lang.Throwable")) {
              incompleteErrorHandling = false;
              break;
            }
          }
          if (incompleteErrorHandling) {
            cb.addScanIssue(
                new CustomScanIssue(
                    baseRequestResponse.getHttpService(),
                    helpers.analyzeRequest(baseRequestResponse).getUrl(),
                    baseRequestResponse,
                    "Compliance Checks - web.xml - Incomplete Error Handling (Throwable)",
                    "J2EEScan identified a potential Information Disclosure vulnerabilitiy inspecting"
                        + " the remote web.xml resource.<br /><br />"
                        + "The remote application seems to not correctly handle application errors; the web.xml does not "
                        + "provide an error page for <i>java.lang.Throwable</i> exceptions.<br /><br />"
                        + "<b>References:</b><br />"
                        + "https://blog.whitehatsec.com/error-handling-in-java-web-xml/<br />"
                        + "http://software-security.sans.org/blog/2010/08/11/security-misconfigurations-java-webxml-files<br />",
                    "Modify the error handling catching the <i>java.lang.Throwable</i> exception to avoid possible Information Disclosure vulnerabilities<br /><br />"
                        + "<div style=\"font: courier;\"><pre>"
                        + "&lt;error-page&gt;\n"
                        + "  &lt;error-code&gt;404&lt;/error-code&gt;\n"
                        + "  &lt;location&gt;/error.jsp&lt;/location&gt;\n"
                        + "&lt;/error-page&gt;\n"
                        + "&lt;error-page&gt;\n"
                        + "  &lt;error-code&gt;500&lt;/error-code&gt;\n"
                        + "  &lt;location&gt;/error.jsp&lt;/location&gt;\n"
                        + "&lt;/error-page&gt;\n"
                        + "&lt;error-page&gt;\n"
                        + "  &lt;exception-type&gt;java.lang.Throwable&lt;/exception-type&gt;\n"
                        + "  &lt;location&gt;/error.jsp&lt;/location&gt;\n"
                        + "&lt;/error-page&gt;\n"
                        + "</pre></div>",
                    Risk.Low,
                    Confidence.Tentative));
          }
        } catch (Exception ex) {
          ex.printStackTrace(stderr);
        }

        try {

          NodeList exceptionType = doc.getElementsByTagName("error-code");
          Boolean incompleteErrorHandling500 = true;
          int excTypeLen = exceptionType.getLength();

          for (int i = 0; i < excTypeLen; i++) {
            Node s = exceptionType.item(i);
            String value = s.getTextContent();

            if (value.equalsIgnoreCase("500")) {
              incompleteErrorHandling500 = false;
              break;
            }
          }
          if (incompleteErrorHandling500) {
            cb.addScanIssue(
                new CustomScanIssue(
                    baseRequestResponse.getHttpService(),
                    helpers.analyzeRequest(baseRequestResponse).getUrl(),
                    baseRequestResponse,
                    "Compliance Checks - web.xml - Incomplete Error Handling (HTTP Code 500)",
                    "J2EEScan identified a potential Information Disclosure vulnerabilitiy inspecting"
                        + " the remote web.xml resource.<br /><br />"
                        + "The remote application seems to not correctly handle application errors; the web.xml does not "
                        + "provide an error page for <i>500</i> HTTP code.<br /><br />"
                        + "<b>References:</b><br />"
                        + "https://blog.whitehatsec.com/error-handling-in-java-web-xml/<br />"
                        + "http://software-security.sans.org/blog/2010/08/11/security-misconfigurations-java-webxml-files<br />",
                    "Modify the error handling catching the <i>500</i> error code to avoid possible Information Disclosure vulnerabilities<br /><br />"
                        + "<div style=\"font: courier;\"><pre>"
                        + "&lt;error-page&gt;\n"
                        + "  &lt;error-code&gt;404&lt;/error-code&gt;\n"
                        + "  &lt;location&gt;/error.jsp&lt;/location&gt;\n"
                        + "&lt;/error-page&gt;\n"
                        + "&lt;error-page&gt;\n"
                        + "  &lt;error-code&gt;500&lt;/error-code&gt;\n"
                        + "  &lt;location&gt;/error.jsp&lt;/location&gt;\n"
                        + "&lt;/error-page&gt;\n"
                        + "&lt;error-page&gt;\n"
                        + "  &lt;exception-type&gt;java.lang.Throwable&lt;/exception-type&gt;\n"
                        + "  &lt;location&gt;/error.jsp&lt;/location&gt;\n"
                        + "&lt;/error-page&gt;\n"
                        + "</pre></div>",
                    Risk.Low,
                    Confidence.Tentative));
          }
        } catch (Exception ex) {
          ex.printStackTrace(stderr);
        }

        try {

          NodeList exceptionType = doc.getElementsByTagName("error-code");
          Boolean incompleteErrorHandling404 = true;
          int excTypeLen = exceptionType.getLength();

          for (int i = 0; i < excTypeLen; i++) {
            Node s = exceptionType.item(i);
            String value = s.getTextContent();

            if (value.equalsIgnoreCase("404")) {
              incompleteErrorHandling404 = false;
              break;
            }
          }
          if (incompleteErrorHandling404) {
            cb.addScanIssue(
                new CustomScanIssue(
                    baseRequestResponse.getHttpService(),
                    helpers.analyzeRequest(baseRequestResponse).getUrl(),
                    baseRequestResponse,
                    "Compliance Checks - web.xml - Incomplete Error Handling (HTTP Code 404)",
                    "J2EEScan identified a potential Information Disclosure vulnerabilitiy inspecting"
                        + " the remote web.xml resource.<br /><br />"
                        + "The remote application seems to not correctly handle application errors; the web.xml does not "
                        + "provide an error page for <i>404</i> HTTP code.<br /><br />"
                        + "<b>References:</b><br />"
                        + "https://blog.whitehatsec.com/error-handling-in-java-web-xml/<br />"
                        + "http://software-security.sans.org/blog/2010/08/11/security-misconfigurations-java-webxml-files<br />",
                    "Modify the error handling catching the <i>404</i> error code to avoid possible Information Disclosure vulnerabilities<br /><br />"
                        + "<div style=\"font: courier;\"><pre>"
                        + "&lt;error-page&gt;\n"
                        + "  &lt;error-code&gt;404&lt;/error-code&gt;\n"
                        + "  &lt;location&gt;/error.jsp&lt;/location&gt;\n"
                        + "&lt;/error-page&gt;\n"
                        + "&lt;error-page&gt;\n"
                        + "  &lt;error-code&gt;500&lt;/error-code&gt;\n"
                        + "  &lt;location&gt;/error.jsp&lt;/location&gt;\n"
                        + "&lt;/error-page&gt;\n"
                        + "&lt;error-page&gt;\n"
                        + "  &lt;exception-type&gt;java.lang.Throwable&lt;/exception-type&gt;\n"
                        + "  &lt;location&gt;/error.jsp&lt;/location&gt;\n"
                        + "&lt;/error-page&gt;\n"
                        + "</pre></div>",
                    Risk.Low,
                    Confidence.Tentative));
          }
        } catch (Exception ex) {
          ex.printStackTrace(stderr);
        }

        /** InvokerServlet */
        try {

          NodeList exceptionType = doc.getElementsByTagName("servlet-class");

          int excTypeLen = exceptionType.getLength();

          for (int i = 0; i < excTypeLen; i++) {
            Node s = exceptionType.item(i);
            String value = s.getTextContent();

            if (value.contains("InvokerServlet")) {
              cb.addScanIssue(
                  new CustomScanIssue(
                      baseRequestResponse.getHttpService(),
                      helpers.analyzeRequest(baseRequestResponse).getUrl(),
                      baseRequestResponse,
                      "Compliance Checks - web.xml - Invoker Servlet",
                      "J2EEScan identified the <i>InvokerServlet</> enabled inspecting"
                          + " the remote web.xml resource.<br /><br />"
                          + "It allows any class in your classpath to be accessed, as long as the class is a valid servlet. <br />"
                          + "This functionality could potentially introduces a security risk; different servlets could be directly accessed from remote bypassing any Authorization Layers<br /><br />"
                          + "<b>References:</b><br />"
                          + "http://www.coderanch.com/how-to/java/InvokerServlet<br />"
                          + "https://tomcat.apache.org/tomcat-4.1-doc/catalina/funcspecs/fs-invoker.html<br />",
                      "Disable or restrict access to the remote InvokerServlet",
                      Risk.Medium,
                      Confidence.Tentative));
              break;
            }
          }
        } catch (Exception ex) {
          ex.printStackTrace(stderr);
        }

      } catch (ParserConfigurationException | SAXException | IOException ex) {
        ex.printStackTrace(stderr);
      }
    }
  }
示例#4
0
  public static void getIssues(
      String software,
      String release,
      IBurpExtenderCallbacks callbacks,
      IHttpRequestResponse baseRequestResponse) {

    IExtensionHelpers helpers = callbacks.getHelpers();

    /** Apache Tomcat */
    if (software.equalsIgnoreCase("Apache Tomcat")) {

      /** End of Life - Apache Tomcat */
      if (Integer.parseInt(release.substring(0, 1)) <= 5) {

        callbacks.addScanIssue(
            new CustomScanIssue(
                baseRequestResponse.getHttpService(),
                helpers.analyzeRequest(baseRequestResponse).getUrl(),
                baseRequestResponse,
                "End of Life Software - Apache Tomcat " + release,
                "J2EEScan identified an unsupported release of Apache Tomcat <b>"
                    + release
                    + "</b>.<br />"
                    + "No more security updates for this version will be released by Apache <br /><br />"
                    + "<b>References</b><br />"
                    + "http://tomcat.apache.org/tomcat-55-eol.html<br />",
                "Update the Apache Servlet Container with the last stable release",
                Risk.High,
                Confidence.Certain));
      }
    }

    /** Jetty */
    if (software.equalsIgnoreCase("Jetty")) {

      /** End of Life - Jetty */
      if (Integer.parseInt(release.substring(0, 1)) < 9) {

        callbacks.addScanIssue(
            new CustomScanIssue(
                baseRequestResponse.getHttpService(),
                helpers.analyzeRequest(baseRequestResponse).getUrl(),
                baseRequestResponse,
                "End of Life Software - Jetty " + release,
                "J2EEScan identified an unsupported release of Jetty <b>"
                    + release
                    + "</b>.<br />"
                    + "No more security updates for this version will be released by the vendor <br /><br />"
                    + "<b>References</b><br />"
                    + "https://webtide.com/jetty-7-and-jetty-8-end-of-life/<br />",
                "Update the Jetty Container with the last stable release",
                Risk.High,
                Confidence.Certain));
      }
    }

    /** Oracle Application Server */
    if (software.equalsIgnoreCase("Oracle Application Server")) {

      /** End of Life - Oracle Application Server */
      if (release.startsWith("9.") || release.startsWith("10.1.2")) {

        callbacks.addScanIssue(
            new CustomScanIssue(
                baseRequestResponse.getHttpService(),
                helpers.analyzeRequest(baseRequestResponse).getUrl(),
                baseRequestResponse,
                "End of Life Software - Oracle Application Server " + release,
                "J2EEScan identified an unsupported release of Oracle Application Server <b>"
                    + release
                    + "</b>.<br />"
                    + "No more security updates for this version will be released by the vendor <br /><br />"
                    + "<b>References</b><br />"
                    + "http://www.oracle.com/us/support/library/lifetime-support-middleware-069163.pdf<br />",
                "Update the Oracle Application Server with the last stable release",
                Risk.High,
                Confidence.Tentative));
      }
    }
  }
  /**
   * Analyze and categorize each of the parameters in scope.
   *
   * @param helpers The standard burp ExtensionHelpers object.
   * @param messages The set of request messages to be processed.
   */
  private void firstPass(IExtensionHelpers helpers, IHttpRequestResponse[] messages) {
    publish("Examining parameters...");
    for (int i = 0; i < messages.length; i++) {
      publish(100 * i / messages.length);
      messages[i].getHttpService();
      //  Analyze response for cookies
      if (messages[i].getResponse() != null) {
        IResponseInfo responseInfo = helpers.analyzeResponse(messages[i].getResponse());
        List<String> headers = responseInfo.getHeaders();
        for (String header : headers) {
          if (startsWithIgnoreCase(header, "set-cookie:")) {
            processCookieHeader(header);
          }
        }
      }
      IRequestInfo requestInfo = helpers.analyzeRequest(messages[i]);
      if (callbacks.isInScope(requestInfo.getUrl())) {
        byte[] responseBytes = messages[i].getResponse();
        String responseString = "";
        if (responseBytes != null) {
          responseString = helpers.bytesToString(responseBytes);
          inScopeMessagesWithResponses.add(messages[i]);
        }

        List<IParameter> params = requestInfo.getParameters();
        for (IParameter param : params) {
          if ((!ignoreEmpty || param.getValue().length() > 0)
              && !ignoreList.contains(param.getName())) {
            int type = param.getType();
            Map<String, CorrelatedParam> paramMap;
            switch (type) {
              case IParameter.PARAM_URL:
                paramMap = urlParameters;
                break;
              case IParameter.PARAM_BODY:
                paramMap = bodyParameters;
                break;
              case IParameter.PARAM_COOKIE:
                paramMap = cookieParameters;
                break;
              case IParameter.PARAM_JSON:
                paramMap = jsonParameters;
                break;
              default:
                paramMap = null;
                // nothing
            }

            if (paramMap != null) {
              if (messages[i] == null) {
                callbacks.printOutput("Warning... adding null message!");
              }

              if (paramMap.containsKey(param.getName())) {
                paramMap
                    .get(param.getName())
                    .put(param, messages[i], requestInfo, responseString, helpers);
              } else {
                paramMap.put(
                    param.getName(),
                    new CorrelatedParam(param, messages[i], requestInfo, responseString, helpers));
              }
            }
          }
        }
      }
    }
  }