Ejemplo n.º 1
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
			))
Ejemplo n.º 2
0
def main():
	parser = argparse.ArgumentParser(description='King Phisher TOTP Enrollment Utility', conflict_handler='resolve')
	utilities.argp_add_args(parser)
	config_group = parser.add_mutually_exclusive_group(required=True)
	config_group.add_argument('-c', '--config', dest='server_config', type=argparse.FileType('r'), help='the server configuration file')
	config_group.add_argument('-u', '--url', dest='database_url', help='the database connection url')
	parser.add_argument('--otp', dest='otp_secret', help='a specific otp secret')
	parser.add_argument('user', help='the user to mange')
	parser.add_argument('action', choices=('remove', 'set', 'show'), help='the action to preform')
	parser.epilog = PARSER_EPILOG
	arguments = parser.parse_args()

	utilities.configure_stream_logger(arguments.loglvl, arguments.logger)

	if arguments.database_url:
		database_connection_url = arguments.database_url
	elif arguments.server_config:
		server_config = yaml.load(arguments.server_config)
		database_connection_url = server_config['server']['database']
	else:
		raise RuntimeError('no database connection was specified')

	manager.init_database(database_connection_url)
	session = manager.Session()
	user = session.query(models.User).filter_by(id=arguments.user).first()
	if not user:
		color.print_error("invalid user id: {0}".format(arguments.user))
		return

	for case in utilities.switch(arguments.action):
		if case('remove'):
			user.otp_secret = None
			break
		if case('set'):
			if user.otp_secret:
				color.print_error("the specified user already has an otp secret set")
				return
			if arguments.otp_secret:
				new_otp = arguments.otp_secret
			else:
				new_otp = pyotp.random_base32()
			if len(new_otp) != 16:
				color.print_error("invalid otp secret length, must be 16")
				return
			user.otp_secret = new_otp
			break

	if user.otp_secret:
		color.print_status("user: {0} otp: {1}".format(user.id, user.otp_secret))
		totp = pyotp.TOTP(user.otp_secret)
		uri = totp.provisioning_uri(user.id + '@king-phisher') + '&issuer=King%20Phisher'
		color.print_status("provisioning uri: {0}".format(uri))
	else:
		color.print_status("user: {0} otp: N/A".format(user.id))
	session.commit()
Ejemplo n.º 3
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
Ejemplo n.º 4
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
Ejemplo n.º 5
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))
Ejemplo n.º 6
0
def main():
    parser = argparse.ArgumentParser(
        description='King Phisher Interactive Database Console',
        conflict_handler='resolve')
    utilities.argp_add_args(parser)
    config_group = parser.add_mutually_exclusive_group(required=True)
    config_group.add_argument('-c',
                              '--config',
                              dest='server_config',
                              type=argparse.FileType('r'),
                              help='the server configuration file')
    config_group.add_argument('-u',
                              '--url',
                              dest='database_url',
                              help='the database connection url')
    arguments = parser.parse_args()

    utilities.configure_stream_logger(arguments.logger, arguments.loglvl)

    if arguments.database_url:
        database_connection_url = arguments.database_url
    elif arguments.server_config:
        server_config = yaml.load(arguments.server_config)
        database_connection_url = server_config['server']['database']
    else:
        raise RuntimeError('no database connection was specified')

    engine = manager.init_database(database_connection_url)
    session = manager.Session()
    rpc_session = aaa.AuthenticatedSession(user=getpass.getuser())
    console = code.InteractiveConsole(
        dict(engine=engine,
             graphql=graphql,
             graphql_query=graphql_query,
             manager=manager,
             models=models,
             pprint=pprint.pprint,
             rpc_session=rpc_session,
             session=session))
    console.interact('starting interactive database console')

    if os.path.isdir(os.path.dirname(history_file)):
        readline.write_history_file(history_file)
Ejemplo n.º 7
0
def main():
	parser = argparse.ArgumentParser(description='King Phisher SMTP Debug Server', conflict_handler='resolve')
	utilities.argp_add_args(parser)
	parser.add_argument('-f', '--foreground', dest='foreground', action='store_true', default=False, help='run in foreground (do not fork)')
	parser.add_argument('-a', '--address', dest='address', default='127.0.0.1', help='address to listen on')
	parser.add_argument('-p', '--port', dest='port', type=int, default=2525, help='port to listen on')
	arguments = parser.parse_args()
	del parser

	utilities.configure_stream_logger(arguments.loglvl, arguments.logger)

	if (not arguments.foreground) and os.fork():
		return

	bind_address = (arguments.address, arguments.port)
	server = smtp_server.BaseSMTPServer(bind_address)
	color.print_status("smtp server listening on {0}:{1}".format(bind_address[0], bind_address[1]))
	try:
		server.serve_forever()
	except KeyboardInterrupt:
		color.print_status('keyboard interrupt caught, now exiting')
Ejemplo n.º 8
0
def main():
	parser = argparse.ArgumentParser(description='King Phisher SMTP Debug Server', conflict_handler='resolve')
	utilities.argp_add_args(parser)
	parser.add_argument('-f', '--foreground', dest='foreground', action='store_true', default=False, help='run in foreground (do not fork)')
	parser.add_argument('-a', '--address', dest='address', default='127.0.0.1', help='address to listen on')
	parser.add_argument('-p', '--port', dest='port', type=int, default=2525, help='port to listen on')
	arguments = parser.parse_args()
	del parser

	utilities.configure_stream_logger(arguments.logger, arguments.loglvl)

	if (not arguments.foreground) and os.fork():
		return

	bind_address = (arguments.address, arguments.port)
	server = smtp_server.BaseSMTPServer(bind_address)
	color.print_status("smtp server listening on {0}:{1}".format(bind_address[0], bind_address[1]))
	try:
		server.serve_forever()
	except KeyboardInterrupt:
		color.print_status('keyboard interrupt caught, now exiting')
Ejemplo n.º 9
0
def main():
	parser = argparse.ArgumentParser(description='King Phisher Interactive Database Console', conflict_handler='resolve')
	utilities.argp_add_args(parser)
	config_group = parser.add_mutually_exclusive_group(required=True)
	config_group.add_argument('-c', '--config', dest='server_config', type=argparse.FileType('r'), help='the server configuration file')
	config_group.add_argument('-u', '--url', dest='database_url', help='the database connection url')
	arguments = parser.parse_args()

	utilities.configure_stream_logger(arguments.loglvl, arguments.logger)

	if arguments.database_url:
		database_connection_url = arguments.database_url
	elif arguments.server_config:
		server_config = yaml.load(arguments.server_config)
		database_connection_url = server_config['server']['database']
	else:
		raise RuntimeError('no database connection was specified')

	engine = manager.init_database(database_connection_url)
	session = manager.Session()
	console = code.InteractiveConsole(dict(engine=engine, manager=manager, models=models, session=session))
	console.interact('starting interactive database console')
Ejemplo n.º 10
0
 def test_configure_stream_logger(self):
     logger = utilities.configure_stream_logger('KingPhisher', 'INFO')
     self.assertEqual(logger.level, logging.INFO)
Ejemplo n.º 11
0
	def test_configure_stream_logger(self):
		logger = utilities.configure_stream_logger('INFO', 'KingPhisher')
		self.assertEqual(logger.level, logging.INFO)