Пример #1
0
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
Пример #2
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
			))
Пример #3
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')
	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
			))
Пример #4
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.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))
Пример #6
0
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
Пример #7
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
Пример #8
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
Пример #9
0
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
Пример #10
0
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
Пример #11
0
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))
Пример #12
0
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
			))
Пример #13
0
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))