def prepare_environment(work_dir): package_directory = os.path.dirname(os.path.abspath(beeswarm.__file__)) config_file = os.path.join(work_dir, 'beeswarmcfg.json') if not os.path.isfile(config_file): logging.info('Copying configuration file to workdir.') print '*** Please answer a few configuration options ***' print '' print '* Certificate Information *' print 'IMPORTANT: Please make sure that "Common Name" is the IP address or fully qualified host name ' \ ' that you want to use for the beekeeper API.' cert_cn = raw_input('Common Name: ') cert_country = raw_input('Country: ') cert_state = raw_input('State: ') cert_locality = raw_input('Locality/City: ') cert_org = raw_input('Organization: ') cert_org_unit = raw_input('Organizational unit: ') print '' print '* Network *' tcp_port = raw_input('Port for UI/API (default: 5000): ') if tcp_port: tcp_port = int(tcp_port) else: tcp_port = 5000 # to keep things simple we just use the CN for host for now. tcp_host = cert_cn create_self_signed_cert(work_dir, 'beekeeper.crt', 'beekeeper.key', cert_country, cert_state, cert_org, cert_locality, cert_org_unit, cert_cn) shutil.copyfile(os.path.join(package_directory, 'beekeeper/beeswarmcfg.json.dist'), config_file) # update the config file update_config_file(config_file, {'network': {'port': tcp_port, 'host': tcp_host}})
def __init__(self, work_dir, config, key='server.key', cert='server.crt', **kwargs): """ Main class which runs Beeswarm in Honeypot mode. :param work_dir: Working directory (usually the current working directory) :param config: Beeswarm configuration dictionary, None if no configuration was supplied. :param key: Key file used for SSL enabled capabilities :param cert: Cert file used for SSL enabled capabilities """ if config is None or not os.path.isdir(os.path.join(work_dir, 'data')): Honeypot.prepare_environment(work_dir) self.work_dir = work_dir self.config = config self.key = os.path.join(work_dir, key) self.cert = os.path.join(work_dir, cert) self._servers = [] self._server_greenlets = [] self.honeypot_id = self.config['general']['id'] Session.honeypot_id = self.honeypot_id # write ZMQ keys to files - as expected by pyzmq extract_keys(work_dir, config) if not (os.path.isfile(os.path.join(work_dir, 'server.key'))): cert_info = config['certificate_info'] if cert_info['common_name']: cert_info['common_name'] = cert_info['common_name'] else: cert_info['common_name'] = get_most_likely_ip() cert, priv_key = create_self_signed_cert(cert_info['country'], cert_info['state'], cert_info['organization'], cert_info['locality'], cert_info['organization_unit'], cert_info['common_name']) cert_path = os.path.join(work_dir, 'server.crt') key_path = os.path.join(work_dir, 'server.key') with open(cert_path, 'w') as certfile: certfile.write(cert) with open(key_path, 'w') as keyfile: keyfile.write(priv_key) send_zmq_push(SocketNames.SERVER_RELAY.value, '{0} {1} {2}'.format(Messages.KEY.value, self.honeypot_id, priv_key)) send_zmq_push(SocketNames.SERVER_RELAY.value, '{0} {1} {2}'.format(Messages.CERT.value, self.honeypot_id, cert)) if self.config['general']['fetch_ip']: try: url = 'http://api.externalip.net/ip' req = requests.get(url) self.honeypot_ip = req.text logger.info('Fetched {0} as external ip for Honeypot.'.format(self.honeypot_ip)) except (Timeout, ConnectionError) as e: logger.warning('Could not fetch public ip: {0}'.format(e)) else: self.honeypot_ip = '' # spawning time checker if self.config['timecheck']['enabled']: Greenlet.spawn(self.check_time)
def __init__(self, work_dir, config, key='server.key', cert='server.crt', **kwargs): """ Main class which runs Beeswarm in Honeypot mode. :param work_dir: Working directory (usually the current working directory) :param config: Beeswarm configuration dictionary, None if no configuration was supplied. :param key: Key file used for SSL enabled capabilities :param cert: Cert file used for SSL enabled capabilities """ if fs.__version__ != '0.5.4': os.exit('the python fs package must be verison 0.5.4') if config is None or not os.path.isdir(os.path.join(work_dir, 'data')): Honeypot.prepare_environment(work_dir) self.work_dir = work_dir self.config = config self.key = os.path.join(work_dir, key) self.cert = os.path.join(work_dir, cert) self._servers = [] self._server_greenlets = [] self.honeypot_id = self.config['general']['id'] Session.honeypot_id = self.honeypot_id # write ZMQ keys to files - as expected by pyzmq extract_keys(work_dir, config) if not (os.path.isfile(os.path.join(work_dir, 'server.key'))): cert_info = config['certificate_info'] if cert_info['common_name']: cert_info['common_name'] = cert_info['common_name'] else: cert_info['common_name'] = get_most_likely_ip() cert, priv_key = create_self_signed_cert( cert_info['country'], cert_info['state'], cert_info['organization'], cert_info['locality'], cert_info['organization_unit'], cert_info['common_name']) cert_path = os.path.join(work_dir, 'server.crt') key_path = os.path.join(work_dir, 'server.key') with open(cert_path, 'w') as certfile: certfile.write(cert) with open(key_path, 'w') as keyfile: keyfile.write(priv_key) send_zmq_push( SocketNames.SERVER_RELAY.value, '{0} {1} {2}'.format(Messages.KEY.value, self.honeypot_id, priv_key)) send_zmq_push( SocketNames.SERVER_RELAY.value, '{0} {1} {2}'.format(Messages.CERT.value, self.honeypot_id, cert)) if self.config['general']['fetch_ip']: try: url = 'http://api.externalip.net/ip' req = requests.get(url) self.honeypot_ip = req.text logger.info('Fetched {0} as external ip for Honeypot.'.format( self.honeypot_ip)) except (Timeout, ConnectionError) as e: logger.warning('Could not fetch public ip: {0}'.format(e)) else: self.honeypot_ip = '' # spawning time checker if self.config['timecheck']['enabled']: Greenlet.spawn(self.check_time)
def __init__(self, work_dir, config, key='server.key', cert='server.crt', curses_screen=None, **kwargs): """ Main class which runs Beeswarm in Honeypot mode. :param work_dir: Working directory (usually the current working directory) :param config: Beeswarm configuration dictionary, None if no configuration was supplied. :param key: Key file used for SSL enabled capabilities :param cert: Cert file used for SSL enabled capabilities :param curses_screen: Contains a curses screen object, if UI is enabled. Default is None. """ if config is None or not os.path.isdir(os.path.join(work_dir, 'data')): Honeypot.prepare_environment(work_dir) with open('beeswarmcfg.json', 'r') as config_file: config = json.load(config_file, object_hook=asciify) self.work_dir = work_dir self.config = config self.key = key self.cert = cert self.curses_screen = curses_screen # TODO: pass honeypot otherwise Session.honeypot_id = self.config['general']['id'] self.id = self.config['general']['id'] # write ZMQ keys to files - as expected by pyzmq extract_keys(work_dir, config) if not (os.path.isfile(os.path.join(work_dir, 'server.key'))): cert_info = config['certificate_info'] #TODO: IF NOT COMMON_NAME: Use own ip address... cert, priv_key = create_self_signed_cert(cert_info['country'], cert_info['state'], cert_info['organization'], cert_info['locality'], cert_info['organization_unit'], cert_info['common_name']) cert_path = os.path.join(work_dir, 'server.crt') key_path = os.path.join(work_dir, 'server.key') with open(cert_path, 'w') as certfile: certfile.write(cert) with open(key_path, 'w') as keyfile: keyfile.write(priv_key) send_zmq_push('ipc://serverRelay', '{0} {1} {2}'.format(Messages.KEY, self.id, keyfile)) send_zmq_push('ipc://serverRelay', '{0} {1} {2}'.format(Messages.CERT, self.id, cert)) if self.config['general']['fetch_ip']: try: url = 'http://api.externalip.net/ip' req = requests.get(url) self.honeypot_ip = req.text logger.info('Fetched {0} as external ip for Honeypot.'.format(self.honeypot_ip)) except (Timeout, ConnectionError) as e: logger.warning('Could not fetch public ip: {0}'.format(e)) else: self.honeypot_ip = '' self.status = { 'mode': 'Honeypot', 'ip_address': self.honeypot_ip, 'honeypot_id': self.config['general']['id'], 'total_sessions': 0, 'active_sessions': 0, 'enabled_capabilities': [], 'managment_url': '' } # will contain BaitUser objects self.users = self.create_users() # inject authentication mechanism Session.authenticator = Authenticator(self.users) # spawning time checker if self.config['timecheck']['enabled']: Greenlet.spawn(self.checktime) # show curses UI if self.curses_screen is not None: self.uihandler = HoneypotUIHandler(self.status, self.curses_screen) Greenlet.spawn(self.show_status_ui)
def prepare_environment(work_dir, customize): package_directory = os.path.dirname(os.path.abspath(beeswarm.__file__)) config_file = os.path.join(work_dir, 'beeswarmcfg.json') if not os.path.isfile(config_file): print '*** Please answer a few configuration options ***' if customize: logging.info('Copying configuration file to workdir.') print '' print '* Certificate Information *' print 'IMPORTANT: Please make sure that "Common Name" is the IP address or fully qualified host name ' \ ' that you want to use for the server API.' cert_cn = raw_input('Common Name: ') cert_country = raw_input('Country: ') cert_state = raw_input('State: ') cert_locality = raw_input('Locality/City: ') cert_org = raw_input('Organization: ') cert_org_unit = raw_input('Organizational unit: ') print '' print '* Network *' web_port = raw_input('Port for UI (default: 5000): ') if web_port: web_port = int(web_port) else: web_port = 5000 else: logging.warn('Beeswarm server will be configured using default ssl parameters and network ' 'configuration, this could be used to fingerprint the beeswarm server. If you want to ' 'customize these options please use the --customize options on first startup.') cert_cn = '*' cert_country = 'US' cert_state = 'None' cert_locality = 'None' cert_org = 'None' cert_org_unit = '' web_port = 5000 cert, priv_key = create_self_signed_cert(cert_country, cert_state, cert_org, cert_locality, cert_org_unit, cert_cn) cert_path = os.path.join(work_dir, 'server.crt') key_path = os.path.join(work_dir, 'server.key') with open(cert_path, 'w') as certfile: certfile.write(cert) with open(key_path, 'w') as keyfile: keyfile.write(priv_key) shutil.copyfile(os.path.join(package_directory, 'server/beeswarmcfg.json.dist'), config_file) print '' print '* Communication between drones (honeypots and clients) and server *' print '* Please make sure that drones can always contact the Beeswarm server using the information that' \ ' you are about to enter. *' zmq_port = 5712 zmq_command_port = 5713 zmq_host = raw_input('IP or hostname of server: ') if customize: zmq_port = raw_input('TCP port for session data (default: 5712) : ') if zmq_port != '': zmq_port = int(zmq_port) zmq_command_port = raw_input('TCP port for drone commands(default: 5713) : ') if zmq_command_port != '': zmq_command_port = int(zmq_port) #tmp actor while initializing config_actor = ConfigActor('beeswarmcfg.json', work_dir) config_actor.start() context = zmq.Context() socket = context.socket(zmq.REQ) socket.connect('ipc://configCommands') socket.send('{0} {1}'.format(Messages.GEN_ZMQ_KEYS, 'beeswarm_server')) result = socket.recv() if result.split(' ', 1)[0] == Messages.OK: result = json.loads(result.split(' ', 1)[1]) zmq_public, zmq_private = (result['public_key'], result['private_key']) else: assert False socket.send('{0} {1}'.format(Messages.SET, json.dumps({'network': {'zmq_server_public_key': zmq_public, 'web_port': web_port, 'zmq_port': zmq_port, 'zmq_command_port': zmq_command_port, 'zmq_host': zmq_host}}))) socket.recv() config_actor.close()
def prepare_environment(self, work_dir, customize, server_hostname=None): config_file = self.config_file if not os.path.isfile(config_file): print '*** Please answer a few configuration options ***' if customize: logging.info('Copying configuration file to workdir.') print '' print '* Certificate Information *' print 'IMPORTANT: Please make sure that "Common Name" is the IP address or fully qualified host name ' \ ' that you want to use for the server API.' cert_cn = raw_input('Common Name: ') cert_country = raw_input('Country: ') cert_state = raw_input('State: ') cert_locality = raw_input('Locality/City: ') cert_org = raw_input('Organization: ') cert_org_unit = raw_input('Organizational unit: ') print '' print '* Network *' web_port = raw_input('Port for UI (default: 5000): ') if web_port: web_port = int(web_port) else: web_port = 5000 else: logging.warn( 'Beeswarm server will be configured using default ssl parameters and network ' 'configuration, this could be used to fingerprint the beeswarm server. If you want to ' 'customize these options please use the --customize options on first startup.' ) cert_cn = '*' cert_country = 'US' cert_state = 'None' cert_locality = 'None' cert_org = 'None' cert_org_unit = '' web_port = 5000 cert, priv_key = create_self_signed_cert(cert_country, cert_state, cert_org, cert_locality, cert_org_unit, cert_cn) cert_path = os.path.join(work_dir, 'server.crt') key_path = os.path.join(work_dir, 'server.key') with open(cert_path, 'w') as certfile: certfile.write(cert) with open(key_path, 'w') as keyfile: keyfile.write(priv_key) if not server_hostname: print '' print '* Communication between drones (honeypots and clients) and server *' print '* Please make sure that drones can always contact the Beeswarm server using the information that' \ ' you are about to enter. *' server_hostname = raw_input('IP or hostname of server: ') zmq_port = 5712 zmq_command_port = 5713 if customize: zmq_port_input = raw_input( 'TCP port for session data (default: 5712) : ') if zmq_port_input != '': zmq_port = int(zmq_port) zmq_command_port_input = raw_input( 'TCP port for drone commands(default: 5713) : ') if zmq_command_port_input != '': zmq_command_port = int(zmq_port) # tmp actor while initializing config_actor = ConfigActor(self.config_file, work_dir) config_actor.start() context = beeswarm.shared.zmq_context socket = context.socket(zmq.REQ) gevent.sleep() socket.connect(SocketNames.CONFIG_COMMANDS.value) socket.send('{0} {1}'.format(Messages.GET_ZMQ_KEYS.value, 'beeswarm_server')) result = socket.recv() if result.split(' ', 1)[0] == Messages.OK.value: result = json.loads(result.split(' ', 1)[1]) zmq_public, zmq_private = (result['public_key'], result['private_key']) else: assert False sqlite_db = os.path.join(work_dir, 'beeswarm_sqlite.db') message_dict = { 'network': { 'zmq_server_public_key': zmq_public, 'web_port': web_port, 'zmq_port': zmq_port, 'zmq_command_port': zmq_command_port, 'server_host': server_hostname }, 'sql': { 'connection_string': 'sqlite:///{0}'.format(sqlite_db) }, 'ssl': { 'certpath': 'server.crt', 'keypath': 'server.key' }, 'general': { 'mode': 'server' }, 'bait_session_retain': 2, 'malicious_session_retain': 100, 'ignore_failed_bait_session': False } socket.send('{0} {1}'.format(Messages.SET_CONFIG_ITEM.value, json.dumps(message_dict))) socket.recv() config_actor.stop()
def prepare_environment(self, work_dir, customize, server_hostname=None): config_file = self.config_file if not os.path.isfile(config_file): print '*** Please answer a few configuration options ***' if customize: logging.info('Copying configuration file to workdir.') print '' print '* Certificate Information *' print 'IMPORTANT: Please make sure that "Common Name" is the IP address or fully qualified host name ' \ ' that you want to use for the server API.' cert_cn = raw_input('Common Name: ') cert_country = raw_input('Country: ') cert_state = raw_input('State: ') cert_locality = raw_input('Locality/City: ') cert_org = raw_input('Organization: ') cert_org_unit = raw_input('Organizational unit: ') print '' print '* Network *' web_port = raw_input('Port for UI (default: 5000): ') if web_port: web_port = int(web_port) else: web_port = 5000 else: logging.warn('Beeswarm server will be configured using default ssl parameters and network ' 'configuration, this could be used to fingerprint the beeswarm server. If you want to ' 'customize these options please use the --customize options on first startup.') cert_cn = '*' cert_country = 'US' cert_state = 'None' cert_locality = 'None' cert_org = 'None' cert_org_unit = '' web_port = 5000 cert, priv_key = create_self_signed_cert(cert_country, cert_state, cert_org, cert_locality, cert_org_unit, cert_cn) cert_path = os.path.join(work_dir, 'server.crt') key_path = os.path.join(work_dir, 'server.key') with open(cert_path, 'w') as certfile: certfile.write(cert) with open(key_path, 'w') as keyfile: keyfile.write(priv_key) if not server_hostname: print '' print '* Communication between drones (honeypots and clients) and server *' print '* Please make sure that drones can always contact the Beeswarm server using the information that' \ ' you are about to enter. *' server_hostname = raw_input('IP or hostname of server: ') zmq_port = 5712 zmq_command_port = 5713 if customize: zmq_port_input = raw_input('TCP port for session data (default: 5712) : ') if zmq_port_input != '': zmq_port = int(zmq_port) zmq_command_port_input = raw_input('TCP port for drone commands(default: 5713) : ') if zmq_command_port_input != '': zmq_command_port = int(zmq_port) # tmp actor while initializing config_actor = ConfigActor(self.config_file, work_dir) config_actor.start() context = beeswarm.shared.zmq_context socket = context.socket(zmq.REQ) gevent.sleep() socket.connect(SocketNames.CONFIG_COMMANDS.value) socket.send('{0} {1}'.format(Messages.GET_ZMQ_KEYS.value, 'beeswarm_server')) result = socket.recv() if result.split(' ', 1)[0] == Messages.OK.value: result = json.loads(result.split(' ', 1)[1]) zmq_public, zmq_private = (result['public_key'], result['private_key']) else: assert False sqlite_db = os.path.join(work_dir, 'beeswarm_sqlite.db') message_dict = {'network': {'zmq_server_public_key': zmq_public, 'web_port': web_port, 'zmq_port': zmq_port, 'zmq_command_port': zmq_command_port, 'server_host': server_hostname}, 'sql': { 'connection_string': 'sqlite:///{0}'.format(sqlite_db)}, 'ssl': { 'certpath': 'server.crt', 'keypath': 'server.key' }, 'general': { 'mode': 'server' }, 'bait_session_retain': 2, 'malicious_session_retain': 100, 'ignore_failed_bait_session': False} socket.send('{0} {1}'.format(Messages.SET_CONFIG_ITEM.value, json.dumps(message_dict))) socket.recv() config_actor.stop()
def __init__(self, work_dir, config, key='server.key', cert='server.crt', **kwargs): """ Main class which runs Beeswarm in Honeypot mode. :param work_dir: Working directory (usually the current working directory) :param config: Beeswarm configuration dictionary, None if no configuration was supplied. :param key: Key file used for SSL enabled capabilities :param cert: Cert file used for SSL enabled capabilities """ if config is None or not os.path.isdir(os.path.join(work_dir, 'data')): Honeypot.prepare_environment(work_dir) with open('beeswarmcfg.json', 'r') as config_file: config = json.load(config_file, object_hook=asciify) self.work_dir = work_dir self.config = config self.key = key self.cert = cert self._servers = [] self._server_greenlets = [] # will contain Session objects self._sessions = {} self._session_consumer = None # TODO: pass honeypot otherwise Session.honeypot_id = self.config['general']['id'] self.id = self.config['general']['id'] # write ZMQ keys to files - as expected by pyzmq extract_keys(work_dir, config) if not (os.path.isfile(os.path.join(work_dir, 'server.key'))): cert_info = config['certificate_info'] if cert_info['common_name']: cert_info['common_name'] = cert_info['common_name'] else: cert_info['common_name'] = get_most_likely_ip() cert, priv_key = create_self_signed_cert( cert_info['country'], cert_info['state'], cert_info['organization'], cert_info['locality'], cert_info['organization_unit'], cert_info['common_name']) cert_path = os.path.join(work_dir, 'server.crt') key_path = os.path.join(work_dir, 'server.key') with open(cert_path, 'w') as certfile: certfile.write(cert) with open(key_path, 'w') as keyfile: keyfile.write(priv_key) send_zmq_push('inproc://serverRelay', '{0} {1} {2}'.format(Messages.KEY, self.id, keyfile)) send_zmq_push('inproc://serverRelay', '{0} {1} {2}'.format(Messages.CERT, self.id, cert)) if self.config['general']['fetch_ip']: try: url = 'http://api.externalip.net/ip' req = requests.get(url) self.honeypot_ip = req.text logger.info('Fetched {0} as external ip for Honeypot.'.format( self.honeypot_ip)) except (Timeout, ConnectionError) as e: logger.warning('Could not fetch public ip: {0}'.format(e)) else: self.honeypot_ip = '' # spawning time checker if self.config['timecheck']['enabled']: Greenlet.spawn(self.checktime)