def set_honeypot_mode(drone_id): db_session = database_setup.get_session() drone = db_session.query(Drone).filter(Drone.id == drone_id).one() if drone is None or drone.discriminator != 'honeypot': # meh, better way do do this? db_session.delete(drone) db_session.commit() honeypot = Honeypot(id=drone_id) honeypot.ip_address = drone.ip_address db_session.add(honeypot) db_session.commit() return '' else: return ''
def setUp(self): self.password = '******' app.ensure_admin_password(True, password=self.password) app.app.config['WTF_CSRF_ENABLED'] = False self.work_dir = tempfile.mkdtemp() beeswarm.shared.zmq_context = zmq.Context() fd, self.db_file = tempfile.mkstemp() os.close(fd) connection_string = 'sqlite:///{0}'.format(self.db_file) os.remove(self.db_file) database.setup_db(connection_string) self.config_actor = ConfigActor( os.path.join(os.path.dirname(__file__), 'beeswarmcfg.json.test'), self.work_dir) self.config_actor.start() # seed database with test data session = database.get_session() session.add_all([Client(), Honeypot()]) session.commit() # startup session database self.database_actor = DatabaseActor(999, delay_seconds=2) self.database_actor.start() self.app = app.app.test_client() app.connect_sockets()
def setUp(self): app.app.config['WTF_CSRF_ENABLED'] = False self.work_dir = tempfile.mkdtemp() self.config_actor = ConfigActor( os.path.join(os.path.dirname(__file__), 'beeswarmcfg.json.test'), self.work_dir) self.config_actor.start() self.app = app.app.test_client() self.authenticator = Authenticator() database.setup_db('sqlite://') session = database.get_session() # dummy entities self.authenticator.add_user('test', 'test', 0) self.client_id = str(uuid.uuid4()) self.client_password = str(uuid.uuid4()) self.authenticator.add_user(self.client_id, self.client_password, 2) self.honeypot_id = str(uuid.uuid4()) self.honeypot_password = str(uuid.uuid4()) self.authenticator.add_user(self.honeypot_id, self.honeypot_password, 1) session.add_all([ Client(id=self.client_id, configuration='test_client_config'), Honeypot(id=self.honeypot_id, configuration='test_honeypot_config') ]) session.commit()
def populate_honeypots(self): """ Populates the database with 4 honeypots """ db_session = database.get_session() self.honeypots = [] for i in xrange( 4): # We add 4 here, but one is added in the setup method h = Honeypot() self.honeypots.append(h.id) db_session.add(h) db_session.commit()
def populate_honeypots(self): """ Populates the database with 4 honeypots """ db_session = database.get_session() self.honeypots = [] for i in xrange( 4): # We add 4 here, but one is added in the setup method curr_id = str(uuid.uuid4()) curr_id = curr_id.encode('utf-8') self.honeypots.append(curr_id) h = Honeypot(id=curr_id) db_session.add(h) db_session.commit()
def test_matching_quick_succession(self): """ Tests that attack sessions coming in quick succession are classified correctly. This test relates to issue #218 """ honeypot_id = 1 honeypot = Honeypot(id=honeypot_id) db_session = database_setup.get_session() db_session.add(honeypot) db_session.commit() drone_data_socket = beeswarm.shared.zmq_context.socket(zmq.PUB) drone_data_socket.bind(SocketNames.DRONE_DATA.value) # startup session database database_actor = DatabaseActor(999, delay_seconds=2) database_actor.start() gevent.sleep(1) for x in xrange(0, 100): honeypot_session = HoneypotSession(source_ip='192.168.100.22', source_port=52311, protocol='pop3', users={}, destination_port=110) honeypot_session.add_auth_attempt('plaintext', True, username='******', password='******') honeypot_session.honeypot_id = honeypot_id drone_data_socket.send('{0} {1} {2}'.format( Messages.SESSION_HONEYPOT.value, honeypot_id, json.dumps(honeypot_session.to_dict(), default=json_default, ensure_ascii=False))) gevent.sleep(1) database_actor_request_socket = beeswarm.shared.zmq_context.socket( zmq.REQ) database_actor_request_socket.connect( SocketNames.DATABASE_REQUESTS.value) sessions = send_zmq_request_socket( database_actor_request_socket, '{0}'.format(Messages.GET_SESSIONS_ALL.value)) for session in sessions: self.assertEqual(session['classification'], 'Bruteforce') self.assertEqual(len(sessions), 100)
def _config_honeypot(self, drone, db_session, config): if drone.discriminator != 'honeypot': # meh, better way do do this? drone_id = drone.id ip_address = drone.ip_address db_session.delete(drone) db_session.commit() drone = Honeypot(id=drone_id) drone.ip_address = ip_address db_session.add(drone) db_session.commit() # common properties drone.name = config['name'] # certificate information drone.cert_common_name = config['certificate']['common_name'] drone.cert_country = config['certificate']['country'] drone.cert_state = config['certificate']['state'] drone.cert_locality = config['certificate']['locality'] drone.cert_organization = config['certificate']['organization'] drone.cert_organization_unit = config['certificate']['organization_unit'] # add capabilities drone.capabilities = [] for protocol_name, protocol_config in config['capabilities'].items(): if 'protocol_specific_data' in protocol_config: protocol_specific_data = protocol_config['protocol_specific_data'] else: protocol_specific_data = {} drone.add_capability(protocol_name, protocol_config['port'], protocol_specific_data) db_session.add(drone) db_session.commit() self._handle_command_drone_config_changed(drone.id)
def bootstrap(server_workdir, drone_workdir): """Bootstraps localhost configurations for a Beeswarm server and a honeypot. :param server_workdir: Output directory for the server configuration file. :param drone_workdir: Output directory for the drone configuration file. """ root_logger = logging.getLogger() root_logger.setLevel(logging.DEBUG) formatter = logging.Formatter('%(asctime)-15s (%(name)s) %(message)s') console_log = logging.StreamHandler() console_log.setLevel(logging.INFO) console_log.setFormatter(formatter) root_logger.addHandler(console_log) server_workdir_absolute = os.path.abspath(server_workdir) old_cwd = os.getcwd() os.chdir(server_workdir) server = Server(server_workdir_absolute, None, start_webui=False, customize=False, reset_password=False, max_sessions=0, server_hostname='127.0.0.1') logger.info('Server config has been written to {0}'.format(os.path.join(server_workdir, 'beeswarmcfg.json'))) gevent.spawn(server.start, False) # waiting game to ensure actors has started. gevent.sleep(2) os.chdir(old_cwd) # setting up socket to communicate with ZMQ actor. context = beeswarm.shared.zmq_context config_actor_socket = context.socket(zmq.REQ) config_actor_socket.connect(SocketNames.CONFIG_COMMANDS) db_session = database_setup.get_session() drone = Honeypot() protocol_config = ( ('ftp', 21, { 'max_attempts': 3, 'banner': 'Microsoft FTP Server', 'syst_type': 'Windows-NT' }), ('telnet', 23, { 'max_attempts': 3 }), ('pop3', 110, { 'max_attempts': 3 }), ('pop3s', 993, { 'max_attempts': 3 }), ('ssh', 22, {}), ('http', 80, { 'banner': 'Microsoft-IIS/5.0' }), ('https', 443, { 'banner': 'Microsoft-IIS/5.0' }), ('smtp', 25, { 'banner': 'Microsoft ESMTP MAIL service ready' }), ('vnc', 5900, {}) ) for protocol, port, protocol_specific_data in protocol_config: drone.add_capability(protocol, port, protocol_specific_data) drone.cert_common_name = '*' drone.cert_country = 'US' drone.cert_state = 'None' drone.cert_locality = 'None' drone.cert_organization = 'None' drone.cert_organization_unit = '' db_session.add(drone) db_session.commit() drone_config = send_zmq_request_socket(config_actor_socket, '{0} {1}'.format(Messages.DRONE_CONFIG, drone.id)) with open(os.path.join(drone_workdir, 'beeswarmcfg.json'), 'w') as drone_config_file: drone_config_file.write(json.dumps(drone_config, indent=4)) logger.info('Drone config has been written to {0}'.format(os.path.join(server_workdir, 'beeswarmcfg.json'))) server.stop()
def fill_dummy_data(): """ Populates the server data with dummy data to ease development. """ db_session = database_setup.get_session() protocols = [('pop3', 110), ('ssh', 22), ('telnet', 23), ('ftp', 21), ('http', 80)] source_ips = ('192.168.1.2', '192.168.2.3', '192.168.3.4', '192.168.4.5') honeypots = [Honeypot(id=str(uuid.uuid4()))] client = [Client(id=str(uuid.uuid4()))] sessions = [] authentications = [] while len(sessions) < 100: session = BaitSession(id=str(uuid.uuid4()), timestamp=datetime.now(), source_ip=random.choice(source_ips), source_port=random.randint(1024, 65535), destination_ip='4.3.2.1', destination_port='1111') session.protocol, session.destination_port = random.choice(protocols) session.honeypot = random.choice(honeypots) session.client = random.choice(client) session.classification = db_session.query(Classification).filter( Classification.type == 'bait_session').one() username = ''.join(random.choice(string.lowercase) for x in range(8)) password = ''.join(random.choice(string.lowercase) for x in range(8)) authentication = Authentication(id=str(uuid.uuid4()), username=username, password=password) session.authentication.append(authentication) for x in range(10): data = ''.join(random.choice(string.lowercase) for x in range(15)) direction = ('in', 'out')[x % 2] transcript = Transcript(timestamp=datetime.now(), direction=direction, data=data) session.transcript.append(transcript) authentications.append(authentication) sessions.append(session) while len(sessions) < 200: session = Session(id=str(uuid.uuid4()), timestamp=datetime.now(), source_ip=random.choice(source_ips), source_port=random.randint(1024, 65535), destination_ip='4.3.2.1', destination_port='1111') session.protocol, session.destination_port = random.choice(protocols) session.honeypot = random.choice(honeypots) session.classification = db_session.query(Classification).filter( Classification.type == 'credentials_reuse').one() username = ''.join(random.choice(string.lowercase) for x in range(8)) password = ''.join(random.choice(string.lowercase) for x in range(8)) authentication = Authentication(id=str(uuid.uuid4()), username=username, password=password) session.authentication.append(authentication) authentications.append(authentication) sessions.append(session) db_session.add_all(authentications) db_session.add_all(sessions) db_session.add_all(honeypots) db_session.add_all(client) db_session.commit()
def populate_bait(self, honeypot_first): honeypot_id = 1 client_id = 2 honeypot = Honeypot(id=honeypot_id) client = Client(id=client_id) db_session = database_setup.get_session() db_session.add(honeypot) db_session.add(client) db_session.commit() drone_data_socket = beeswarm.shared.zmq_context.socket(zmq.PUB) drone_data_socket.bind(SocketNames.DRONE_DATA.value) config_file = tempfile.mkstemp()[1] os.remove(config_file) # persistence actor needs to communicate with on config REQ/REP socket config_actor = ConfigActor(config_file, '') config_actor.start() # startup session database database_actor = DatabaseActor(999, delay_seconds=2) database_actor.start() gevent.sleep(1) BaitSession.client_id = client_id honeypot_session = HoneypotSession(source_ip='192.168.100.22', source_port=52311, protocol='pop3', users={}, destination_port=110) honeypot_session.add_auth_attempt('plaintext', True, username='******', password='******') honeypot_session.honeypot_id = honeypot_id bait_session = BaitSession('pop3', '1234', 110, honeypot_id) bait_session.add_auth_attempt('plaintext', True, username='******', password='******') bait_session.honeypot_id = honeypot_id bait_session.did_connect = bait_session.did_login = bait_session.alldone = bait_session.did_complete = True if honeypot_first: drone_data_socket.send('{0} {1} {2}'.format( Messages.SESSION_HONEYPOT.value, honeypot_id, json.dumps(honeypot_session.to_dict(), default=json_default, ensure_ascii=False))) drone_data_socket.send('{0} {1} {2}'.format( Messages.SESSION_CLIENT.value, client_id, json.dumps(bait_session.to_dict(), default=json_default, ensure_ascii=False))) else: drone_data_socket.send('{0} {1} {2}'.format( Messages.SESSION_CLIENT.value, client_id, json.dumps(bait_session.to_dict(), default=json_default, ensure_ascii=False))) drone_data_socket.send('{0} {1} {2}'.format( Messages.SESSION_HONEYPOT.value, honeypot_id, json.dumps(honeypot_session.to_dict(), default=json_default, ensure_ascii=False))) # some time for the session actor to work gevent.sleep(2) config_actor.stop() database_actor.stop() if os.path.isfile(config_file): os.remove(config_file)
def bootstrap(server_workdir, drone_workdir): """Bootstraps localhost configurations for a Beeswarm server and a honeypot. :param server_workdir: Output directory for the server configuration file. :param drone_workdir: Output directory for the drone configuration file. """ root_logger = logging.getLogger() root_logger.setLevel(logging.DEBUG) formatter = logging.Formatter('%(asctime)-15s (%(name)s) %(message)s') console_log = logging.StreamHandler() console_log.setLevel(logging.INFO) console_log.setFormatter(formatter) root_logger.addHandler(console_log) server_workdir_absolute = os.path.abspath(server_workdir) old_cwd = os.getcwd() os.chdir(server_workdir) server = Server(server_workdir_absolute, None, start_webui=False, customize=False, reset_password=False, max_sessions=0, server_hostname='127.0.0.1') logger.info('Server config has been written to {0}'.format(os.path.join(server_workdir, 'beeswarmcfg.json'))) gevent.spawn(server.start, False) # waiting game to ensure actors has started. gevent.sleep(2) os.chdir(old_cwd) # setting up socket to communicate with ZMQ actor. context = beeswarm.shared.zmq_context database_actor = context.socket(zmq.REQ) database_actor.connect(SocketNames.DATABASE_REQUESTS.value) db_session = database_setup.get_session() drone = Honeypot() protocol_config = ( ('ftp', 21, { 'max_attempts': 3, 'banner': 'Microsoft FTP Server', 'syst_type': 'Windows-NT' }), ('telnet', 23, { 'max_attempts': 3 }), ('pop3', 110, { 'max_attempts': 3 }), ('pop3s', 993, { 'max_attempts': 3 }), ('ssh', 22, {}), ('http', 80, { 'banner': 'Microsoft-IIS/5.0' }), ('https', 443, { 'banner': 'Microsoft-IIS/5.0' }), ('smtp', 25, { 'banner': 'Microsoft ESMTP MAIL service ready' }), ('vnc', 5900, {}) ) for protocol, port, protocol_specific_data in protocol_config: drone.add_capability(protocol, port, protocol_specific_data) drone.cert_common_name = '*' drone.cert_country = 'US' drone.cert_state = 'None' drone.cert_locality = 'None' drone.cert_organization = 'None' drone.cert_organization_unit = '' db_session.add(drone) db_session.commit() drone_config = send_zmq_request_socket(database_actor, '{0} {1}'.format(Messages.DRONE_CONFIG.value, drone.id)) with open(os.path.join(drone_workdir, 'beeswarmcfg.json'), 'w') as drone_config_file: drone_config_file.write(json.dumps(drone_config, indent=4)) logger.info('Drone config has been written to {0}'.format(os.path.join(server_workdir, 'beeswarmcfg.json'))) server.stop()