def __init__(self, max_sessions, clear_sessions=False, delay_seconds=30): assert delay_seconds > 1 Greenlet.__init__(self) db_session = database_setup.get_session() self.enabled = True # pending session will be converted to attacks if we cannot match with bait traffic # with this period self.delay_seconds = delay_seconds # clear all pending sessions on startup, pending sessions on startup pending_classification = db_session.query(Classification).filter(Classification.type == 'pending').one() pending_deleted = db_session.query(Session).filter( Session.classification == pending_classification).delete() db_session.commit() logging.info('Cleaned {0} pending sessions on startup'.format(pending_deleted)) self.do_classify = False self.do_maintenance = False if clear_sessions or max_sessions == 0: db_session = database_setup.get_session() count = db_session.query(Session).delete() logging.info('Deleting {0} sessions on startup.'.format(count)) db_session.commit() self.max_session_count = max_sessions if max_sessions: logger.info('Database has been limited to contain {0} sessions.'.format(max_sessions)) context = beeswarm.shared.zmq_context # prepare sockets self.drone_data_socket = context.socket(zmq.SUB) self.processedSessionsPublisher = context.socket(zmq.PUB) self.databaseRequests = context.socket(zmq.REP) self.config_actor_socket = context.socket(zmq.REQ) self.drone_command_receiver = context.socket(zmq.PUSH)
def test_data_transcripts(self): """ Tests that if given a session ID we can extract the relevant transcripts""" db_session = database.get_session() self.login('test', self.password) session_id = str(uuid.uuid4()) timestamp = datetime.utcnow() db_session.add( Transcript(timestamp=timestamp, direction='outgoing', data='whoami', session_id=session_id)) db_session.add( Transcript(timestamp=timestamp, direction='outgoing', data='root\r\n', session_id=session_id)) db_session.commit() resp = self.app.get('/data/session/{0}/transcript'.format(session_id)) data = json.loads(resp.data) string_timestamp = timestamp.strftime('%Y-%m-%d %H:%M:%S') expected_result = [{ u'direction': u'outgoing', u'data': u'whoami', u'time': u'{0}'.format(string_timestamp) }, { u'direction': u'outgoing', u'data': u'root\r\n', u'time': u'{0}'.format(string_timestamp) }] self.assertDictEqual(sorted(data)[0], sorted(expected_result)[0])
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 _handle_ping_all_drones(self): db_session = database_setup.get_session() drones = db_session.query(Drone) for drone in drones: logger.debug('Sending ping to {0}'.format(drone.id)) self.drone_command_receiver.send('{0} {1} {2}'.format(drone.id, Messages.PING.value, ''))
def populate_honeybees(self): """ Populates the database with 3 Honeybees """ db_session = database.get_session() for i in xrange(3): h = BaitSession( id=str(uuid.uuid4()), timestamp=datetime.utcnow(), received=datetime.utcnow(), protocol="ssh", destination_ip="1.2.3.4", destination_port=1234, source_ip="4.3.2.1", source_port=4321, did_connect=True, did_login=False, did_complete=True, ) a = Authentication( id=str(uuid.uuid4()), username="******", password="******", successful=False, timestamp=datetime.utcnow() ) h.authentication.append(a) db_session.add(h) db_session.commit()
def add_user(self, username, password, user_type, nickname=''): session = database_setup.get_session() userid = username pw_hash = generate_password_hash(password) u = User(id=userid, nickname=nickname, password=pw_hash, utype=user_type) session.add(u) session.commit()
def classify_bait_session(self, delay_seconds=30, db_session=None): """ Will classify all unclassified bait_sessions as either legit or malicious activity. A bait session can e.g. be classified as involved in malicious activity if the bait session is subject to a MiTM attack. :param delay_seconds: no bait_sessions newer than (now - delay_seconds) will be processed. """ min_datetime = datetime.datetime.utcnow() - datetime.timedelta(seconds=delay_seconds) if not db_session: db_session = database_setup.get_session() bait_sessions = db_session.query(BaitSession).options(joinedload(BaitSession.authentication)) \ .filter(BaitSession.classification_id == 'unclassified') \ .filter(BaitSession.did_complete == True) \ .filter(BaitSession.timestamp < min_datetime).all() for bait_session in bait_sessions: session_match = self.get_matching_session(bait_session, db_session=db_session) # if we have a match this is legit bait session if session_match: logger.debug('Classifying bait session with id {0} as legit bait session and deleting ' 'matching session with id {1}'.format(bait_session.id, session_match.id)) bait_session.classification = db_session.query(Classification).filter(Classification.type == 'bait_session').one() db_session.delete(session_match) # else we classify it as a MiTM attack else: bait_session.classification = db_session.query(Classification).filter(Classification.type == 'mitm_1').one() db_session.commit()
def __init__(self, max_sessions, clear_sessions=False, delay_seconds=30): assert delay_seconds > 1 Greenlet.__init__(self) self.db_session = database_setup.get_session() # pending session will be converted to attacks if we cannot match with bait traffic # with this period self.delay_seconds = delay_seconds # clear all pending sessions on startup, pending sessions on startup pending_classification = self.db_session.query(Classification).filter(Classification.type == 'pending').one() pending_deleted = self.db_session.query(Session).filter( Session.classification == pending_classification).delete() self.db_session.commit() logging.info('Cleaned {0} pending sessions on startup'.format(pending_deleted)) self.do_classify = False if clear_sessions or max_sessions == 0: count = self.db_session.query(Session).delete() logging.info('Deleting {0} sessions on startup.'.format(count)) self.db_session.commit() self.max_session_count = max_sessions if max_sessions: logger.info('Database has been limited to contain {0} sessions.'.format(max_sessions)) context = beeswarm.shared.zmq_context self.subscriber_sessions = context.socket(zmq.SUB) self.subscriber_sessions.connect(SocketNames.RAW_SESSIONS) self.subscriber_sessions.setsockopt(zmq.SUBSCRIBE, Messages.SESSION_CLIENT) self.subscriber_sessions.setsockopt(zmq.SUBSCRIBE, Messages.SESSION_HONEYPOT) self.processedSessionsPublisher = context.socket(zmq.PUB) self.processedSessionsPublisher.bind(SocketNames.PROCESSED_SESSIONS) self.config_actor_socket = context.socket(zmq.REQ) self.config_actor_socket.connect(SocketNames.CONFIG_COMMANDS)
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) fd, config_file = tempfile.mkstemp() os.close(fd) 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 _handle_command_get_db_stats(self): db_session = database_setup.get_session() database_stats = { 'count_honeypots': db_session.query(Honeypot).count(), 'count_clients': db_session.query(Client).count(), 'count_sessions': db_session.query(Session).count(), 'count_all_baits': db_session.query(BaitSession).count(), 'count_all_attacks': db_session.query(Session).filter(Session.classification_id != 'bait_session') .filter(Session.classification_id != 'pending') .filter(Session.classification_id is not None).count(), 'count_attack_type': { 'http': self._get_num_attacks('http', db_session), 'vnc': self._get_num_attacks('vnc', db_session), 'ssh': self._get_num_attacks('ssh', db_session), 'ftp': self._get_num_attacks('ftp', db_session), 'https': self._get_num_attacks('https', db_session), 'pop3': self._get_num_attacks('pop3', db_session), 'pop3s': self._get_num_attacks('pop3s', db_session), 'smtp': self._get_num_attacks('smtp', db_session), 'telnet': self._get_num_attacks('telnet', db_session), }, 'baits': { 'successful': db_session.query(BaitSession).filter(BaitSession.did_login).count(), 'failed': db_session.query(BaitSession).filter(not BaitSession.did_login).count(), } } return database_stats
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 _reconfigure_all_clients(self): db_session = database_setup.get_session() db_session.query(DroneEdge).delete() db_session.commit() honeypots = db_session.query(Honeypot).all() clients = db_session.query(Client).all() # delete old architecture credentials = db_session.query(BaitUser).all() for honeypot in honeypots: for capability in honeypot.capabilities: for client in clients: # following three variables should be make somewhat user configurable again client_timings = json.loads(client.bait_timings) if capability.protocol in client_timings: # the time range in which to activate the bait sessions activation_range = client_timings[capability.protocol]['active_range'] # period to sleep before using activation_probability sleep_interval = client_timings[capability.protocol]['sleep_interval'] # the probability that a bait session will be activated, 1 is always activate activation_probability = client_timings[capability.protocol]['activation_probability'] else: logger.warning('Bait timings for {0} not found on client drone {1}({2}), using defaults instead' .format(capability.protocol, client.name, client.id)) activation_range = '00:00 - 23:59' sleep_interval = '60' activation_probability = 1 bait_credentials = random.choice(credentials) client.add_bait(capability, activation_range, sleep_interval, activation_probability, bait_credentials.username, bait_credentials.password) db_session.commit() drones = db_session.query(Drone).all() for drone in drones: self._send_config_to_drone(drone.id)
def _db_maintenance(self): logger.debug('Doing database maintenance') bait_session_retain_days = int( self.send_config_request('{0} {1}'.format( Messages.GET_CONFIG_ITEM.value, 'bait_session_retain'))) bait_retain = datetime.utcnow() - timedelta( days=bait_session_retain_days) malicious_session_retain_days = int( self.send_config_request('{0} {1}'.format( Messages.GET_CONFIG_ITEM.value, 'malicious_session_retain'))) malicious_retain = datetime.utcnow() - timedelta( days=malicious_session_retain_days) db_session = database_setup.get_session() malicious_deleted_count = db_session.query(Session).filter(Session.classification_id != 'bait_session') \ .filter(Session.timestamp < malicious_retain).delete() bait_deleted_count = db_session.query(Session).filter(Session.classification_id == 'bait_session') \ .filter(Session.timestamp < bait_retain).delete() db_session.commit() logger.info( 'Database maintenance finished. Deleted {0} bait_sessions and {1} malicious sessions)' .format(bait_deleted_count, malicious_deleted_count))
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 get_bait_users(): db_session = database_setup.get_session() if request.method == 'GET': bait_users = db_session.query(BaitUser) rows = [] for bait_user in bait_users: row = { 'id': bait_user.id, 'username': bait_user.username, 'password': bait_user.password } rows.append(row) rsp = Response(response=json.dumps(rows, indent=4), status=200, mimetype='application/json') return rsp else: db_session.query(BaitUser).delete() bait_users = json.loads(request.data) for bait_user in bait_users: new_bait_users = BaitUser(username=bait_user['username'], password=bait_user['password']) db_session.add(new_bait_users) db_session.commit() 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 populate_honeybees(self): """ Populates the database with 3 Honeybees """ db_session = database.get_session() for i in xrange(3): h = BaitSession(id=str(uuid.uuid4()), timestamp=datetime.utcnow(), received=datetime.utcnow(), protocol='ssh', destination_ip='1.2.3.4', destination_port=1234, source_ip='4.3.2.1', source_port=4321, did_connect=True, did_login=False, did_complete=True) a = Authentication(id=str(uuid.uuid4()), username='******', password='******', successful=False, timestamp=datetime.utcnow()) h.authentication.append(a) db_session.add(h) db_session.commit()
def _handle_command_get_sessions(self, _type): db_session = database_setup.get_session() # the database_setup will not get hit until we start iterating the query object query_iterators = { Messages.GET_SESSIONS_ALL.value: db_session.query(Session, Drone.name), Messages.GET_SESSIONS_BAIT.value: db_session.query(BaitSession, Drone.name), Messages.GET_SESSIONS_ATTACKS.value: db_session.query( Session, Drone.name).filter(Session.classification_id != 'bait_session') } if _type not in query_iterators: logger.warning( 'Query for sessions with unknown type: {0}'.format(_type)) return [] # select which iterator to use entries = query_iterators[_type].order_by(desc(Session.timestamp)) rows = [] for session in entries: session[0].name = session[1] rows.append(session[0].to_dict()) return rows
def data_drones(dronetype): db_session = database_setup.get_session() if dronetype is None: drones = db_session.query(Drone).all() elif dronetype == 'unassigned': drones = db_session.query(Drone).filter(Drone.discriminator == None) else: drones = db_session.query(Drone).filter( Drone.discriminator == dronetype) rows = [] for d in drones: if d.last_activity == datetime.min: timestamp = 'Never' else: timestamp = d.last_activity.strftime('%Y-%m-%d %H:%M:%S') if d.discriminator is None: _type = '' else: _type = d.discriminator.capitalize() row = { 'id': d.id, 'name': d.name, 'type': _type, 'last_activity': timestamp } rows.append(row) rsp = Response(response=json.dumps(rows, indent=4), status=200, mimetype='application/json') return rsp
def _handle_command_config_drone(self, data): drone_id, config = data.split(' ', 1) config = json.loads(config) db_session = database_setup.get_session() drone = db_session.query(Drone).filter(Drone.id == drone_id).one() if not drone: self.databaseRequests.send('{0} {1}'.format( Messages.FAIL.value, 'Drone with id {0} could not ' 'found'.format(drone_id))) elif config['mode'] == 'honeypot': # it is a honeypot self._config_honeypot(drone, db_session, config) self.databaseRequests.send('{0} {1}'.format(Messages.OK.value, {})) elif config['mode'] == 'client': # it is a client self._config_client(drone, db_session, config) self.databaseRequests.send('{0} {1}'.format(Messages.OK.value, {})) else: logger.error( 'Could not detect mode for drone config, drone id: {0}'.format( drone_id)) self.databaseRequests.send('{0} {1}'.format( Messages.FAIL.value, 'Malformed data in drone config data.' 'Drone id: {0}'.format(drone_id)))
def home(): db_session = database_setup.get_session() status = { 'nhoneypots': db_session.query(Honeypot).count(), 'nclients': db_session.query(Client).count(), 'nsessions': db_session.query(Session).count(), 'nbees': db_session.query(BaitSession).count(), 'nattacks': db_session.query(Session).filter(Session.classification_id != 'bait_session')\ .filter(Session.classification_id is not None).count(), 'attacks': { 'http': get_num_attacks('http'), 'vnc': get_num_attacks('vnc'), 'ssh': get_num_attacks('ssh'), 'ftp': get_num_attacks('ftp'), 'https': get_num_attacks('https'), 'pop3': get_num_attacks('pop3'), 'pop3s': get_num_attacks('pop3s'), 'smtp': get_num_attacks('smtp'), 'telnet': get_num_attacks('telnet'), }, 'bees': { 'successful': db_session.query(BaitSession).filter(BaitSession.did_login).count(), 'failed': db_session.query(BaitSession).filter(not BaitSession.did_login).count(), } } urls = { 'honeypotdata': '/data/honeypots', 'clientdata': '/data/clients', 'delhoneypot': '/ws/honeypot/delete', 'delclient': '/ws/client/delete' } return render_template('index.html', user=current_user, status=status, urls=urls)
def configure_drone(id): db_session = database_setup.get_session() drone = db_session.query(Drone).filter(Drone.id == id).one() if drone is None: abort(404, 'Drone with id {0} could not be found.'.format(id)) else: return render_template('drone_mode.html', drone_id=drone.id, user=current_user)
def data_sessions_attacks(_type): db_session = database_setup.get_session() #the database_setup will not get hit until we start iterating the query object query_iterators = { 'all': db_session.query(Session), 'bait_sessions': db_session.query(BaitSession), 'attacks': db_session.query(Session).filter(Session.classification_id != 'bait_session') } if _type not in query_iterators: return 'Not Found', 404 #select which iterator to use entries = query_iterators[_type] rows = [] for a in entries: auth_attempts = [] for attempt in a.authentication: auth_attempts.append( {'username': attempt.username, 'password': attempt.password, 'successful': attempt.successful}) classification = a.classification_id.replace('_', ' ').capitalize() row = {'time': a.timestamp.strftime('%Y-%m-%d %H:%M:%S'), 'protocol': a.protocol, 'ip_address': a.source_ip, 'classification': classification, 'id': a.id, 'auth_attempts': auth_attempts} rows.append(row) rsp = Response(response=json.dumps(rows, indent=4), status=200, mimetype='application/json') return rsp
def _handle_command_get_credentials(self, session_id): db_session = database_setup.get_session() credentials = db_session.query(Authentication).filter(Authentication.session_id == session_id) return_rows = [] for credential in credentials: return_rows.append(credential.to_dict()) return return_rows
def _handle_ping_all_drones(self): db_session = database_setup.get_session() drones = db_session.query(Drone) for drone in drones: logger.debug('Sending ping to {0}'.format(drone.id)) self.drone_command_receiver.send( '{0} {1} {2}'.format(drone.id, Messages.PING.value, ''))
def _handle_command_get_bait_users(self): db_session = database_setup.get_session() bait_users = db_session.query(BaitUser) return_rows = [] for bait_user in bait_users: row = {'id': bait_user.id, 'username': bait_user.username, 'password': bait_user.password} return_rows.append(row) return return_rows
def add_bait_users(): db_session = database_setup.get_session() bait_users = json.loads(request.data) for bait_user in bait_users: # TODO: Also validate client side if bait_user['username'] == '': continue send_config_request('{0} {1} {2}'.format(Messages.BAIT_USER_ADD, bait_user['username'], bait_user['password'])) return ''
def _update_drone_last_activity(self, drone_id): db_session = database_setup.get_session() drone = db_session.query(Drone).filter(Drone.id == drone_id).one() if drone: drone.last_activity = datetime.now() db_session.add(drone) db_session.commit() else: logger.warning('Trying to update last activity non-exting drone with id {0}'.format(drone_id))
def _handle_command_add_drone(self): db_session = database_setup.get_session() drone = Drone() db_session.add(drone) db_session.commit() logger.debug('New drone has been added with id: {0}'.format(drone.id)) drone_config = self._get_drone_config(drone.id) self.databaseRequests.send('{0} {1}'.format(Messages.OK.value, json.dumps(drone_config)))
def _handle_command_bait_user_add(self, data): username, password = data.split(' ') db_session = database_setup.get_session() existing_bait_user = db_session.query(BaitUser).filter(BaitUser.username == username, BaitUser.password == password).first() if not existing_bait_user: new_bait_user = BaitUser(username=username, password=password) db_session.add(new_bait_user) db_session.commit()
def user_loader(userid): userid = userid.encode('utf-8') db_session = database_setup.get_session() user = None try: user = db_session.query(User).filter(User.id == userid).one() except NoResultFound: logger.info('Attempt to load non-existent user: {0}'.format(userid)) return user
def data_session_credentials(_id): db_session = database_setup.get_session() credentials = db_session.query(Authentication).filter(Authentication.session_id == _id) return_rows = [] for c in credentials: return_rows.append(c.to_dict()) rsp = Response(response=json.dumps(return_rows, indent=4), status=200, mimetype='application/json') return rsp
def _bait_user_changed(self, username, password): db_session = database_setup.get_session() drone_edge = db_session.query(DroneEdge).filter(DroneEdge.username == username, DroneEdge.password == password).first() # A drone is using the bait users, reconfigure all # TODO: This is lazy, we should only reconfigure the drone(s) who are actually # using the credentials if drone_edge: self._reconfigure_all_clients()
def populate_bait_users(self): """ Populates the database with 2 bait users """ db_session = database.get_session() db_session.query(BaitUser).delete() self.clients = [] for c in [("userA", "passA"), ("userB", "passB")]: # We add 4 here, but one is added in the setup method bait_user = BaitUser(username=c[0], password=c[1]) db_session.add(bait_user) db_session.commit()
def _handle_command_bait_user_delete(self, data): bait_user_id = int(data) db_session = database_setup.get_session() bait_user = db_session.query(BaitUser).filter(BaitUser.id == bait_user_id).first() if bait_user: db_session.delete(bait_user) db_session.commit() self._bait_user_changed(bait_user.username, bait_user.password) else: logger.warning('Tried to delete non-existing bait user with id {0}.'.format(bait_user_id))
def data_honeypots(): db_session = database_setup.get_session() honeypots = db_session.query(Honeypot).all() rows = [] for h in honeypots: row = {'honeypot_id': h.id, 'attacks': db_session.query(Session).filter(Session.honeypot_id == h.id).count(), 'checked': False, 'name': h.name} rows.append(row) rsp = Response(response=json.dumps(rows, indent=4), status=200, mimetype='application/json') return rsp
def data_session_transcript(_id): db_session = database_setup.get_session() transcripts = db_session.query(Transcript).filter(Transcript.session_id == _id) return_rows = [] for t in transcripts: row = {'time': t.timestamp.strftime('%Y-%m-%d %H:%M:%S'), 'direction': t.direction, 'data': t.data} return_rows.append(row) rsp = Response(response=json.dumps(return_rows, indent=4), status=200, mimetype='application/json') return rsp
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_clients(self): """ Populates the database with 4 clients """ db_session = database.get_session() self.clients = [] for i in xrange(4): # We add 4 here, but one is added in the setup method f = Client() self.clients.append(f.id) db_session.add(f) db_session.commit()
def _handle_command_get_transcript(self, session_id): db_session = database_setup.get_session() transcripts = db_session.query(Transcript).filter(Transcript.session_id == session_id) return_rows = [] for transcript in transcripts: row = {'time': transcript.timestamp.strftime('%Y-%m-%d %H:%M:%S'), 'direction': transcript.direction, 'data': transcript.data} return_rows.append(row) return return_rows
def populate_bait_users(self): """ Populates the database with 2 bait users """ db_session = database.get_session() db_session.query(BaitUser).delete() self.clients = [] for c in [('userA', 'passA'), ('userB', 'passB') ]: # We add 4 here, but one is added in the setup method bait_user = BaitUser(username=c[0], password=c[1]) db_session.add(bait_user) 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 h = Honeypot() self.honeypots.append(h.id) db_session.add(h) db_session.commit()
def populate_clients(self): """ Populates the database with 4 clients """ db_session = database.get_session() self.clients = [] for i in xrange( 4): # We add 4 here, but one is added in the setup method f = Client() self.clients.append(f.id) db_session.add(f) db_session.commit()
def _classify_malicious_sessions(self): """ Will classify all unclassified sessions as malicious activity. :param delay_seconds: no sessions newer than (now - delay_seconds) will be processed. """ min_datetime = datetime.utcnow() - timedelta(seconds=self.delay_seconds) db_session = database_setup.get_session() # find and process bait sessions that did not get classified during persistence. bait_sessions = db_session.query(BaitSession).options(joinedload(BaitSession.authentication)) \ .filter(BaitSession.classification_id == 'pending') \ .filter(BaitSession.did_complete == True) \ .filter(BaitSession.received < min_datetime).all() for bait_session in bait_sessions: logger.debug('Classifying bait session with id {0} as MITM'.format(bait_session.id)) bait_session.classification = db_session.query(Classification).filter(Classification.type == 'mitm').one() db_session.commit() # find and process honeypot sessions that did not get classified during persistence. sessions = db_session.query(Session, Drone.name).filter(Session.discriminator == None) \ .filter(Session.timestamp <= min_datetime) \ .filter(Session.classification_id == 'pending') \ .all() for entry in sessions: # Check if the attack used credentials leaked by beeswarm drones session = entry[0] bait_match = None for a in session.authentication: bait_match = db_session.query(BaitSession) \ .filter(BaitSession.authentication.any(username=a.username, password=a.password)).first() if bait_match: break if bait_match: logger.debug('Classifying session with id {0} as attack which involved the reuse ' 'of previously transmitted credentials.'.format(session.id)) session.classification = db_session.query(Classification).filter( Classification.type == 'credentials_reuse').one() elif len(session.authentication) == 0: logger.debug('Classifying session with id {0} as probe.'.format(session.id)) session.classification = db_session.query(Classification).filter(Classification.type == 'probe').one() else: # we have never transmitted this username/password combo logger.debug('Classifying session with id {0} as bruteforce attempt.'.format(session.id)) session.classification = db_session.query(Classification).filter( Classification.type == 'bruteforce').one() db_session.commit() session.name = entry[1] self.processedSessionsPublisher.send( '{0} {1}'.format(Messages.SESSION.value, json.dumps(session.to_dict())))
def _handle_command_delete_drone(self, data): drone_id = data logger.debug('Deleting drone: {0}'.format(drone_id)) db_session = database_setup.get_session() drone_to_delete = db_session.query(Drone).filter(Drone.id == drone_id).first() if drone_to_delete: db_session.delete(drone_to_delete) db_session.commit() # tell the drone to kill itself self.drone_command_receiver.send('{0} {1} '.format(drone_id, Messages.DRONE_DELETE)) self._remove_zmq_keys(drone_id) self._reconfigure_all_clients()