Пример #1
0
  public static byte[] convertToJSON(
      IExtensionHelpers helpers, IHttpRequestResponse requestResponse) {

    byte[] request = requestResponse.getRequest();

    if (Objects.equals(helpers.analyzeRequest(request).getMethod(), "GET")) {
      request = helpers.toggleRequestMethod(request);
    }

    IRequestInfo requestInfo = helpers.analyzeRequest(request);

    int bodyOffset = requestInfo.getBodyOffset();

    byte content_type = requestInfo.getContentType();

    String body = new String(request, bodyOffset, request.length - bodyOffset);

    String json = "";

    Boolean success = true;

    try {
      if (content_type == 3) {
        JSONObject xmlJSONObject = XML.toJSONObject(body);
        json = xmlJSONObject.toString(2);
      } else if (content_type == 0 || content_type == 1) {
        Map<String, String> params = splitQuery(body);
        Gson gson = new Gson();
        json = gson.toJson(params);
      } else {
        json = body;
      }
    } catch (Exception e) {
      success = false;
    }

    if (!success) {
      return request;
    } else {

      List<String> headers;

      headers = helpers.analyzeRequest(request).getHeaders();

      Iterator<String> iter = headers.iterator();
      while (iter.hasNext()) {
        if (iter.next().contains("Content-Type")) iter.remove();
      }

      headers.add("Content-Type: application/json;charset=UTF-8");

      return helpers.buildHttpMessage(headers, json.getBytes());
    }
  }
 private void secondPass(IExtensionHelpers helpers) {
   publish("Second Pass...");
   publish(0);
   Set<Map<String, CorrelatedParam>> allStats = new HashSet<>();
   allStats.add(urlParameters);
   allStats.add(bodyParameters);
   allStats.add(cookieParameters);
   int x = 0;
   for (IHttpRequestResponse message : inScopeMessagesWithResponses) {
     publish(100 * x / inScopeMessagesWithResponses.size());
     x += 1;
     String responseString = helpers.bytesToString(message.getResponse());
     for (Map<String, CorrelatedParam> paramMap : allStats) {
       for (String paramName : paramMap.keySet()) {
         publish("Analyzing " + paramName + "...");
         for (CorrelatedParam param : paramMap.values()) {
           for (String value : param.getUniqueValues()) {
             if (responseString.contains(value)) {
               param.putSeenParam(value, message);
             }
           }
         }
       }
     }
   }
 }
Пример #3
0
  public static byte[] convertToXML(IExtensionHelpers helpers, IHttpRequestResponse requestResponse)
      throws Exception {

    byte[] request = requestResponse.getRequest();

    if (Objects.equals(helpers.analyzeRequest(request).getMethod(), "GET")) {
      request = helpers.toggleRequestMethod(request);
    }

    IRequestInfo requestInfo = helpers.analyzeRequest(request);

    int bodyOffset = requestInfo.getBodyOffset();

    byte content_type = requestInfo.getContentType();

    String body = new String(request, bodyOffset, request.length - bodyOffset, "UTF-8");

    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    Document doc =
        new Document() {
          public String getNodeName() {
            return null;
          }

          public String getNodeValue() throws DOMException {
            return null;
          }

          public void setNodeValue(String nodeValue) throws DOMException {}

          public short getNodeType() {
            return 0;
          }

          public Node getParentNode() {
            return null;
          }

          public NodeList getChildNodes() {
            return null;
          }

          public Node getFirstChild() {
            return null;
          }

          public Node getLastChild() {
            return null;
          }

          public Node getPreviousSibling() {
            return null;
          }

          public Node getNextSibling() {
            return null;
          }

          public NamedNodeMap getAttributes() {
            return null;
          }

          public Document getOwnerDocument() {
            return null;
          }

          public Node insertBefore(Node newChild, Node refChild) throws DOMException {
            return null;
          }

          public Node replaceChild(Node newChild, Node oldChild) throws DOMException {
            return null;
          }

          public Node removeChild(Node oldChild) throws DOMException {
            return null;
          }

          public Node appendChild(Node newChild) throws DOMException {
            return null;
          }

          public boolean hasChildNodes() {
            return false;
          }

          public Node cloneNode(boolean deep) {
            return null;
          }

          public void normalize() {}

          public boolean isSupported(String feature, String version) {
            return false;
          }

          public String getNamespaceURI() {
            return null;
          }

          public String getPrefix() {
            return null;
          }

          public void setPrefix(String prefix) throws DOMException {}

          public String getLocalName() {
            return null;
          }

          public boolean hasAttributes() {
            return false;
          }

          public String getBaseURI() {
            return null;
          }

          public short compareDocumentPosition(Node other) throws DOMException {
            return 0;
          }

          public String getTextContent() throws DOMException {
            return null;
          }

          public void setTextContent(String textContent) throws DOMException {}

          public boolean isSameNode(Node other) {
            return false;
          }

          public String lookupPrefix(String namespaceURI) {
            return null;
          }

          public boolean isDefaultNamespace(String namespaceURI) {
            return false;
          }

          public String lookupNamespaceURI(String prefix) {
            return null;
          }

          public boolean isEqualNode(Node arg) {
            return false;
          }

          public Object getFeature(String feature, String version) {
            return null;
          }

          public Object setUserData(String key, Object data, UserDataHandler handler) {
            return null;
          }

          public Object getUserData(String key) {
            return null;
          }

          public DocumentType getDoctype() {
            return null;
          }

          public DOMImplementation getImplementation() {
            return null;
          }

          public Element getDocumentElement() {
            return null;
          }

          public Element createElement(String tagName) throws DOMException {
            return null;
          }

          public DocumentFragment createDocumentFragment() {
            return null;
          }

          public Text createTextNode(String data) {
            return null;
          }

          public Comment createComment(String data) {
            return null;
          }

          public CDATASection createCDATASection(String data) throws DOMException {
            return null;
          }

          public ProcessingInstruction createProcessingInstruction(String target, String data)
              throws DOMException {
            return null;
          }

          public Attr createAttribute(String name) throws DOMException {
            return null;
          }

          public EntityReference createEntityReference(String name) throws DOMException {
            return null;
          }

          public NodeList getElementsByTagName(String tagname) {
            return null;
          }

          public Node importNode(Node importedNode, boolean deep) throws DOMException {
            return null;
          }

          public Element createElementNS(String namespaceURI, String qualifiedName)
              throws DOMException {
            return null;
          }

          public Attr createAttributeNS(String namespaceURI, String qualifiedName)
              throws DOMException {
            return null;
          }

          public NodeList getElementsByTagNameNS(String namespaceURI, String localName) {
            return null;
          }

          public Element getElementById(String elementId) {
            return null;
          }

          public String getInputEncoding() {
            return null;
          }

          public String getXmlEncoding() {
            return null;
          }

          public boolean getXmlStandalone() {
            return false;
          }

          public void setXmlStandalone(boolean xmlStandalone) throws DOMException {}

          public String getXmlVersion() {
            return null;
          }

          public void setXmlVersion(String xmlVersion) throws DOMException {}

          public boolean getStrictErrorChecking() {
            return false;
          }

          public void setStrictErrorChecking(boolean strictErrorChecking) {}

          public String getDocumentURI() {
            return null;
          }

          public void setDocumentURI(String documentURI) {}

          public Node adoptNode(Node source) throws DOMException {
            return null;
          }

          public DOMConfiguration getDomConfig() {
            return null;
          }

          public void normalizeDocument() {}

          public Node renameNode(Node n, String namespaceURI, String qualifiedName)
              throws DOMException {
            return null;
          }
        };

    StringBuilder xml = new StringBuilder();
    xml.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
    xml.append("<root>");

    if (content_type == 0 || content_type == 1) {

      Map<String, String> params = splitQuery(body);
      Gson gson = new Gson();
      body = gson.toJson(params);
    }

    Boolean success = true;

    try {
      JSONObject json = new JSONObject(body);

      xml.append(XML.toString(json));
      xml.append("</root>");

      DocumentBuilder builder = factory.newDocumentBuilder();

      ByteArrayInputStream input = new ByteArrayInputStream(xml.toString().getBytes("UTF-8"));
      doc = builder.parse(input);

    } catch (Exception e) {
      success = false;
    }

    if (!success) {
      return null;
    } else {

      List<String> headers;

      headers = helpers.analyzeRequest(request).getHeaders();

      Iterator<String> iter = headers.iterator();
      while (iter.hasNext()) {
        if (iter.next().contains("Content-Type")) iter.remove();
      }

      headers.add("Content-Type: application/xml;charset=UTF-8");

      return helpers.buildHttpMessage(headers, prettyPrint(doc).getBytes());
    }
  }
Пример #4
0
  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);
      }
    }
  }
Пример #5
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));
              }
            }
          }
        }
      }
    }
  }