def main(): parser = argparse.ArgumentParser(description='Stat File Verification', conflict_handler='resolve') parser.add_argument('-v', '--version', action='version', version='%(prog)s Version: ' + __version__) parser.add_argument('data_file', type=argparse.FileType('r'), help='the stats file to verify') arguments = parser.parse_args() try: data = serializers.JSON.load(arguments.data_file) except Exception: color.print_error('failed to load the data') return 1 else: color.print_status('loaded the statistics data') finally: arguments.data_file.close() if not verify_signature(data): color.print_error('the signature is invalid') return 1 color.print_good('the signature is valid') return 0
def main(): parser = argparse.ArgumentParser(description='King Phisher SPF Check Utility', conflict_handler='resolve') utilities.argp_add_args(parser) parser.add_argument('smtp_server_ip', help='the ip address of the sending smtp server') parser.add_argument('target_email', help='the email address that messages are from') arguments = parser.parse_args() utilities.configure_stream_logger(arguments.logger, arguments.loglvl) server_ip = arguments.smtp_server_ip target_email = arguments.target_email if not ipaddress.is_valid(server_ip): color.print_error('the smtp server ip address specified is invalid') return if not '@' in target_email: target_email = utilities.random_string_lower_numeric(8) + '@' + target_email color.print_status('target email appears to be just a domain, changed to: ' + target_email) if not utilities.is_valid_email_address(target_email): color.print_error('the email address specified is invalid') return spf_sender, spf_domain = target_email.split('@') spf_test = spf.SenderPolicyFramework(server_ip, spf_domain, spf_sender) try: result = spf_test.check_host() except spf.SPFParseError as error: color.print_error('check_host failed with error: permerror (parsing failed)') color.print_error('error reason: ' + error.message) return except spf.SPFPermError as error: color.print_error('check_host failed with error: permerror') color.print_error('error reason: ' + error.message) return except spf.SPFTempError as error: color.print_error('check_host failed with error: temperror') color.print_error('error reason: ' + error.message) return if not result: color.print_status('no spf policy was found for the specified domain') return color.print_good("spf policy result: {0}".format(result)) color.print_status('top level spf records found:') match = spf_test.match for record_id, record in enumerate(spf_test.records.values(), 1): color.print_status(" #{0} {1: <10} {2}".format( record_id, ('(matched)' if match.record == record else ''), record.domain )) for directive_id, directive in enumerate(record.directives, 1): color.print_status(" #{0}.{1} {2: <10} {3}".format( record_id, directive_id, ('(matched)' if match.record == record and match.directive == directive else ''), directive ))
def main(): parser = argparse.ArgumentParser(description='King Phisher SPF Check Utility', conflict_handler='resolve') utilities.argp_add_args(parser) parser.add_argument('smtp_server_ip', help='the ip address of the sending smtp server') parser.add_argument('target_email', help='the email address that messages are from') parser.add_argument('--dns-timeout', dest='dns_timeout', default=spf.DEFAULT_DNS_TIMEOUT, type=int, help='the timeout for dns queries') arguments = parser.parse_args() server_ip = arguments.smtp_server_ip target_email = arguments.target_email if not ipaddress.is_valid(server_ip): color.print_error('the smtp server ip address specified is invalid') return if not '@' in target_email: target_email = utilities.random_string_lower_numeric(8) + '@' + target_email color.print_status('target email appears to be just a domain, changed to: ' + target_email) if not utilities.is_valid_email_address(target_email): color.print_error('the email address specified is invalid') return spf_sender, spf_domain = target_email.split('@') spf_test = spf.SenderPolicyFramework(server_ip, spf_domain, sender=spf_sender, timeout=arguments.dns_timeout) try: result = spf_test.check_host() except spf.SPFParseError as error: color.print_error('check_host failed with error: permerror (parsing failed)') color.print_error('error reason: ' + error.message) return except spf.SPFPermError as error: color.print_error('check_host failed with error: permerror') color.print_error('error reason: ' + error.message) return except spf.SPFTempError as error: color.print_error('check_host failed with error: temperror') color.print_error('error reason: ' + error.message) return if not result: color.print_status('no spf policy was found for the specified domain') return color.print_good("spf policy result: {0}".format(result)) color.print_status('top level spf records found:') match = spf_test.match for record_id, record in enumerate(spf_test.records.values(), 1): color.print_status(" #{0} {1: <10} {2}".format( record_id, ('(matched)' if match.record == record else ''), record.domain )) for directive_id, directive in enumerate(record.directives, 1): color.print_status(" #{0}.{1: <2} {2: <10} {3}".format( record_id, directive_id, ('(matched)' if match.record == record and match.directive == directive else ''), directive ))
def main(): parser = argparse.ArgumentParser(description='King Phisher SPF Check Utility', conflict_handler='resolve') utilities.argp_add_args(parser) parser.add_argument('smtp_server_ip', help='the ip address of the sending smtp server') parser.add_argument('target_email', help='the email address that messages are from') arguments = parser.parse_args() utilities.configure_stream_logger(arguments.loglvl, arguments.logger) server_ip = arguments.smtp_server_ip target_email = arguments.target_email if not utilities.is_valid_ip_address(server_ip): color.print_error('the smtp server ip address specified is invalid') return if not '@' in target_email: target_email = utilities.random_string_lower_numeric(8) + '@' + target_email color.print_status('target email appears to be just a domain, changed to: ' + target_email) if not utilities.is_valid_email_address(target_email): color.print_error('the email address specified is invalid') return spf_sender, spf_domain = target_email.split('@') spf_test = spf.SenderPolicyFramework(server_ip, spf_domain, spf_sender) try: result = spf_test.check_host() except spf.SPFPermError as error: color.print_error('check_host failed with error: permerror') color.print_error('error reason: ' + error.message) return except spf.SPFTempError as error: color.print_error('check_host failed with error: temperror') color.print_error('error reason: ' + error.message) return if not result: color.print_status('no spf policy was found for the specified domain') return color.print_good("spf policy result: {0}".format(result)) color.print_status('top level spf records found:') for rid in range(len(spf_test.spf_records)): record = spf.record_unparse(spf_test.spf_records[rid]) color.print_status(" #{0} {1: <10} {2}".format(rid + 1, ('(matched)' if rid == spf_test.spf_record_id else ''), record))
def main(): parser = argparse.ArgumentParser(description='King Phisher SPF Check Utility', conflict_handler='resolve') parser.add_argument('-v', '--version', action='version', version=parser.prog + ' Version: ' + version.version) parser.add_argument('-L', '--log', dest='loglvl', action='store', choices=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'], default='CRITICAL', help='set the logging level') parser.add_argument('smtp_server_ip', help='the ip address of the sending smtp server') parser.add_argument('target_email', help='the email address that messages are from') arguments = parser.parse_args() logging.getLogger('').setLevel(logging.DEBUG) console_log_handler = logging.StreamHandler() console_log_handler.setLevel(getattr(logging, arguments.loglvl)) console_log_handler.setFormatter(logging.Formatter("%(levelname)-8s %(message)s")) logging.getLogger('').addHandler(console_log_handler) server_ip = arguments.smtp_server_ip target_email = arguments.target_email if not utilities.is_valid_ip_address(server_ip): color.print_error('the smtp server ip address specified is invalid') return if not utilities.is_valid_email_address(target_email): color.print_error('the email address specified is invalid') return spf_sender, spf_domain = target_email.split('@') spf_test = spf.SenderPolicyFramework(server_ip, spf_domain, spf_sender) try: result = spf_test.check_host() except spf.SPFPermError: color.print_error('check_host failed with error: permerror') return except spf.SPFTempError: color.print_error('check_host failed with error: temperror') return if not result: color.print_status('no spf policy was found for the specified domain') return color.print_good("spf policy result: {0}".format(result)) color.print_status('top level spf records found:') for rid in range(len(spf_test.spf_records)): record = spf.record_unparse(spf_test.spf_records[rid]) color.print_status(" #{0} {1: <10} {2}".format(rid + 1, ('(matched)' if rid == spf_test.spf_record_id else ''), record))
def main(): parser = argparse.ArgumentParser(description='Stat File Verification', conflict_handler='resolve') parser.add_argument('-v', '--version', action='version', version='%(prog)s Version: ' + __version__) parser.add_argument('data_file', type=argparse.FileType('r'), help='the stats file to verify') arguments = parser.parse_args() try: data = json_ex.load(arguments.data_file) except Exception: color.print_error('failed to load the data') return 1 else: color.print_status('loaded the statistics data') finally: arguments.data_file.close() if not verify_signature(data): color.print_error('the signature is invalid') return 1 color.print_good('the signature is valid') return 0
def main(): parser = argparse.ArgumentParser(description='King Phisher Server', conflict_handler='resolve') utilities.argp_add_args(parser) startup.argp_add_server(parser) arguments = parser.parse_args() # basic runtime checks if sys.version_info < (3, 4): color.print_error('the Python version is too old (minimum required is 3.4)') return 0 console_log_handler = utilities.configure_stream_logger(arguments.logger, arguments.loglvl) del parser if os.getuid(): color.print_error('the server must be started as root, configure the') color.print_error('\'server.setuid_username\' option in the config file to drop privileges') return os.EX_NOPERM # configure environment variables and load the config find.init_data_path('server') config = configuration.ex_load_config(arguments.config_file) if arguments.verify_config: color.print_good('configuration verification passed') color.print_good('all required settings are present') return os.EX_OK if config.has_option('server.data_path'): find.data_path_append(config.get('server.data_path')) if arguments.update_geoip_db: color.print_status('downloading a new geoip database') try: size = geoip.download_geolite2_city_db(config.get('server.geoip.database')) except errors.KingPhisherResourceError as error: color.print_error(error.message) return os.EX_UNAVAILABLE color.print_good("download complete, file size: {0}".format(strutils.bytes2human(size))) return os.EX_OK # setup logging based on the configuration if config.has_section('logging'): log_file = _ex_config_logging(arguments, config, console_log_handler) logger.debug("king phisher version: {0} python version: {1}.{2}.{3}".format(version.version, sys.version_info[0], sys.version_info[1], sys.version_info[2])) # initialize the plugin manager try: plugin_manager = plugins.ServerPluginManager(config) except errors.KingPhisherError as error: if isinstance(error, errors.KingPhisherPluginError): color.print_error("plugin error: {0} ({1})".format(error.plugin_name, error.message)) else: color.print_error(error.message) return os.EX_SOFTWARE status_code = build_and_run(arguments, config, plugin_manager, log_file) plugin_manager.shutdown() logging.shutdown() return status_code
def main(): parser = argparse.ArgumentParser( description='King Phisher Certbot Wrapper Utility', conflict_handler='resolve') utilities.argp_add_args(parser) parser.add_argument('--certbot', dest='certbot_bin', help='the path to the certbot binary to use') parser.add_argument('--json-output', dest='json_file', help='update a json formatted file with the details') parser.add_argument('--restart-service', action='store_true', default=False, help='attempt to restart the king-phisher service') parser.add_argument('server_config', help='the server configuration file') parser.add_argument('hostnames', nargs='+', help='the host names to request certificates for') parser.epilog = PARSER_EPILOG arguments = parser.parse_args() server_config = configuration.ex_load_config( arguments.server_config).get('server') web_root = server_config['web_root'] if os.getuid(): color.print_error('this tool must be run as root') return os.EX_NOPERM certbot_bin = arguments.certbot_bin or smoke_zephyr.utilities.which( 'certbot') if certbot_bin is None: color.print_error( 'could not identify the path to the certbot binary, make sure that it is' ) color.print_error( 'installed and see: https://certbot.eff.org/ for more details') return os.EX_UNAVAILABLE if not os.access(certbot_bin, os.R_OK | os.X_OK): color.print_error( 'found insufficient permissions on the certbot binary') return os.EX_NOPERM logger = logging.getLogger('KingPhisher.Tool.CLI.CertbotWrapper') logger.info('using certbot binary at: ' + certbot_bin) logger.debug('getting server binding information') if server_config.get('addresses'): address = server_config['addresses'][0] else: address = server_config['address'] address['ssl'] = bool(server_config.get('ssl_cert')) logger.debug( "checking that the king phisher server is running on: {host}:{port} (ssl={ssl})" .format(**address)) try: rpc = advancedhttpserver.RPCClient((address['host'], address['port']), use_ssl=address['ssl']) version = rpc('version') except (advancedhttpserver.RPCError, socket.error): logger.error('received an rpc error while checking the version', exc_info=True) color.print_error( 'failed to verify that the king phisher server is running') return os.EX_UNAVAILABLE logger.info('connected to server version: ' + version['version']) vhost_directories = server_config['vhost_directories'] if len(arguments.hostnames) > 1 and not vhost_directories: color.print_error( 'vhost_directories must be true to specify multiple hostnames') return os.EX_CONFIG for hostname in arguments.hostnames: if vhost_directories: directory = os.path.join(web_root, hostname) else: directory = web_root if os.path.split(os.path.abspath(directory))[-1] != hostname: color.print_error( 'when the vhost_directories option is not set, the web_root option' ) color.print_error('must be: ' + os.path.join(web_root, hostname)) return os.EX_CONFIG if not os.path.exists(directory): os.mkdir(directory, mode=0o775) logger.info('created directory for host at: ' + directory) certbot_args = (certbot_bin, 'certonly', '--webroot', '-w', directory, '-d', hostname) logger.info('running certbot command: ' + ' '.join(certbot_args)) proc_h = subprocess.Popen(certbot_args, shell=False) status = proc_h.wait() if status != os.EX_OK: color.print_error('certbot exited with exit status: ' + str(status)) break color.print_good('certbot exited with a successful status code') timestamp = datetime.datetime.utcnow().isoformat() + '+00:00' if not os.path.isdir(os.path.join(LETS_ENCRYPT_LIVE_PATH, hostname)): logger.warning('failed to find the new hostname in: ' + LETS_ENCRYPT_LIVE_PATH) continue details = { 'created': timestamp, 'host': hostname, 'ssl_cert': os.path.join(LETS_ENCRYPT_LIVE_PATH, hostname, 'fullchain.pem'), 'ssl_key': os.path.join(LETS_ENCRYPT_LIVE_PATH, hostname, 'privkey.pem') } if arguments.json_file: existing_data = [] if os.path.isfile(arguments.json_file): with open(arguments.json_file, 'r') as file_h: existing_data = serializers.JSON.load(file_h) if not isinstance(existing_data, list): color.print_status( 'the existing json data must be a list to add the new data' ) existing_data.append(details) with open(arguments.json_file, 'w') as file_h: serializers.JSON.dump(existing_data, file_h) else: color.print_status( 'copy the following lines into the server configuration file under' ) color.print_status( 'the \'ssl_hosts:\' section to use the certificates with king phisher' ) print(' # created: ' + details['created']) print(' - host: ' + details['host']) print(' ssl_cert: ' + details['ssl_cert']) print(' ssl_key: ' + details['ssl_key']) if arguments.hostnames and arguments.json_file and arguments.restart_service: systemctl_bin = smoke_zephyr.utilities.which('systemctl') if systemctl_bin is None: color.print_error( 'could not restart the king-phisher service (could not find systemctl)' ) return os.EX_OK proc_h = subprocess.Popen([systemctl_bin, 'restart', 'king-phisher'], shell=False) if proc_h.wait() != 0: color.print_error( 'failed to restart the king-phisher service via systemctl') return os.EX_SOFTWARE color.print_status('restarted the king-phisher service via systemctl') return os.EX_OK
def main(): parser = argparse.ArgumentParser( conflict_handler='resolve', description=PARSER_DESCRIPTION, epilog=PARSER_EPILOG, formatter_class=argparse.RawTextHelpFormatter ) utilities.argp_add_args(parser) parser.add_argument('--certbot', dest='certbot_bin', help='the path to the certbot binary to use') parser.add_argument('--json-output', dest='json_file', help='update a json formatted file with the details') parser.add_argument('--restart-service', action='store_true', default=False, help='attempt to restart the king-phisher service') parser.add_argument('server_config', help='the server configuration file') parser.add_argument('hostnames', nargs='+', help='the host names to request certificates for') parser.epilog = PARSER_EPILOG arguments = parser.parse_args() server_config = configuration.ex_load_config(arguments.server_config).get('server') web_root = server_config['web_root'] if os.getuid(): color.print_error('this tool must be run as root') return os.EX_NOPERM certbot_bin = arguments.certbot_bin or smoke_zephyr.utilities.which('certbot') if certbot_bin is None: color.print_error('could not identify the path to the certbot binary, make sure that it is') color.print_error('installed and see: https://certbot.eff.org/ for more details') return os.EX_UNAVAILABLE if not os.access(certbot_bin, os.R_OK | os.X_OK): color.print_error('found insufficient permissions on the certbot binary') return os.EX_NOPERM logger = logging.getLogger('KingPhisher.Tool.CLI.CertbotWrapper') logger.info('using certbot binary at: ' + certbot_bin) logger.debug('getting server binding information') if server_config.get('addresses'): address = server_config['addresses'][0] else: address = server_config['address'] address['ssl'] = bool(server_config.get('ssl_cert')) logger.debug("checking that the king phisher server is running on: {host}:{port} (ssl={ssl})".format(**address)) try: rpc = advancedhttpserver.RPCClient((address['host'], address['port']), use_ssl=address['ssl']) version = rpc('version') except (advancedhttpserver.RPCError, socket.error): logger.error('received an rpc error while checking the version', exc_info=True) color.print_error('failed to verify that the king phisher server is running') return os.EX_UNAVAILABLE logger.info('connected to server version: ' + version['version']) vhost_directories = server_config['vhost_directories'] if len(arguments.hostnames) > 1 and not vhost_directories: color.print_error('vhost_directories must be true to specify multiple hostnames') return os.EX_CONFIG for hostname in arguments.hostnames: if vhost_directories: directory = os.path.join(web_root, hostname) else: directory = web_root if os.path.split(os.path.abspath(directory))[-1] != hostname: color.print_error('when the vhost_directories option is not set, the web_root option') color.print_error('must be: ' + os.path.join(web_root, hostname)) return os.EX_CONFIG if not os.path.exists(directory): os.mkdir(directory, mode=0o775) logger.info('created directory for host at: ' + directory) certbot_args = (certbot_bin, 'certonly', '--webroot', '-w', directory, '-d', hostname) logger.info('running certbot command: ' + ' '.join(certbot_args)) proc_h = subprocess.Popen(certbot_args, shell=False) status = proc_h.wait() if status != os.EX_OK: color.print_error('certbot exited with exit status: ' + str(status)) break color.print_good('certbot exited with a successful status code') timestamp = datetime.datetime.utcnow().isoformat() + '+00:00' if not os.path.isdir(os.path.join(LETS_ENCRYPT_LIVE_PATH, hostname)): logger.warning('failed to find the new hostname in: ' + LETS_ENCRYPT_LIVE_PATH) continue details = { 'created': timestamp, 'host': hostname, 'ssl_cert': os.path.join(LETS_ENCRYPT_LIVE_PATH, hostname, 'fullchain.pem'), 'ssl_key': os.path.join(LETS_ENCRYPT_LIVE_PATH, hostname, 'privkey.pem') } if arguments.json_file: existing_data = [] if os.path.isfile(arguments.json_file): with open(arguments.json_file, 'r') as file_h: existing_data = serializers.JSON.load(file_h) if not isinstance(existing_data, list): color.print_status('the existing json data must be a list to add the new data') existing_data.append(details) with open(arguments.json_file, 'w') as file_h: serializers.JSON.dump(existing_data, file_h) else: color.print_status('copy the following lines into the server configuration file under') color.print_status('the \'ssl_hosts:\' section to use the certificates with king phisher') print(' # created: ' + details['created']) print(' - host: ' + details['host']) print(' ssl_cert: ' + details['ssl_cert']) print(' ssl_key: ' + details['ssl_key']) if arguments.hostnames and arguments.json_file and arguments.restart_service: systemctl_bin = smoke_zephyr.utilities.which('systemctl') if systemctl_bin is None: color.print_error('could not restart the king-phisher service (could not find systemctl)') return os.EX_OK proc_h = subprocess.Popen([systemctl_bin, 'restart', 'king-phisher'], shell=False) if proc_h.wait() != 0: color.print_error('failed to restart the king-phisher service via systemctl') return os.EX_SOFTWARE color.print_status('restarted the king-phisher service via systemctl') return os.EX_OK
def main(): parser = argparse.ArgumentParser(description='King Phisher Certbot Wrapper Utility', conflict_handler='resolve') utilities.argp_add_args(parser) parser.add_argument('--certbot', dest='certbot_bin', help='the path to the certbot binary to use') parser.add_argument('server_config', type=argparse.FileType('r'), help='the server configuration file') parser.add_argument('hostnames', nargs='+', help='the host names to request certificates for') parser.epilog = PARSER_EPILOG arguments = parser.parse_args() server_config = yaml.load(arguments.server_config) web_root = server_config['server']['web_root'] if os.getuid(): color.print_error('this tool must be ran as root') return os.EX_NOPERM certbot_bin = arguments.certbot_bin or smoke_zephyr.utilities.which('certbot') if certbot_bin is None: color.print_error('could not identify the path to the certbot binary, make sure that it is') color.print_error('installed and see: https://certbot.eff.org/ for more details') return os.EX_NOTFOUND if not os.access(certbot_bin, os.R_OK | os.X_OK): color.print_error('found insufficient permissions on the certbot binary') return os.EX_NOPERM logger = logging.getLogger('KingPhisher.Tool.CLI.CertbotWrapper') logger.info('using certbot binary at: ' + certbot_bin) logger.debug('getting server binding information') if server_config['server'].get('addresses'): address = server_config['server']['addresses'][0] else: address = server_config['server']['address'] address['ssl'] = bool(server_config['server'].get('ssl_cert')) logger.debug("checking that the king phisher server is running on: {host}:{port} (ssl={ssl})".format(**address)) try: rpc = advancedhttpserver.RPCClient((address['host'], address['port']), use_ssl=address['ssl']) version = rpc('version') except (advancedhttpserver.RPCError, socket.error): logger.error('received an rpc error while checking the version', exc_info=True) color.print_error('failed to verify that the king phisher server is running') return os.EX_UNAVAILABLE logger.info('connected to server version: ' + version['version']) vhost_directories = server_config['server']['vhost_directories'] if len(arguments.hostnames) > 1 and not vhost_directories: color.print_error('vhost_directories must be true to specify multiple hostnames') return os.EX_CONFIG for hostname in arguments.hostnames: if vhost_directories: directory = os.path.join(web_root, hostname) else: directory = web_root if os.path.split(os.path.abspath(directory))[-1] != hostname: color.print_error('when the vhost_directories option is not set, the web_root option') color.print_error('must be: ' + os.path.join(web_root, hostname)) return os.EX_CONFIG if not os.path.exists(directory): os.mkdir(directory, mode=0o775) logger.info('created directory for host at: ' + directory) certbot_args = (certbot_bin, 'certonly', '--webroot', '-w', directory, '-d', hostname) logger.info('running certbot command: ' + ' '.join(certbot_args)) proc_h = subprocess.Popen(certbot_args, shell=False) status = proc_h.wait() if status != os.EX_OK: color.print_error('certbot exited with exit status: ' + int(status)) break color.print_good('certbot exited with successful status code') if not os.path.isdir(os.path.join(LETS_ENCRYPT_LIVE_PATH, hostname)): logger.warning('failed to find the new hostname in: ' + LETS_ENCRYPT_LIVE_PATH) continue color.print_status('copy the following lines into the server configuration file under') color.print_status('the \'ssl_hosts:\' section to use the certificates with king phisher') print(" - host: {0}".format(hostname)) print(" ssl_cert: /etc/letsencrypt/live/{0}/fullchain.pem".format(hostname)) print(" ssl_key: /etc/letsencrypt/live/{0}/privkey.pem".format(hostname))
def main(): parser = argparse.ArgumentParser( conflict_handler='resolve', description=PARSER_DESCRIPTION, epilog=PARSER_EPILOG, formatter_class=argparse.RawTextHelpFormatter ) utilities.argp_add_args(parser) parser.add_argument('smtp_server_ip', help='the ip address of the sending smtp server') parser.add_argument('target_email', help='the email address that messages are from') parser.add_argument('--dns-timeout', dest='dns_timeout', default=spf.DEFAULT_DNS_TIMEOUT, metavar='TIMEOUT', type=int, help='the timeout for dns queries') arguments = parser.parse_args() server_ip = arguments.smtp_server_ip target_email = arguments.target_email if not ipaddress.is_valid(server_ip): color.print_error('the smtp server ip address specified is invalid') return if not '@' in target_email: target_email = utilities.random_string_lower_numeric(8) + '@' + target_email color.print_status('target email appears to be just a domain, changed to: ' + target_email) if not utilities.is_valid_email_address(target_email): color.print_error('the email address specified is invalid') return spf_sender, spf_domain = target_email.split('@') spf_test = spf.SenderPolicyFramework(server_ip, spf_domain, sender=spf_sender, timeout=arguments.dns_timeout) try: result = spf_test.check_host() except spf.SPFParseError as error: color.print_error('check_host failed with error: permerror (parsing failed)') color.print_error('error reason: ' + error.message) return except spf.SPFPermError as error: color.print_error('check_host failed with error: permerror') color.print_error('error reason: ' + error.message) return except spf.SPFTempError as error: color.print_error('check_host failed with error: temperror') color.print_error('error reason: ' + error.message) return if not result: color.print_status('no spf policy was found for the specified domain') return color.print_good("spf policy result: {0}".format(result)) color.print_status('top level spf records found:') match = spf_test.match for record_id, record in enumerate(spf_test.records.values(), 1): color.print_status(" #{0} {1: <10} {2}".format( record_id, ('(matched)' if match.record == record else ''), record.domain )) for directive_id, directive in enumerate(record.directives, 1): color.print_status(" #{0}.{1: <2} {2: <10} {3}".format( record_id, directive_id, ('(matched)' if match.record == record and match.directive == directive else ''), directive ))
def main(): parser = argparse.ArgumentParser( description='King Phisher SPF Check Utility', conflict_handler='resolve') parser.add_argument('-v', '--version', action='version', version=parser.prog + ' Version: ' + version.version) parser.add_argument( '-L', '--log', dest='loglvl', action='store', choices=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'], default='CRITICAL', help='set the logging level') parser.add_argument('smtp_server_ip', help='the ip address of the sending smtp server') parser.add_argument('target_email', help='the email address that messages are from') arguments = parser.parse_args() logging.getLogger('').setLevel(logging.DEBUG) console_log_handler = logging.StreamHandler() console_log_handler.setLevel(getattr(logging, arguments.loglvl)) console_log_handler.setFormatter( logging.Formatter("%(levelname)-8s %(message)s")) logging.getLogger('').addHandler(console_log_handler) server_ip = arguments.smtp_server_ip target_email = arguments.target_email if not utilities.is_valid_ip_address(server_ip): color.print_error('the smtp server ip address specified is invalid') return if not utilities.is_valid_email_address(target_email): color.print_error('the email address specified is invalid') return spf_sender, spf_domain = target_email.split('@') spf_test = spf.SenderPolicyFramework(server_ip, spf_domain, spf_sender) try: result = spf_test.check_host() except spf.SPFPermError: color.print_error('check_host failed with error: permerror') return except spf.SPFTempError: color.print_error('check_host failed with error: temperror') return if not result: color.print_status('no spf policy was found for the specified domain') return color.print_good("spf policy result: {0}".format(result)) color.print_status('top level spf records found:') for rid in range(len(spf_test.spf_records)): record = spf.record_unparse(spf_test.spf_records[rid]) color.print_status(" #{0} {1: <10} {2}".format( rid + 1, ('(matched)' if rid == spf_test.spf_record_id else ''), record))