def server_ssh_connect(self): """ Connect to the remote SMTP server over SSH and configure port forwarding with :py:class:`.SSHTCPForwarder` for tunneling SMTP traffic. :return: The connection status. :rtype: bool """ server = utilities.server_parse(self.config['ssh_server'], 22) username = self.config['ssh_username'] password = self.config['ssh_password'] remote_server = utilities.server_parse(self.config['smtp_server'], 25) local_port = random.randint(2000, 6000) try: self.ssh_forwarder = SSHTCPForwarder( server, username, password, local_port, remote_server, preferred_private_key=self.config.get('ssh_preferred_key')) self.ssh_forwarder.start() time.sleep(0.5) except: self.logger.warning('failed to connect to remote ssh server') return False self.smtp_server = ('localhost', local_port) return True
def server_ssh_connect(self): server = utilities.server_parse(self.config['ssh_server'], 22) username = self.config['ssh_username'] password = self.config['ssh_password'] remote_server = utilities.server_parse(self.config['smtp_server'], 25) local_port = random.randint(2000, 6000) try: self.ssh_forwarder = SSHTCPForwarder(server, username, password, local_port, remote_server, preferred_private_key=self.config.get('ssh_preferred_key')) self.ssh_forwarder.start() time.sleep(0.5) except: self.logger.warning('failed to connect to remote ssh server') return False self.smtp_server = ('localhost', local_port) return True
def __init__(self, config, target_file, rpc, tab=None): """ :param dict config: The King Phisher client configuration. :param str target_file: The CSV formatted file to read message targets from. :param tab: The GUI tab to report information to. :type tab: :py:class:`.MailSenderSendTab` :param rpc: The client's connected RPC instance. :type rpc: :py:class:`.KingPhisherRPCClient` """ super(MailSenderThread, self).__init__() self.daemon = True self.logger = logging.getLogger('KingPhisher.Client.' + self.__class__.__name__) self.config = config self.target_file = target_file """The name of the target file in CSV format.""" self.tab = tab """The optional :py:class:`.MailSenderSendTab` instance for reporting status messages to the GUI.""" self.rpc = rpc self._ssh_forwarder = None self.smtp_connection = None """The :py:class:`smtplib.SMTP` connection instance.""" self.smtp_server = utilities.server_parse(self.config['smtp_server'], 25) self.running = threading.Event() """A :py:class:`threading.Event` object indicating if emails are being sent.""" self.paused = threading.Event() """A :py:class:`threading.Event` object indicating if the email sending operation is or should be paused.""" self.should_exit = threading.Event() self.max_messages_per_minute = float(self.config.get('smtp_max_send_rate', 0.0)) self._mime_attachments = None
def __init__(self, config, target_file, rpc, tab=None): """ :param dict config: The King Phisher client configuration. :param str target_file: The CSV formatted file to read message targets from. :param tab: The GUI tab to report information to. :type tab: :py:class:`.MailSenderSendTab` :param rpc: The client's connected RPC instance. :type rpc: :py:class:`.KingPhisherRPCClient` """ super(MailSenderThread, self).__init__() self.daemon = True self.logger = logging.getLogger('KingPhisher.Client.' + self.__class__.__name__) self.config = config self.target_file = target_file """The name of the target file in CSV format.""" self.tab = tab """The optional :py:class:`.MailSenderSendTab` instance for reporting status messages to the GUI.""" self.rpc = rpc self.ssh_forwarder = None """The :py:class:`.SSHTCPForwarder` instance for tunneling traffic to the SMTP server.""" self.smtp_connection = None """The :py:class:`smtplib.SMTP` connection instance.""" self.smtp_server = utilities.server_parse(self.config['smtp_server'], 25) self.running = threading.Event() """A :py:class:`threading.Event` object indicating if emails are being sent.""" self.paused = threading.Event() """A :py:class:`threading.Event` object indicating if the email sending operation is or should be paused.""" self.should_exit = threading.Event() self.max_messages_per_minute = float( self.config.get('smtp_max_send_rate', 0.0)) self._mime_attachments = None
def server_ssh_connect(self): """ Connect to the remote SMTP server over SSH and configure port forwarding with :py:class:`.SSHTCPForwarder` for tunneling SMTP traffic. :return: The connection status. :rtype: bool """ server = utilities.server_parse(self.config['ssh_server'], 22) username = self.config['ssh_username'] password = self.config['ssh_password'] remote_server = utilities.server_parse(self.config['smtp_server'], 25) local_port = random.randint(2000, 6000) try: self._ssh_forwarder = SSHTCPForwarder(server, username, password, local_port, remote_server, preferred_private_key=self.config.get('ssh_preferred_key')) self._ssh_forwarder.start() time.sleep(0.5) except Exception: self.logger.warning('failed to connect to remote ssh server') return False self.smtp_server = ('localhost', local_port) return True
def __init__(self, config, target_file, tab, rpc): super(MailSenderThread, self).__init__() self.logger = logging.getLogger('KingPhisher.Client.' + self.__class__.__name__) self.config = config self.target_file = target_file self.tab = tab self.rpc = rpc self.ssh_forwarder = None self.smtp_connection = None self.smtp_server = utilities.server_parse(self.config['smtp_server'], 25) self.running = threading.Event() self.paused = threading.Event() self.should_exit = threading.Event() self.max_messages_per_minute = float(self.config.get('smtp_max_send_rate', 0.0))
def signal_login_dialog_response(self, dialog, response, glade_dialog): server_version_info = None title_rpc_error = 'Failed To Connect To The King Phisher RPC Service' if response == Gtk.ResponseType.CANCEL or response == Gtk.ResponseType.DELETE_EVENT: dialog.destroy() self.emit('exit') return True glade_dialog.objects_save_to_config() server = utilities.server_parse(self.config['server'], 22) username = self.config['server_username'] password = self.config['server_password'] if server[0] == 'localhost' or (utilities.is_valid_ip_address( server[0]) and ipaddress.ip_address(server[0]).is_loopback): local_port = self.config['server_remote_port'] self.logger.info("connecting to local king-phisher instance") else: local_port = self._create_ssh_forwarder(server, username, password) if not local_port: return self.rpc = KingPhisherRPCClient( ('localhost', local_port), username=username, password=password, use_ssl=self.config.get('server_use_ssl')) if self.config.get('rpc.serializer'): try: self.rpc.set_serializer(self.config['rpc.serializer']) except ValueError as error: self.logger.error( "failed to set the rpc serializer, error: '{0}'".format( error.message)) connection_failed = True try: assert self.rpc('client/initialize') server_version_info = self.rpc('version') assert server_version_info != None except AdvancedHTTPServerRPCError as err: if err.status == 401: self.logger.warning( 'failed to authenticate to the remote king phisher service' ) gui_utilities.show_dialog_error( title_rpc_error, self, 'The server responded that the credentials are invalid.') else: self.logger.warning( 'failed to connect to the remote rpc server with http status: ' + str(err.status)) gui_utilities.show_dialog_error( title_rpc_error, self, 'The server responded with HTTP status: ' + str(err.status)) except socket.error as error: gui_utilities.show_dialog_exc_socket_error(error, self) except Exception as error: self.logger.warning('failed to connect to the remote rpc service') gui_utilities.show_dialog_error( title_rpc_error, self, 'Ensure that the King Phisher Server is currently running.') else: connection_failed = False finally: if connection_failed: self.rpc = None self.server_disconnect() return server_rpc_api_version = server_version_info.get('rpc_api_version', -1) if isinstance(server_rpc_api_version, int): # compatibility with pre-0.2.0 version server_rpc_api_version = (server_rpc_api_version, 0) self.logger.info( "successfully connected to the king phisher server (version: {0} rpc api version: {1}.{2})" .format(server_version_info['version'], server_rpc_api_version[0], server_rpc_api_version[1])) self.server_local_port = local_port error_text = None if server_rpc_api_version[0] < version.rpc_api_version.major or ( server_rpc_api_version[0] == version.rpc_api_version.major and server_rpc_api_version[1] < version.rpc_api_version.minor): error_text = 'The server is running an old and incompatible version.' error_text += '\nPlease update the remote server installation.' elif server_rpc_api_version[0] > version.rpc_api_version.major: error_text = 'The client is running an old and incompatible version.' error_text += '\nPlease update the local client installation.' if error_text: gui_utilities.show_dialog_error( 'The RPC API Versions Are Incompatible', self, error_text) self.server_disconnect() return dialog.destroy() self.emit('server-connected') return
def signal_login_dialog_response(self, dialog, response, glade_dialog): server_version_info = None title_rpc_error = 'Failed To Connect To The King Phisher RPC Service' if response == Gtk.ResponseType.CANCEL or response == Gtk.ResponseType.DELETE_EVENT: dialog.destroy() self.emit('exit') return True glade_dialog.objects_save_to_config() server = utilities.server_parse(self.config['server'], 22) username = self.config['server_username'] password = self.config['server_password'] if server[0] == 'localhost' or (utilities.is_valid_ip_address(server[0]) and ipaddress.ip_address(server[0]).is_loopback): local_port = self.config['server_remote_port'] self.logger.info("connecting to local king-phisher instance") else: local_port = self._create_ssh_forwarder(server, username, password) if not local_port: return self.rpc = KingPhisherRPCClient(('localhost', local_port), username=username, password=password, use_ssl=self.config.get('server_use_ssl')) if self.config.get('rpc.serializer'): try: self.rpc.set_serializer(self.config['rpc.serializer']) except ValueError as error: self.logger.error("failed to set the rpc serializer, error: '{0}'".format(error.message)) connection_failed = True try: assert self.rpc('client/initialize') server_version_info = self.rpc('version') assert server_version_info != None except AdvancedHTTPServerRPCError as err: if err.status == 401: self.logger.warning('failed to authenticate to the remote king phisher service') gui_utilities.show_dialog_error(title_rpc_error, self, 'The server responded that the credentials are invalid.') else: self.logger.warning('failed to connect to the remote rpc server with http status: ' + str(err.status)) gui_utilities.show_dialog_error(title_rpc_error, self, 'The server responded with HTTP status: ' + str(err.status)) except socket.error as error: gui_utilities.show_dialog_exc_socket_error(error, self) except Exception as error: self.logger.warning('failed to connect to the remote rpc service') gui_utilities.show_dialog_error(title_rpc_error, self, 'Ensure that the King Phisher Server is currently running.') else: connection_failed = False finally: if connection_failed: self.rpc = None self.server_disconnect() return server_rpc_api_version = server_version_info.get('rpc_api_version', -1) if isinstance(server_rpc_api_version, int): # compatibility with pre-0.2.0 version server_rpc_api_version = (server_rpc_api_version, 0) self.logger.info("successfully connected to the king phisher server (version: {0} rpc api version: {1}.{2})".format(server_version_info['version'], server_rpc_api_version[0], server_rpc_api_version[1])) self.server_local_port = local_port error_text = None if server_rpc_api_version[0] < version.rpc_api_version.major or (server_rpc_api_version[0] == version.rpc_api_version.major and server_rpc_api_version[1] < version.rpc_api_version.minor): error_text = 'The server is running an old and incompatible version.' error_text += '\nPlease update the remote server installation.' elif server_rpc_api_version[0] > version.rpc_api_version.major: error_text = 'The client is running an old and incompatible version.' error_text += '\nPlease update the local client installation.' if error_text: gui_utilities.show_dialog_error('The RPC API Versions Are Incompatible', self, error_text) self.server_disconnect() return dialog.destroy() self.emit('server-connected') return
def server_connect(self): """ Perform the connection setup as part of the server connection initialization process. This will display a GUI window requesting the connection information. An :py:class:`.SSHTCPForwarder` instance is created and configured for tunneling traffic to the King Phisher server. This also verifies that the RPC API version running on the server is compatible with the client. :return: Whether or not the connection attempt was successful. :rtype: bool """ server_version_info = None title_ssh_error = 'Failed To Connect To The SSH Service' title_rpc_error = 'Failed To Connect To The King Phisher RPC Service' while True: if self.ssh_forwarder: self.ssh_forwarder.stop() self.ssh_forwarder = None self.logger.info('stopped ssh port forwarding') login_dialog = dialogs.KingPhisherClientLoginDialog( self.config, self) login_dialog.objects_load_from_config() response = login_dialog.interact() if response == Gtk.ResponseType.CANCEL: return False server = utilities.server_parse(self.config['server'], 22) username = self.config['server_username'] password = self.config['server_password'] server_remote_port = self.config['server_remote_port'] local_port = random.randint(2000, 6000) try: self.ssh_forwarder = SSHTCPForwarder( server, username, password, local_port, ('127.0.0.1', server_remote_port), preferred_private_key=self.config['ssh_preferred_key']) self.ssh_forwarder.start() time.sleep(0.5) self.logger.info('started ssh port forwarding') except paramiko.AuthenticationException: self.logger.warning( 'failed to authenticate to the remote ssh server') gui_utilities.show_dialog_error( title_ssh_error, self, 'The server responded that the credentials are invalid') continue except socket.error as error: error_number, error_message = error.args if error_number == 111: gui_utilities.show_dialog_error( title_ssh_error, self, 'The server refused the connection') else: gui_utilities.show_dialog_error( title_ssh_error, self, "Socket error #{0} ({1})".format( (error_number or 'NOT-SET'), error_message)) continue except Exception: self.logger.warning( 'failed to connect to the remote ssh server') gui_utilities.show_dialog_error(title_ssh_error, self) continue self.rpc = KingPhisherRPCClient( ('localhost', local_port), username=username, password=password, use_ssl=self.config.get('server_use_ssl')) if self.config.get('rpc.serializer'): try: self.rpc.set_serializer(self.config['rpc.serializer']) except ValueError as error: self.logger.error( "failed to set the rpc serializer, error: '{0}'". format(error.message)) try: assert (self.rpc('client/initialize')) server_version_info = self.rpc('version') except AdvancedHTTPServerRPCError as err: if err.status == 401: self.logger.warning( 'failed to authenticate to the remote king phisher service' ) gui_utilities.show_dialog_error( title_rpc_error, self, 'The server responded that the credentials are invalid' ) else: self.logger.warning( 'failed to connect to the remote rpc server with http status: ' + str(err.status)) gui_utilities.show_dialog_error( title_rpc_error, self, 'The server responded with HTTP status: ' + str(err.status)) continue except: self.logger.warning( 'failed to connect to the remote rpc service') gui_utilities.show_dialog_error( title_rpc_error, self, 'Ensure that the King Phisher Server is currently running') continue break assert (server_version_info != None) server_rpc_api_version = server_version_info.get('rpc_api_version', -1) self.logger.info( "successfully connected to the king phisher server (version: {0} rpc api version: {1})" .format(server_version_info['version'], server_rpc_api_version)) self.server_local_port = local_port if server_rpc_api_version != version.rpc_api_version: if version.rpc_api_version < server_rpc_api_version: secondary_text = 'The local client is not up to date with the server version.' else: secondary_text = 'The remote server is not up to date with the client version.' secondary_text += '\nPlease ensure that both the client and server are fully up to date.' gui_utilities.show_dialog_error( 'The RPC API Versions Are Incompatible', self, secondary_text) self.server_disconnect() return False return True
def server_connect(self): import socket server_version_info = None while True: if self.ssh_forwarder: self.ssh_forwarder.stop() self.ssh_forwarder = None self.logger.info('stopped ssh port forwarding') login_dialog = KingPhisherClientLoginDialog(self.config, self) login_dialog.objects_load_from_config() response = login_dialog.interact() if response == Gtk.ResponseType.CANCEL: return False server = utilities.server_parse(self.config['server'], 22) username = self.config['server_username'] password = self.config['server_password'] server_remote_port = self.config.get('server_remote_port', 80) local_port = random.randint(2000, 6000) try: self.ssh_forwarder = SSHTCPForwarder(server, username, password, local_port, ('127.0.0.1', server_remote_port), preferred_private_key=self.config.get('ssh_preferred_key')) self.ssh_forwarder.start() time.sleep(0.5) self.logger.info('started ssh port forwarding') except paramiko.AuthenticationException: self.logger.warning('failed to authenticate to the remote ssh server') gui_utilities.show_dialog_error('Invalid Credentials', self) continue except: self.logger.warning('failed to connect to the remote ssh server') gui_utilities.show_dialog_error('Failed To Connect To The SSH Service', self) continue self.rpc = KingPhisherRPCClient(('localhost', local_port), username=username, password=password) try: server_version_info = self.rpc('version') assert(self.rpc('client/initialize')) except AdvancedHTTPServerRPCError as err: if err.status == 401: self.logger.warning('failed to authenticate to the remote king phisher service') gui_utilities.show_dialog_error('Invalid Credentials', self) else: self.logger.warning('failed to connect to the remote rpc server with http status: ' + str(err.status)) gui_utilities.show_dialog_error('Failed To Connect To The King Phisher RPC Service', self, 'The server responded with HTTP status: ' + str(err.status)) continue except: self.logger.warning('failed to connect to the remote rpc service') gui_utilities.show_dialog_error('Failed To Connect To The King Phisher RPC Service', self) continue break assert(server_version_info != None) server_rpc_api_version = server_version_info.get('rpc_api_version', -1) self.logger.info("successfully connected to the king phisher server (version: {0} rpc api version: {1})".format(server_version_info['version'], server_rpc_api_version)) self.server_local_port = local_port if server_rpc_api_version != version.rpc_api_version: if version.rpc_api_version < server_rpc_api_version: secondary_text = 'The local client is not up to date with the server version.' else: secondary_text = 'The remote server is not up to date with the client version.' secondary_text += '\nPlease ensure that both the client and server are fully up to date.' gui_utilities.show_dialog_error('The RPC API Versions Are Incompatible', self, secondary_text) self.server_disconnect() return False return True