DEV Community

Cover image for HTTP - File Transfers for CTFs and Red-Teamers Pt. 1
Adam Katora
Adam Katora

Posted on

HTTP - File Transfers for CTFs and Red-Teamers Pt. 1

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.


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,, 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,, they start an HTTP server with python -m http.server 80 from the directory containing file.txt.

On the victim's machine, the attacker runs the command wget, 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.

HTTP Unidirectional

Opsec Considerations

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.

File Transfer Scenarios

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.

Linux Attacker -> Linux 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 sudo.

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 which downloads the file from the attacker, onto the victim.

File Transfer: Linux Attacker to Linux Victim

Linux Victim -> Linux Attacker

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

Linux victim to Linux attacker

Linux Attacker -> Windows Victim

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.

Linux Attacker to Windows Victim

Windows Victim -> Linux Attacker

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.

Windows Victim to Linux Attacker

Linux HTTP Server Options:

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, == But, != 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

With 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
Enter fullscreen mode Exit fullscreen mode

The 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
Enter fullscreen mode Exit fullscreen mode

Python 2

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
Enter fullscreen mode Exit fullscreen mode

Unlike the http.server module, SimpleHTTPServer does not support a flag to specify the directory to serve files from. If you want to achieve that result, you'll have to use pushd and popd:

# Will serve files from /var/www/html on Port 80
pushd /var/www/html; python -m SimpleHTTPServer 80; popd
Enter fullscreen mode Exit fullscreen mode


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 /etc/apache2/apache2.conf.

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 /var/www/html/ directory.

Starting Apache on Kali:

# Will start an apache server with the options from /etc/apache2/apache2.conf
sudo service apache2 start
Enter fullscreen mode Exit fullscreen mode

Stopping Apache on Kali:

# Will stop an already running apache server
sudo service apache2 stop
Enter fullscreen mode Exit fullscreen mode


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:

Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Stopping Nginx on Kali:

# Will stop an already running nginx server
sudo service nginx stop
Enter fullscreen mode Exit fullscreen mode


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
Enter fullscreen mode Exit fullscreen mode

Linux HTTP Client Options:

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode


Another program that's very commonly found on Linux systems is curl. Unlike wget, curl defaults to displaying the output in the terminal instead of downloading files, however, you can easily save files with the --output flag.

curl --output file.txt
Enter fullscreen mode Exit fullscreen mode

Windows HTTP Server Options:

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:

iisreset /start
Enter fullscreen mode Exit fullscreen mode

Start IIS - powershell:

Start-IISSite -Name "Default Web Site"
Enter fullscreen mode Exit fullscreen mode

Python 3

If 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 80
Enter fullscreen mode Exit fullscreen mode

Windows HTTP Client Options:

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.

Invoke-WebRequest - Powershell

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 -OutFile file.txt
Enter fullscreen mode Exit fullscreen mode

Certutil.exe - cmd / Powershell

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 file.txt
Enter fullscreen mode Exit fullscreen mode

Potential Firewall Issues

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.

Top comments (0)