Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FTP Check #8

Open
freb opened this issue May 19, 2017 · 8 comments
Open

FTP Check #8

freb opened this issue May 19, 2017 · 8 comments

Comments

@freb
Copy link
Contributor

freb commented May 19, 2017

Nessus has this plugin (https://www.tenable.com/plugins/index.php?view=single&id=34324) that doesn't always fire. It would be nice to have a plugin for nmap to double check. FTP has a few different modes. There is FTPS which runs over an always encrypted connection. There is normal unencrypted connections over 20/21 and then there is the AUTH TLS which upgrades the connection. It would be nice to tease out exactly what is supported.

@freb
Copy link
Contributor Author

freb commented Mar 14, 2019

If you look at the [FTP library[(https://nmap.org/nsedoc/lib/ftp.html) for nmap, it is super simple. Just a few functions wrapping the lower level comm library. It should be easy to add this functionality.

@freb
Copy link
Contributor Author

freb commented Mar 14, 2019

Content of ftp_clear_text_credentials.nasl:

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

include("compat.inc");

if (description)
{
 script_id(34324);
 script_version("$Revision: 1.25 $");
 script_cvs_date("$Date: 2016/12/08 20:42:13 $");

 script_name(english:"FTP Supports Cleartext Authentication");
 script_summary(english:"Check if the FTP server accepts passwords in cleartext.");


 script_set_attribute(attribute:"synopsis", value:"Authentication credentials might be intercepted.");
 script_set_attribute(attribute:"description", value:
"The remote FTP server allows the user's name and password to be
transmitted in cleartext, which could be intercepted by a network
sniffer or a man-in-the-middle attack.");
 script_set_attribute(attribute:"solution", value:
"Switch to SFTP (part of the SSH suite) or FTPS (FTP over SSL/TLS). In
the latter case, configure the server so that control connections are
encrypted.");
 script_set_cvss_base_vector("CVSS2#AV:N/AC:H/Au:N/C:P/I:N/A:N");
 script_cwe_id(
   522,	# Insufficiently Protected Credentials
   523,	# Unprotected Transport of Credentials
   928, # Weaknesses in OWASP Top Ten 2013
   930  # OWASP Top Ten 2013 Category A2 - Broken Authentication and Session Management
 );

 script_set_attribute(attribute:"plugin_publication_date", value:"2008/10/01");

 script_set_attribute(attribute:"plugin_type", value:"remote");
 script_end_attributes();

 script_category(ACT_GATHER_INFO);

 script_copyright(english:"This script is Copyright (C) 2008-2016 Tenable Network Security, Inc.");
 script_family(english:"FTP");

 script_dependencies("ftpserver_detect_type_nd_version.nasl", "ftp_starttls.nasl");
 script_require_ports("Services/ftp", 21);

 exit(0);
}

include("audit.inc");
include("global_settings.inc");
include("misc_func.inc");
include("ftp_func.inc");

user = get_kb_item('ftp/login');
if (strlen(user) == 0 || user == 'anonymous' || user == 'ftp')
{
  if (supplied_logins_only)  audit(AUDIT_SUPPLIED_LOGINS_ONLY);

  user = rand_str(length:8, charset:'abcdefghijklmnopqrstuvwxyz');
}
pass = get_kb_item('ftp/password');
if (strlen(pass) == 0) pass = '[email protected]';

port = get_ftp_port(default: 21);

banner = get_ftp_banner(port: port);
if (strlen(banner) == 0) exit(1, "No FTP banner on port "+port+".");
if (banner =~ '^[45][0-9][0-9][ -]')
 exit(1, "The FTP server on port "+port+" rejects our connections.");

trp = get_port_transport(port);
if (trp > ENCAPS_IP)
 exit(0, "The FTP server on port "+port+" is running through SSL/TLS.");

soc = open_sock_tcp(port);
if (! soc) audit(AUDIT_SOCK_FAIL, port);

b = ftp_recv_line(socket: soc);
if (b =~ '^2[0-9][0-9][ -]')
{
 u = ftp_send_cmd(socket: soc, cmd: 'USER '+user);
 if (u =~ '^3[0-9][0-9][ -]')
 {
  if (report_verbosity < 1)
  {
    if ( get_kb_item("Settings/PCI_DSS") ) set_kb_item(name:"PCI/ClearTextCreds/" + port,
						value:"The remote FTP server allows the credentials to be transmitted in clear text.");
    security_note(port);
  }
  else
  {
   if (get_kb_item("ftp/"+port+"/starttls")) report =
'\nAlthough this FTP server supports \'AUTH TLS\', it is not mandatory
and USER and PASS may be sent without switching to TLS.';
   else report = '\nThis FTP server does not support \'AUTH TLS\'.';

   if ( get_kb_item("Settings/PCI_DSS") ) set_kb_item(name:"PCI/ClearTextCreds/" + port, value:report);
   security_note(port:port, extra:report);
  }

  # Make FTPD happy
  b = ftp_send_cmd(socket: soc, cmd: 'PASS '+pass);
 }
}
ftp_close(socket: soc);

@freb
Copy link
Contributor Author

freb commented Aug 22, 2019

There are also servers which support Auth TLS but don't mandate it. See example in .nmap-commands.

@freb
Copy link
Contributor Author

freb commented Aug 23, 2019

Accepting USER and PASS without upgrading connection means plaintext support:

220 ProFTPD Server (ProFTPD) [x.x.x.41]
USER pentest
331 Password required for pentest
PASS pentest
530 Login incorrect.
quit
221 Goodbye.

@freb
Copy link
Contributor Author

freb commented Aug 26, 2019

Supporting pltainext connection, but not login:

telnet x.x.x.177 1`
Trying x.x.x.177...
Connected to x.x.x.177.
Escape character is '^]'.
220 FTP Server Ready
USER asdf
550 SSL/TLS required on the control channel
quit
221 Goodbye.
Connection closed by foreign host.

You should use the Auth command over the plain control connection initialize a secure connection. Something like:

Trying x.x.x.177...
Connected to x.x.x.177.
Escape character is '^]'.
220 FTP Server Ready
AUTH
504 AUTH requires at least one argument
AUTH TLS
234 AUTH TLS successful
USER asdf
550 TLS handshake failed
Connection closed by foreign host.

@freb
Copy link
Contributor Author

freb commented Aug 27, 2019

There is also the ftp_starttls.nasl, FTP Service AUTH TLS Command Support which will attempt the actual connection. It will report on whether it was able to establish an encrypted connection and whether they are likely supported:

The remote FTP service responded to the 'AUTH TLS' command with a
'234' response code, suggesting that it supports that command.  However,
we failed to negotiate a TLS connection or get the associated SSL
certificate, perhaps because of a network connectivity problem or the
service requires a peer certificate as part of the negotiation.

@freb
Copy link
Contributor Author

freb commented Nov 22, 2019

One more wrinkle. Just encountered a server that will let connect over plaintext, but then when you attempt USER asdf, it drops the connection with:

Connected to x.x.x.x
Escape character is '^]'.
220 (vsFTPd 3.0.2)
USER asdf
530 Non-anonymous sessions must use encryption.
Connection closed by foreign host.

In order of severity, you have:

  1. plaintext ftp, no support for AUTH TLS, permits logins
  2. plaintext ftp, supports AUTH TLS, permits logins
  3. plaintext ftp for anon only, supports AUTH TLS, permits logins only after AUTH TLS
  4. no plaintext ftp

@freb
Copy link
Contributor Author

freb commented Feb 12, 2020

Another response:

USER asdf
530 This server does not allow plain FTP. You have to use FTP over TLS.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant