You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The Ftpd::DiskFileSystem class suffers from a denial of service vulnerability and local file system path disclosure issues when the local file system path supplied in the constructor to be used as the base directory for the FTP server does not end with a trailing /.
This also includes temporary directories generated with Ftpd::TempDir.make which do not end with a trailing /. For example:
Tested on latest version of ftpd from GitHub repository (2.0.1).
The likelihood of this issue arising is increased due to the example code in the examples directory and the README which do not make use of a trailing /:
An excerpt from the README is shown below. Note the lack of the trailing /.
Here's a simple example FTP script to reproduce these errors:
#!/usr/bin/env rubyrequire'ftpd'require'tmpdir'classDriverdefauthenticate(user,password)trueenddeffile_system(user)Ftpd::DiskFileSystem.new('/var/tmp/ftp')# note: no trailing /endenddriver=Driver.newserver=Ftpd::FtpServer.new(driver)server.interface='0.0.0.0'server.port=21server.log=Logger.new($stdout)server.startputs"Server listening on port #{server.bound_port}"gets
Denial of Service
It is possible to delete the base directory thus preventing users from uploading any additional files.
ftp> rmdir .
250 RMD command successful
Likewise, specifying rmdir .. will also delete the directory (note: it does NOT traverse and delete the parent directory, which is nice).
Various commands leak the local file system path of the ftpd base directory which may assist an attacker with further attacks against the system. This may also leak sensitive information in the event that the file system path contains sensitive information, such as client names, unique identifiers, PII, etc.
ftp> get . asdf
local: asdf remote: .
200 PORT command successful
150 Opening BINARY mode data connection
550 Is a directory @ io_fread - /var/tmp/ftp
ftp> get .. asdf
local: asdf remote: ..
200 PORT command successful
150 Opening BINARY mode data connection
550 Is a directory @ io_fread - /var/tmp/ftp
ftp> del .
550 Is a directory @ unlink_internal - /var/tmp/ftp
ftp> del ..
550 Is a directory @ unlink_internal - /var/tmp/ftp
Although not directly related to the trailing slash issue, it's worth mentioning that attempting to delete a non-empty directory also discloses the local file system path.
ftp> ls asdf
200 PORT command successful
150 Opening ASCII mode data connection
-rw-r--r-- 1 root root 242 May 13 04:12 asdf
226 Transfer complete
ftp> rmdir asdf
550 Directory not empty @ dir_s_rmdir - /var/tmp/ftp/asdf
Notes
Note that these issues are also present when usnig Ftpd::TempDir.make
Here's some example output demonstrating some of these issues using the example code which makes use of Ftpd::TempDir.make.
Connected to 127.0.0.1.
220 wconrad/ftpd 2.0.1
Name (127.0.0.1:root): root
331 Password required
Password:
230 Logged in
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
200 PORT command successful
150 Opening ASCII mode data connection
-rw-r--r-- 1 root root 52 May 13 03:42 README
226 Transfer complete
ftp> del .
550 Is a directory @ unlink_internal - /tmp/d20170513-60051-1j26lxs
ftp> ls
200 PORT command successful
150 Opening ASCII mode data connection
-rw-r--r-- 1 root root 52 May 13 03:42 README
226 Transfer complete
ftp> rmdir .
550 Directory not empty @ dir_s_rmdir - /tmp/d20170513-60051-1j26lxs
ftp> ls
200 PORT command successful
150 Opening ASCII mode data connection
-rw-r--r-- 1 root root 52 May 13 03:42 README
226 Transfer complete
ftp> del README
250 DELE command successful
ftp> rmdir .
250 RMD command successful
ftp> ls
200 PORT command successful
150 Opening ASCII mode data connection
226 Transfer complete
ftp>
ftp> put /etc/hosts asdf
local: /etc/hosts remote: asdf
200 PORT command successful
550 No such file or directory
ftp> ls
200 PORT command successful
150 Opening ASCII mode data connection
226 Transfer complete
ftp>
Mitigation
To prevent disclosure of the file path, ensure 550 errors do not return the underlying error to the client.
To prevent denial of service by deleting the base directory, ensure the file system path specified in the Ftpd::DiskFileSystem constructor always makes use of a trailing slash /.
When the base path is specified with a trailing slash, a 550 Access denied error is returned in each instance identified above.
For example:
ftp> rmdir .
550 Access denied
The text was updated successfully, but these errors were encountered:
The
Ftpd::DiskFileSystem
class suffers from a denial of service vulnerability and local file system path disclosure issues when the local file system path supplied in the constructor to be used as the base directory for the FTP server does not end with a trailing/
.This also includes temporary directories generated with
Ftpd::TempDir.make
which do not end with a trailing/
. For example:Tested on latest version of ftpd from GitHub repository (2.0.1).
The likelihood of this issue arising is increased due to the example code in the examples directory and the README which do not make use of a trailing
/
:An excerpt from the README is shown below. Note the lack of the trailing
/
.Steps to Reproduce
Here's a simple example FTP script to reproduce these errors:
Denial of Service
It is possible to delete the base directory thus preventing users from uploading any additional files.
Likewise, specifying
rmdir ..
will also delete the directory (note: it does NOT traverse and delete the parent directory, which is nice).Here's a related excerpt from the server log:
Local File System Path Disclosure
Various commands leak the local file system path of the ftpd base directory which may assist an attacker with further attacks against the system. This may also leak sensitive information in the event that the file system path contains sensitive information, such as client names, unique identifiers, PII, etc.
Although not directly related to the trailing slash issue, it's worth mentioning that attempting to delete a non-empty directory also discloses the local file system path.
Notes
Note that these issues are also present when usnig
Ftpd::TempDir.make
Here's some example output demonstrating some of these issues using the example code which makes use of
Ftpd::TempDir.make
.Mitigation
To prevent disclosure of the file path, ensure
550
errors do not return the underlying error to the client.To prevent denial of service by deleting the base directory, ensure the file system path specified in the
Ftpd::DiskFileSystem
constructor always makes use of a trailing slash/
.When the base path is specified with a trailing slash, a
550 Access denied
error is returned in each instance identified above.For example:
The text was updated successfully, but these errors were encountered: