def test_opt_bool(): # Test OptBool creation opt_bool = OptBool(True, "Test Bool Description") assert opt_bool.description == "Test Bool Description" assert opt_bool.display_value == "true" assert opt_bool.value assert opt_bool.__get__(None, None) # Test OptBool setting to false opt_bool.__set__(None, "false") assert opt_bool.display_value == "false" assert not opt_bool.value assert not opt_bool.__get__(None, None) # Test OptBool setting to true opt_bool.__set__(None, "true") assert opt_bool.display_value == "true" assert opt_bool.value assert opt_bool.__get__(None, None) # Test OptBool setting to invalid value try: opt_bool.__set__(None, "Invalid Value") assert False except OptionValidationError: assert True
class HTTPClient(Exploit): """ HTTP Client exploit """ target_protocol = Protocol.HTTP verbosity = OptBool(True, "Verbosity enabled: true/false") ssl = OptBool(False, "SSL enabled: true/false") def http_request(self, method, path, session=requests, **kwargs): 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 get_target_url(self, path=""): if self.ssl: url = "https://" else: url = "http://" url += "{}:{}{}".format(self.target, self.port, path) return url def http_test_connect(self): response = self.http_request( method="GET", path="/" ) if response: return True return False
class FTPClient(Exploit): """ FTP Client exploit """ target_protocol = Protocol.FTP ssl = OptBool("false", "SSL enabled: true/false") verbosity = OptBool("true", "Enable verbose output: true/false") def ftp_create(self): if self.ssl: ftp_client = ftplib.FTP_TLS() else: ftp_client = ftplib.FTP() return ftp_client def ftp_connect(self, retries=1): ftp_client = self.ftp_create() for _ in range(retries): try: ftp_client.connect(self.target, self.port, timeout=FTP_TIMEOUT) except (socket.error, socket.timeout): print_error("Connection error") except Exception as err: print_error(err) else: return ftp_client ftp_client.close() return None def ftp_login(self, username, password): ftp_client = self.ftp_connect() if ftp_client: try: ftp_client.login(username, password) return ftp_client except Exception as err: pass ftp_client.close() return None def ftp_test_connect(self): ftp_client = self.ftp_connect() if ftp_client: ftp_client.close() return True return False
class SNMPClient(Exploit): """ SNMP Client exploit """ target_protocol = Protocol.SNMP verbosity = OptBool(True, "Enable verbose output: true/false") def snmp_get(self, community_string, oid, version=1, retries=0): cmdGen = cmdgen.CommandGenerator() try: errorIndication, errorStatus, errorIndex, varBinds = cmdGen.getCmd( cmdgen.CommunityData(community_string, mpModel=version), cmdgen.UdpTransportTarget((self.target, self.port), timeout=SNMP_TIMEOUT, retries=retries), oid, ) except Exception: return None if errorIndication or errorStatus: print_error( "SNMP invalid community string: '{}'".format(community_string), verbose=self.verbosity) else: print_success("SNMP valid community string found: '{}'".format( community_string), verbose=self.verbosity) return varBinds return None
class FTPClient(Exploit): """ FTP Client exploit option and api """ target_protocol = Protocol.FTP ssl = OptBool(False, "SSL enabled: true/false") verbosity = OptBool(True, "Enable verbose output: true/false") def ftp_create(self, target=None, port=None): ftp_target = target if target else self.target ftp_port = port if port else self.port ftp_client = FTPCli(ftp_target, ftp_port, ssl=self.ssl, verbosity=self.verbosity) return ftp_client
class FTPClient(Exploit): """ FTP Client exploit """ target_protocol = Protocol.FTP ssl = OptBool(False, "SSL enabled: true/false") verbosity = OptBool(True, "Enable verbose output: true/false") def ftp_create(self, target: str=None, port: int=None) -> FTPCli: """ Create FTP client :param str target: target FTP server ip address :param int port: target FTP server port :return FTPCli: FTP client object """ ftp_target = target if target else self.target ftp_port = port if port else self.port ftp_client = FTPCli(ftp_target, ftp_port, ssl=self.ssl, verbosity=self.verbosity) return ftp_client
class TelnetClient(Exploit): """ Telnet Client exploit """ target_protocol = Protocol.TELNET verbosity = OptBool(True, "Enable verbose output: true/false") def telnet_create(self, target=None, port=None): telnet_target = target if target else self.target telnet_port = port if port else self.port telnet_client = TelnetCli(telnet_target, telnet_port, verbosity=self.verbosity) return telnet_client
class UDPClient(Exploit): """ UDP Client exploit """ target_protocol = Protocol.UDP verbosity = OptBool(True, "Enable verbose output: true/false") def udp_create(self, target=None, port=None): udp_target = target if target else self.target udp_port = port if port else self.port udp_client = UDPCli(udp_target, udp_port, verbosity=self.verbosity) return udp_client
class SNMPClient(Exploit): """ SNMP Client exploit """ target_protocol = Protocol.SNMP verbosity = OptBool(True, "Enable verbose output: true/false") def snmp_create(self, target=None, port=None): snmp_target = target if target else self.target snmp_port = port if port else self.port snmp_client = SNMPCli(snmp_target, snmp_port, verbosity=self.verbosity) return snmp_client
class UDPClient(Exploit): """ UDP Client exploit """ target_protocol = Protocol.UDP verbosity = OptBool(True, "Enable verbose output: true/false") def udp_create(self): if is_ipv4(self.target): udp_client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) elif is_ipv6(self.target): udp_client = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) else: print_error("Target address is not valid IPv4 nor IPv6 address", verbose=self.verbosity) return None udp_client.settimeout(UDP_SOCKET_TIMEOUT) return udp_client def udp_send(self, udp_client, data): if udp_client: if type(data) is bytes: try: return udp_client.sendto(data, (self.target, self.port)) except Exception: print_error("Exception while sending data", verbose=self.verbosity) else: print_error("Data to send is not type of bytes", verbose=self.verbosity) return None def udp_recv(self, udp_client, num): if udp_client: try: response = udp_client.recv(num) return response except socket.timeout: print_error("Socket did timeout", verbose=self.verbosity) except socket.error: print_error("Socket err", verbose=self.verbosity) return None def udp_close(self, udp_client): if udp_client: udp_client.close() return None
class SSHClient(Exploit): """ SSH Client exploit """ target_protocol = Protocol.SSH verbosity = OptBool(True, "Enable verbose output: true/false") def ssh_create(self, target: str = None, port: int = None) -> SSHCli: """ Create SSH client :param str target: target SSH server ip address :param int port: target SSH server port :return SSHCli: SSH client object """ ssh_target = target if target else self.target ssh_port = port if port else self.port ssh_client = SSHCli(ssh_target, ssh_port, verbosity=self.verbosity) return ssh_client
class SNMPClient(Exploit): """ SNMP Client exploit """ target_protocol = Protocol.SNMP verbosity = OptBool(True, "Enable verbose output: true/false") def snmp_create(self, target: str=None, port: int=None) -> SNMPCli: """ Create SNMP client :param str target: target SNMP server ip address :param int port: target SNMP server port :return SNMPCli: SNMP client object """ snmp_target = target if target else self.target snmp_port = port if port else self.port snmp_client = SNMPCli(snmp_target, snmp_port, verbosity=self.verbosity) return snmp_client
class TCPClient(Exploit): """ TCP Client exploit """ target_protocol = Protocol.TCP verbosity = OptBool(True, "Enable verbose output: true/false") def tcp_create(self, target: str=None, port: int=None) -> TCPCli: """ Creates TCP client :param str target: target TCP server ip address :param int port: target TCP server port :return TCPCli: TCP client object """ tcp_target = target if target else self.target tcp_port = port if port else self.port tcp_client = TCPCli(tcp_target, tcp_port, verbosity=self.verbosity) return tcp_client
class UDPClient(Exploit): """ UDP Client exploit """ target_protocol = Protocol.UDP verbosity = OptBool(True, "Enable verbose output: true/false") def udp_create(self, target: str = None, port: int = None) -> UDPCli: """ Create UDP client :param str target: target UDP server ip address :param int port: target UDP server port :return UDPCli: UDP client object """ udp_target = target if target else self.target udp_port = port if port else self.port udp_client = UDPCli(udp_target, udp_port, verbosity=self.verbosity) return udp_client
class TelnetClient(Exploit): """ Telnet Client exploit """ target_protocol = Protocol.TELNET verbosity = OptBool(True, "Enable verbose output: true/false") def telnet_create(self, target: str = None, port: int = None) -> TelnetCli: """ Create Telnet client :param str target: target Telnet ip address :param int port: target Telnet port :return TelnetCli: Telnet client object """ telnet_target = target if target else self.target telnet_port = port if port else self.port telnet_client = TelnetCli(telnet_target, telnet_port, verbosity=self.verbosity) return telnet_client
class FTPClient(Exploit): """ FTP Client exploit """ target_protocol = Protocol.FTP ssl = OptBool(False, "SSL enabled: true/false") verbosity = OptBool(True, "Enable verbose output: true/false") def ftp_create(self): if self.ssl: ftp_client = ftplib.FTP_TLS() else: ftp_client = ftplib.FTP() return ftp_client def ftp_connect(self, retries=1): ftp_client = self.ftp_create() for _ in range(retries): try: ftp_client.connect(self.target, self.port, timeout=FTP_TIMEOUT) except (socket.error, socket.timeout): print_error("Connection error", verbose=self.verbosity) except Exception as err: print_error(err, verbose=self.verbosity) else: return ftp_client ftp_client.close() return None def ftp_login(self, username, password): ftp_client = self.ftp_connect() if ftp_client: try: ftp_client.login(username, password) return ftp_client except Exception as err: pass ftp_client.close() return None def ftp_test_connect(self): ftp_client = self.ftp_connect() if ftp_client: ftp_client.close() return True return False def ftp_get_content(self, ftp_client, remote_file): if ftp_client: fp_content = io.BytesIO() ftp_client.retrbinary("RETR {}".format(remote_file), fp_content.write) return fp_content.getvalue() return None def ftp_close(self, ftp_client): if ftp_client: ftp_client.close() return None
class HTTPClient(Exploit): """ HTTP Client provides methods to handle communication with HTTP server """ target_protocol = Protocol.HTTP verbosity = OptBool(True, "Verbosity enabled: true/false") ssl = OptBool(False, "SSL enabled: true/false") 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 get_target_url(self, path: str = "") -> str: """ Get target URL :param str path: path to http server resource :return str: full target url with correct schema """ if self.ssl: url = "https://" else: url = "http://" url += "{}:{}{}".format(self.target, self.port, path) return url def http_test_connect(self) -> bool: """ Test connection to HTTP server :return bool: True if test connection was successful, False otherwise """ response = self.http_request(method="GET", path="/") if response: return True return False
class SSHClient(Exploit): """ SSH Client exploit """ target_protocol = Protocol.SSH verbosity = OptBool("true", "Enable verbose output: true/false") def ssh_create(self): ssh_client = paramiko.SSHClient() ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) return ssh_client def ssh_login(self, username, password, retries=1): ssh_client = self.ssh_create() for _ in range(retries): try: ssh_client.connect(self.target, self.port, timeout=SSH_TIMEOUT, banner_timeout=SSH_TIMEOUT, username=username, password=password, look_for_keys=False) except paramiko.AuthenticationException: print_error("SSH Authentication Failed - Username: '******' Password: '******'".format(username, password), verbose=self.verbosity) ssh_client.close() break except Exception as err: print_error("Err: {}".format(err), verbose=self.verbosity) else: print_success("SSH Authentication Successful - Username: '******' Password: '******'".format(username, password), verbose=self.verbosity) return ssh_client ssh_client.close() return def ssh_login_pkey(self, username, priv_key, retries=1): ssh_client = self.ssh_create() 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 None for _ in range(retries): try: ssh_client.connect(self.target, self.port, timeout=SSH_TIMEOUT, banner_timeout=SSH_TIMEOUT, username=username, pkey=priv_key, look_for_keys=False) except paramiko.AuthenticationException: print_error("Authentication Failed - Username: '******' auth with private key".format(username), verbose=self.verbosity) except Exception as err: print_error("Err: {}".format(err), verbose=self.verbosity) else: print_success("SSH Authentication Successful - Username: '******' with private key".format(username), verbose=self.verbosity) return ssh_client ssh_client.close() return None def ssh_test_connect(self): ssh_client = self.ssh_create() try: ssh_client.connect(self.target, self.port, timeout=SSH_TIMEOUT, username="******", password=random_text(12), look_for_keys=False) except paramiko.AuthenticationException: ssh_client.close() return True except socket.error: print_error("Connection error") ssh_client.close() return False except Exception as err: print_error("Err: {}".format(err)) ssh_client.close() return False def ssh_execute(self, ssh, cmd): ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command(cmd) return ssh_stdout.read() def ssh_get_file(self, ssh, remote_file, local_file): sftp = ssh.open_sftp() sftp.get(remote_file, local_file) def ssh_get_content(self, ssh, remote_file): fp_content = io.BytesIO() sftp = ssh.open_sftp() sftp.getfo(remote_file, fp_content) return fp_content.getvalue() def ssh_send_file(self, ssh, local_file, dest_file): sftp = ssh.open_sftp() sftp.put(local_file, dest_file) def ssh_send_content(self, ssh, content, dest_file): fp_content = io.BytesIO(content) sftp = ssh.open_sftp() sftp.putfo(fp_content, dest_file) def ssh_interactive(self, ssh): if ssh: chan = ssh.invoke_shell() if os.name == "posix": self._posix_shell(chan) else: self._windows_shell(chan) def _posix_shell(self, chan): import termios import tty oldtty = termios.tcgetattr(sys.stdin) try: tty.setraw(sys.stdin.fileno()) tty.setcbreak(sys.stdin.fileno()) chan.settimeout(0.0) while True: r, w, e = select.select([chan, sys.stdin], [], []) if chan in r: try: x = str(chan.recv(1024), "utf-8") if len(x) == 0: break sys.stdout.write(x) sys.stdout.flush() except socket.timeout: pass if sys.stdin in r: x = sys.stdin.read(1) if len(x) == 0: break chan.send(x) finally: termios.tcsetattr(sys.stdin,termios.TCSADRAIN, oldtty) return def _windows_shell(self, chan): 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("Err: {}".format(err))
class TelnetClient(Exploit): """ Telnet Client exploit """ target_protocol = Protocol.TELNET verbosity = OptBool("true", "Enable verbose output: true/false") def telnet_connect(self, target=None, port=None): if not target: target = self.target if not port: port = self.port try: telnet_client = telnetlib.Telnet(target, port, timeout=TELNET_TIMEOUT) return telnet_client except Exception: pass return None def telnet_login(self, username, password, target=None, port=None, retries=1): if not target: target = self.target if not port: port = self.port for _ in range(retries): try: telnet_client = self.telnet_connect(target=target, port=port) telnet_client.expect( [b"Login: "******"login: "******"Username: "******"username: "******"utf-8") + b"\r\n") telnet_client.expect([b"Password: "******"password: "******"utf-8") + b"\r\n") telnet_client.write(b"\r\n") (i, obj, res) = 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( "Telnet Authentication Successful - Username: '******' Password: '******'" .format(username, password), verbose=self.verbosity) return telnet_client else: print_error( "Telnet Authentication Failed - Username: '******' Password: '******'" .format(username, password), verbose=self.verbosity) break except EOFError: print_error("Telnet connection error") except Exception as err: print_error(err) return None def telnet_test_connect(self): try: telnet_client = telnetlib.Telnet(self.target, self.port, timeout=TELNET_TIMEOUT) telnet_client.expect( [b"Login: "******"login: "******"Username: "******"username: "******"utf-8") return telnet_client.read_until(data, 5) return None def telnet_write(self, telnet_client, data): if telnet_client: if type(data) is str: data = bytes(data, "utf-8") return telnet_client.write(data, 5) return None
def test_opt_bool(): # Test OptBool creation opt_bool = OptBool(True, "Test Bool Description") assert opt_bool.description == "Test Bool Description" assert opt_bool.display_value == "true" assert opt_bool.value assert opt_bool.__get__(None, None) # Test OptBool setting to false opt_bool.__set__(None, "false") assert opt_bool.display_value == "false" assert not opt_bool.value assert not opt_bool.__get__(None, None) # Test OptBool setting to true opt_bool.__set__(None, "true") assert opt_bool.display_value == "true" assert opt_bool.value assert opt_bool.__get__(None, None) # Test OptBool setting to invalid value try: opt_bool.__set__(None, "Invalid Value") assert False except OptionValidationError: assert True
class TCPClient(Exploit): """ TCP Client exploit """ target_protocol = Protocol.TCP verbosity = OptBool(True, "Enable verbose output: true/false") def tcp_create(self): if is_ipv4(self.target): tcp_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) elif is_ipv6(self.target): 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 tcp_client.settimeout(TCP_SOCKET_TIMEOUT) return tcp_client def tcp_connect(self): try: tcp_client = self.tcp_create() tcp_client.connect((self.target, self.port)) print_status("Connection established", verbose=self.verbosity) return tcp_client except Exception as err: print_error("Could not connect", verbose=self.verbosity) print_error(err, verbose=self.verbosity) return None def tcp_send(self, tcp_client, data): if tcp_client: if type(data) is bytes: return tcp_client.send(data) else: print_error("Data to send is not type of bytes", verbose=self.verbosity) return None def tcp_recv(self, tcp_client, num): if tcp_client: try: response = b"" received = 0 while received < num: tmp = tcp_client.recv(num - received) if tmp: received += len(tmp) response += tmp else: break return response except socket.timeout: print_error("Socket did timeout", verbose=self.verbosity) except socket.error: print_error("Socket error", verbose=self.verbosity) return None def tcp_close(self, tcp_client): if tcp_client: tcp_client.close() return None