示例#1
0
    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)
示例#2
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()
示例#3
0
    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()
示例#4
0
    def __init__(self, work_dir, config, **kwargs):
        """
            Main class for the Web-Interface. It takes care of setting up
            the database, managing the users, etc.

        :param work_dir: The working directory (usually the current working directory).
        :param config_arg: Beeswarm configuration dictionary, None if not configuration was supplied.
        """
        customize = kwargs['customize']
        reset_password = kwargs['reset_password']
        if 'clear_db' in kwargs:
            clear_sessions = kwargs['clear_db']
        else:
            clear_sessions = True

        self.work_dir = work_dir
        self.config_file = 'beeswarmcfg.json'
        if config is None:
            Server.prepare_environment(work_dir, customize)
            with open(os.path.join(work_dir, self.config_file),
                      'r') as config_file:
                self.config = json.load(config_file, object_hook=asciify)
        else:
            self.config = config
        # list of all self-running (actor) objects that receive or send
        # messages on one or more zmq queues
        self.actors = []

        gevent.spawn(self.message_proxy, work_dir)
        config_actor = ConfigActor(self.config_file, work_dir)
        config_actor.start()
        self.actors.append(config_actor)

        database_setup.setup_db(
            os.path.join(self.config['sql']['connection_string']))
        persistanceActor = SessionPersister(clear_sessions)
        persistanceActor.start()
        self.actors.append(persistanceActor)
        gevent.sleep()

        self.workers = {}
        self.greenlets = []
        self.started = False

        from beeswarm.server.webapp import app
        self.app = app.app
        self.app.config['CERT_PATH'] = self.config['ssl']['certpath']
        self.authenticator = Authenticator()
        self.authenticator.ensure_default_user(reset_password)
示例#5
0
    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()
示例#6
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()
示例#7
0
    def __init__(self, work_dir, config, **kwargs):
        """
            Main class for the Web-Interface. It takes care of setting up
            the database, managing the users, etc.

        :param work_dir: The working directory (usually the current working directory).
        :param config_arg: Beeswarm configuration dictionary, None if not configuration was supplied.
        """
        customize = kwargs['customize']
        reset_password = kwargs['reset_password']
        if 'clear_db' in kwargs:
            clear_sessions = kwargs['clear_db']
        else:
            clear_sessions = True

        self.work_dir = work_dir
        self.config_file = 'beeswarmcfg.json'
        if config is None:
            Server.prepare_environment(work_dir, customize)
            with open(os.path.join(work_dir, self.config_file), 'r') as config_file:
                self.config = json.load(config_file, object_hook=asciify)
        else:
            self.config = config
        # list of all self-running (actor) objects that receive or send
        # messages on one or more zmq queues
        self.actors = []

        gevent.spawn(self.message_proxy, work_dir)
        config_actor = ConfigActor(self.config_file, work_dir)
        config_actor.start()
        self.actors.append(config_actor)

        database_setup.setup_db(os.path.join(self.config['sql']['connection_string']))
        persistanceActor = SessionPersister(clear_sessions)
        persistanceActor.start()
        self.actors.append(persistanceActor)
        gevent.sleep()

        self.workers = {}
        self.greenlets = []
        self.started = False

        from beeswarm.server.webapp import app
        self.app = app.app
        self.app.config['CERT_PATH'] = self.config['ssl']['certpath']
        self.authenticator = Authenticator()
        self.authenticator.ensure_default_user(reset_password)
示例#8
0
class WebappTests(unittest.TestCase):
    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 tearDown(self):
        database.clear_db()
        self.config_actor.close()
        shutil.rmtree(self.work_dir)

    # TODO: All these posts should be moved to ZMQ tests
    # def test_basic_client_post(self):
    # """
    # Tests if a bait_session dict can be posted without exceptions.
    # """
    #     self.login(self.client_id, self.client_password)
    #     data_dict = {
    #         'id': str(uuid.uuid4()),
    #         'client_id': self.client_id,
    #         'honeypot_id': self.honeypot_id,
    #         'protocol': 'pop3',
    #         'destination_ip': '127.0.0.1',
    #         'destination_port': '110',
    #         'source_ip': '123.123.123.123',
    #         'source_port': 12345,
    #         'timestamp': datetime.utcnow().isoformat(),
    #         'did_connect': True,
    #         'did_login': True,
    #         'did_complete': True,
    #         'protocol_data': None,
    #         'login_attempts': [{'id': str(uuid.uuid4()), 'username': '******', 'password': '******', 'successful': True,
    #                             'timestamp': datetime.utcnow().isoformat()}]
    #     }
    #     r = self.app.post('/ws/client_data', data=json.dumps(data_dict), content_type='application/json')
    #     self.assertEquals(r.status, '200 OK')
    #
    # def test_basic_unsuccessful_client_post(self):
    #     """
    #     Tests if an error is returned when data is posted without ID values.
    #     """
    #
    #     self.login(self.client_id, self.client_password)
    #
    #     #missing id's
    #     data_dict = {
    #         'protocol': 'pop3',
    #         'username': '******',
    #         'password': '******',
    #         'server_host': '127.0.0.1',
    #         'server_port': '110',
    #         'source_ip': '123.123.123.123',
    #         'source_port': 12345,
    #         'timestamp': datetime.utcnow().isoformat(),
    #         'did_connect': True,
    #         'did_login': True,
    #         'did_complete': True,
    #         'protocol_data': None
    #     }
    #
    #     r = self.app.post('/ws/client_data', data=json.dumps(data_dict), content_type='application/json')
    #     self.assertEquals(r.status, '500 INTERNAL SERVER ERROR')
    #
    # def test_basic_honeypot_post(self):
    #     """
    #     Tests if a session dict can be posted without exceptions.
    #     """
    #
    #     self.login(self.honeypot_id, self.honeypot_password)
    #
    #     data_dict = {
    #         'id': 'ba9fdb3d-0efb-4764-9a6b-d9b86eccda96',
    #         'honeypot_id': self.honeypot_id,
    #         'destination_ip': '192.168.1.1',
    #         'destination_port': 8023,
    #         'protocol': 'telnet',
    #         'source_ip': '127.0.0.1',
    #         'timestamp': '2013-05-07T22:21:19.453828',
    #         'source_port': 61175,
    #         'login_attempts': [
    #             {'username': '******', 'timestamp': '2013-05-07T22:21:20.846805', 'password': '******',
    #              'id': '027bd968-f8ea-4a69-8d4c-6cf21476ca10', 'successful': False},
    #             {'username': '******', 'timestamp': '2013-05-07T22:21:21.150571', 'password': '******',
    #              'id': '603f40a4-e7eb-442d-9fde-0cd3ba707af7', 'successful': False}, ],
    #         'transcript': [
    #             {'timestamp': '2013-05-07T22:21:20.846805', 'direction': 'in', 'data': 'whoami\r\n'},
    #             {'timestamp': '2013-05-07T22:21:21.136800', 'direction': 'out', 'data': 'james_brown\r\n$:~'}]
    #     }
    #
    #     r = self.app.post('/ws/honeypot_data', data=json.dumps(data_dict), content_type='application/json')
    #     self.assertEquals(r.status, '200 OK')
    #
    # def test_basic_unsuccessful_honeypot_post(self):
    #     """
    #     Tests if an error is returned when data is posted without ID values.
    #     """
    #
    #     self.login(self.honeypot_id, self.honeypot_password)
    #
    #     #missing id
    #     data_dict = {
    #         'honeypot_id': self.honeypot_id,
    #         'destination_ip': '192.168.1.1',
    #         'destination_port': 8023,
    #         'protocol': 'telnet',
    #         'source_ip': '127.0.0.1',
    #         'timestamp': '2013-05-07T22:21:19.453828',
    #         'source_port': 61175,
    #         'login_attempts': [
    #             {'username': '******', 'timestamp': '2013-05-07T22:21:20.846805', 'password': '******',
    #              'id': '027bd968-f8ea-4a69-8d4c-6cf21476ca10', 'successful': False},
    #             {'username': '******', 'timestamp': '2013-05-07T22:21:21.150571', 'password': '******',
    #              'id': '603f40a4-e7eb-442d-9fde-0cd3ba707af7', 'successful': False}, ],
    #         'transcript': [
    #             {'timestamp': '2013-05-07T22:21:20.846805', 'direction': 'in', 'data': 'whoami\r\n'},
    #             {'timestamp': '2013-05-07T22:21:21.136800', 'direction': 'out', 'data': 'james_brown\r\n$:~'}
    #         ]
    #     }
    #     r = self.app.post('/ws/honeypot_data', data=json.dumps(data_dict), content_type='application/json')
    #     self.assertEquals(r.status, '500 INTERNAL SERVER ERROR')
    #
    # def test_new_client(self):
    #     """
    #     Tests if a new Client configuration can be posted successfully
    #     """
    #
    #     post_data = {
    #         'http_enabled': True,
    #         'http_server': '127.0.0.1',
    #         'http_port': 80,
    #         'http_active_range': '13:40 - 16:30',
    #         'http_sleep_interval': 0,
    #         'http_activation_probability': 1,
    #         'http_login': '******',
    #         'http_password': '******',
    #
    #         'https_enabled': True,
    #         'https_server': '127.0.0.1',
    #         'https_port': 80,
    #         'https_active_range': '13:40 - 16:30',
    #         'https_sleep_interval': 0,
    #         'https_activation_probability': 1,
    #         'https_login': '******',
    #         'https_password': '******',
    #
    #         'pop3s_enabled': True,
    #         'pop3s_server': '127.0.0.1',
    #         'pop3s_port': 80,
    #         'pop3s_active_range': '13:40 - 16:30',
    #         'pop3s_sleep_interval': 0,
    #         'pop3s_activation_probability': 1,
    #         'pop3s_login': '******',
    #         'pop3s_password': '******',
    #
    #         'ssh_enabled': True,
    #         'ssh_server': '127.0.0.1',
    #         'ssh_port': 80,
    #         'ssh_active_range': '13:40 - 16:30',
    #         'ssh_sleep_interval': 0,
    #         'ssh_activation_probability': 1,
    #         'ssh_login': '******',
    #         'ssh_password': '******',
    #
    #         'ftp_enabled': True,
    #         'ftp_server': '127.0.0.1',
    #         'ftp_port': 80,
    #         'ftp_active_range': '13:40 - 16:30',
    #         'ftp_sleep_interval': 0,
    #         'ftp_activation_probability': 1,
    #         'ftp_login': '******',
    #         'ftp_password': '******',
    #
    #         'pop3_enabled': True,
    #         'pop3_server': '127.0.0.1',
    #         'pop3_port': 110,
    #         'pop3_active_range': '13:40 - 16:30',
    #         'pop3_sleep_interval': 0,
    #         'pop3_activation_probability': 1,
    #         'pop3_login': '******',
    #         'pop3_password': '******',
    #
    #         'smtp_enabled': True,
    #         'smtp_server': '127.0.0.1',
    #         'smtp_port': 25,
    #         'smtp_active_range': '13:40 - 16:30',
    #         'smtp_sleep_interval': 0,
    #         'smtp_activation_probability': 1,
    #         'smtp_login': '******',
    #         'smtp_password': '******',
    #
    #         'vnc_enabled': True,
    #         'vnc_server': '127.0.0.1',
    #         'vnc_port': 5900,
    #         'vnc_active_range': '13:40 - 16:30',
    #         'vnc_sleep_interval': 0,
    #         'vnc_activation_probability': 1,
    #         'vnc_login': '******',
    #         'vnc_password': '******',
    #
    #         'telnet_enabled': True,
    #         'telnet_server': '127.0.0.1',
    #         'telnet_port': 23,
    #         'telnet_active_range': '13:40 - 16:30',
    #         'telnet_sleep_interval': 0,
    #         'telnet_activation_probability': 1,
    #         'telnet_login': '******',
    #         'telnet_password': '******',
    #     }
    #     self.login('test', 'test')
    #     resp = self.app.post('/ws/client', data=post_data)
    #     self.assertTrue(200, resp.status_code)
    #     self.logout()
    #
    # def test_new_honeypot(self):
    #     """
    #     Tests whether new Honeypot configuration can be posted successfully.
    #     """
    #     post_data = {
    #         'http_enabled': True,
    #         'http_port': 80,
    #         'http_banner': 'Microsoft-IIS/5.0',
    #
    #         'https_enabled': False,
    #         'https_port': 443,
    #         'https_banner': 'Microsoft-IIS/5.0',
    #
    #         'ftp_enabled': False,
    #         'ftp_port': 21,
    #         'ftp_max_attempts': 3,
    #         'ftp_banner': 'Microsoft FTP Server',
    #
    #         'smtp_enabled': False,
    #         'smtp_port': 25,
    #         'smtp_banner': 'Microsoft ESMTP MAIL service ready',
    #
    #         'vnc_enabled': False,
    #         'vnc_port': 5900,
    #
    #         'telnet_enabled': False,
    #         'telnet_port': 23,
    #         'telnet_max_attempts': 3,
    #
    #         'pop3_enabled': False,
    #         'pop3_port': 110,
    #         'pop3_max_attempts': 3,
    #
    #         'pop3s_enabled': False,
    #         'pop3s_port': 110,
    #         'pop3s_max_attempts': 3,
    #
    #         'ssh_enabled': False,
    #         'ssh_port': 22,
    #         'ssh_key': 'server.key'
    #     }
    #     self.login('test', 'test')
    #     resp = self.app.post('/ws/honeypot', data=post_data)
    #     self.assertTrue(200, resp.status_code)
    #     self.logout()
    #
    # def test_new_honeypot_config(self):
    #     """ Tests if a Honeypot config is being returned correctly """
    #
    #     resp = self.app.get('/ws/honeypot/config/' + self.honeypot_id)
    #     self.assertEquals(resp.data, 'test_honeypot_config')
    #
    # def test_new_client_config(self):
    #     """ Tests if a Client config is being returned correctly """
    #
    #     resp = self.app.get('/ws/client/config/' + self.client_id)
    #     self.assertEquals(resp.data, 'test_client_config')

    def test_data_sessions_all(self):
        """ Tests if all sessions are returned properly"""

        self.login("test", "test")
        self.populate_sessions()
        resp = self.app.get("/data/sessions/all")
        table_data = json.loads(resp.data)
        self.assertEquals(len(table_data), 4)
        self.logout()

    def test_data_sessions_honeybees(self):
        """ Tests if bait_sessions are returned properly """

        self.login("test", "test")
        self.populate_honeybees()
        resp = self.app.get("/data/sessions/bait_sessions")
        table_data = json.loads(resp.data)
        self.assertEquals(len(table_data), 3)
        self.logout()

    def test_data_sessions_attacks(self):
        """ Tests if attacks are returned properly """

        self.login("test", "test")
        self.populate_sessions()
        resp = self.app.get("/data/sessions/attacks")
        table_data = json.loads(resp.data)
        self.assertEquals(len(table_data), 4)
        self.logout()

    def test_data_honeypot(self):
        """ Tests if Honeypot information is returned properly """

        self.login("test", "test")
        self.populate_honeypots()
        resp = self.app.get("/data/honeypots")
        table_data = json.loads(resp.data)
        self.assertEquals(len(table_data), 5)  # One is added in the setup method, and 4 in populate

    def test_data_client(self):
        """ Tests if Client information is returned properly """

        self.login("test", "test")
        self.populate_clients()
        resp = self.app.get("/data/clients")
        table_data = json.loads(resp.data)
        self.assertEquals(len(table_data), 5)  # One is added in the setup method, and 4 in populate

    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", "test")
        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 test_login_logout(self):
        """ Tests basic login/logout """

        self.login("test", "test")
        self.logout()

    # def test_honeypot_delete(self):
    #     """ Tests the '/ws/honeypot/delete' route."""
    #
    #     self.login('test', 'test')
    #     self.populate_honeypots()
    #     data = [self.honeypots[0], self.honeypots[1]]
    #     self.app.post('/ws/drone/delete', data=json.dumps(data))
    #     db_session = database.get_session()
    #     honeypot_count = db_session.query(Honeypot).count()
    #     self.assertEquals(3, honeypot_count)
    #     gevent.sleep()
    #
    # def test_client_delete(self):
    #     """ Tests the '/ws/client/delete' route."""
    #
    #     self.login('test', 'test')
    #     self.populate_clients()
    #     data = [self.clients[0], self.clients[1]]
    #     print data
    #     self.app.post('/ws/drone/delete', data=json.dumps(data))
    #     gevent.sleep(1)
    #     db_session = database.get_session()
    #     nclients = db_session.query(Client).count()
    #     self.assertEquals(3, nclients)

    def test_get_baitusers(self):
        """ Tests GET on the '/ws/bait_users' route."""
        self.login("test", "test")
        self.populate_bait_users()
        resp = self.app.get("/ws/bait_users")
        table_data = json.loads(resp.data)
        self.assertEquals(len(table_data), 2)
        self.logout()

    def test_post_baitusers(self):
        """ Tests POST on the '/ws/bait_users' route."""
        self.login("test", "test")

        data = [
            {"username": "******", "password": "******"},
            {"username": "******", "password": "******"},
            {"username": "******", "password": "******"},
        ]

        self.app.post("/ws/bait_users", data=json.dumps(data), follow_redirects=True)
        db_session = database.get_session()
        bait_user_count = db_session.query(BaitUser).count()
        self.assertEquals(bait_user_count, 3)
        self.logout()

    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
            curr_id = str(uuid.uuid4())
            curr_id = curr_id.encode("utf-8")
            self.clients.append(curr_id)
            f = Client(id=curr_id)
            db_session.add(f)
        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 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 login(self, username, password):
        """ Logs into the web-app """

        data = {"username": username, "password": password}
        return self.app.post("/login", data=data, follow_redirects=True)

    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 populate_sessions(self):
        """ Populates the database with 3 Sessions """

        db_session = database.get_session()
        for i in xrange(4):
            s = Session(
                id=str(uuid.uuid4()),
                timestamp=datetime.utcnow(),
                received=datetime.utcnow(),
                protocol="telnet",
                destination_ip="123.123.123.123",
                destination_port=1234,
                source_ip="12.12.12.12",
                source_port=12345,
                classification_id="asd",
            )
            a = Authentication(
                id=str(uuid.uuid4()), username="******", password="******", successful=False, timestamp=datetime.utcnow()
            )
            s.authentication.append(a)
            db_session.add(s)

        db_session.commit()

    def logout(self):
        return self.app.get("/logout", follow_redirects=True)
示例#9
0
class WebAppTests(unittest.TestCase):
    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()
        self.db_file = tempfile.mkstemp()[1]
        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 tearDown(self):
        self.database_actor.stop()
        self.config_actor.stop()
        shutil.rmtree(self.work_dir)
        if os.path.isfile(self.db_file):
            os.remove(self.db_file)

    # TODO: All these posts should be moved to ZMQ tests
    # def test_basic_client_post(self):
    # """
    # Tests if a bait_session dict can be posted without exceptions.
    # """
    # self.login(self.client_id, self.client_password)
    #     data_dict = {
    #         'id': str(uuid.uuid4()),
    #         'client_id': self.client_id,
    #         'honeypot_id': self.honeypot_id,
    #         'protocol': 'pop3',
    #         'destination_ip': '127.0.0.1',
    #         'destination_port': '110',
    #         'source_ip': '123.123.123.123',
    #         'source_port': 12345,
    #         'timestamp': datetime.utcnow().isoformat(),
    #         'did_connect': True,
    #         'did_login': True,
    #         'did_complete': True,
    #         'protocol_data': None,
    #         'login_attempts': [{'id': str(uuid.uuid4()), 'username': '******', 'password': '******', 'successful': True,
    #                             'timestamp': datetime.utcnow().isoformat()}]
    #     }
    #     r = self.app.post('/ws/client_data', data=json.dumps(data_dict), content_type='application/json')
    #     self.assertEquals(r.status, '200 OK')
    #
    # def test_basic_unsuccessful_client_post(self):
    #     """
    #     Tests if an error is returned when data is posted without ID values.
    #     """
    #
    #     self.login(self.client_id, self.client_password)
    #
    #     #missing id's
    #     data_dict = {
    #         'protocol': 'pop3',
    #         'username': '******',
    #         'password': '******',
    #         'server_host': '127.0.0.1',
    #         'server_port': '110',
    #         'source_ip': '123.123.123.123',
    #         'source_port': 12345,
    #         'timestamp': datetime.utcnow().isoformat(),
    #         'did_connect': True,
    #         'did_login': True,
    #         'did_complete': True,
    #         'protocol_data': None
    #     }
    #
    #     r = self.app.post('/ws/client_data', data=json.dumps(data_dict), content_type='application/json')
    #     self.assertEquals(r.status, '500 INTERNAL SERVER ERROR')
    #
    # def test_basic_honeypot_post(self):
    #     """
    #     Tests if a session dict can be posted without exceptions.
    #     """
    #
    #     self.login(self.honeypot_id, self.honeypot_password)
    #
    #     data_dict = {
    #         'id': 'ba9fdb3d-0efb-4764-9a6b-d9b86eccda96',
    #         'honeypot_id': self.honeypot_id,
    #         'destination_ip': '192.168.1.1',
    #         'destination_port': 8023,
    #         'protocol': 'telnet',
    #         'source_ip': '127.0.0.1',
    #         'timestamp': '2013-05-07T22:21:19.453828',
    #         'source_port': 61175,
    #         'login_attempts': [
    #             {'username': '******', 'timestamp': '2013-05-07T22:21:20.846805', 'password': '******',
    #              'id': '027bd968-f8ea-4a69-8d4c-6cf21476ca10', 'successful': False},
    #             {'username': '******', 'timestamp': '2013-05-07T22:21:21.150571', 'password': '******',
    #              'id': '603f40a4-e7eb-442d-9fde-0cd3ba707af7', 'successful': False}, ],
    #         'transcript': [
    #             {'timestamp': '2013-05-07T22:21:20.846805', 'direction': 'in', 'data': 'whoami\r\n'},
    #             {'timestamp': '2013-05-07T22:21:21.136800', 'direction': 'out', 'data': 'james_brown\r\n$:~'}]
    #     }
    #
    #     r = self.app.post('/ws/honeypot_data', data=json.dumps(data_dict), content_type='application/json')
    #     self.assertEquals(r.status, '200 OK')
    #
    # def test_basic_unsuccessful_honeypot_post(self):
    #     """
    #     Tests if an error is returned when data is posted without ID values.
    #     """
    #
    #     self.login(self.honeypot_id, self.honeypot_password)
    #
    #     #missing id
    #     data_dict = {
    #         'honeypot_id': self.honeypot_id,
    #         'destination_ip': '192.168.1.1',
    #         'destination_port': 8023,
    #         'protocol': 'telnet',
    #         'source_ip': '127.0.0.1',
    #         'timestamp': '2013-05-07T22:21:19.453828',
    #         'source_port': 61175,
    #         'login_attempts': [
    #             {'username': '******', 'timestamp': '2013-05-07T22:21:20.846805', 'password': '******',
    #              'id': '027bd968-f8ea-4a69-8d4c-6cf21476ca10', 'successful': False},
    #             {'username': '******', 'timestamp': '2013-05-07T22:21:21.150571', 'password': '******',
    #              'id': '603f40a4-e7eb-442d-9fde-0cd3ba707af7', 'successful': False}, ],
    #         'transcript': [
    #             {'timestamp': '2013-05-07T22:21:20.846805', 'direction': 'in', 'data': 'whoami\r\n'},
    #             {'timestamp': '2013-05-07T22:21:21.136800', 'direction': 'out', 'data': 'james_brown\r\n$:~'}
    #         ]
    #     }
    #     r = self.app.post('/ws/honeypot_data', data=json.dumps(data_dict), content_type='application/json')
    #     self.assertEquals(r.status, '500 INTERNAL SERVER ERROR')
    #
    # def test_new_client(self):
    #     """
    #     Tests if a new Client configuration can be posted successfully
    #     """
    #
    #     post_data = {
    #         'http_enabled': True,
    #         'http_server': '127.0.0.1',
    #         'http_port': 80,
    #         'http_active_range': '13:40 - 16:30',
    #         'http_sleep_interval': 0,
    #         'http_activation_probability': 1,
    #         'http_login': '******',
    #         'http_password': '******',
    #
    #         'https_enabled': True,
    #         'https_server': '127.0.0.1',
    #         'https_port': 80,
    #         'https_active_range': '13:40 - 16:30',
    #         'https_sleep_interval': 0,
    #         'https_activation_probability': 1,
    #         'https_login': '******',
    #         'https_password': '******',
    #
    #         'pop3s_enabled': True,
    #         'pop3s_server': '127.0.0.1',
    #         'pop3s_port': 80,
    #         'pop3s_active_range': '13:40 - 16:30',
    #         'pop3s_sleep_interval': 0,
    #         'pop3s_activation_probability': 1,
    #         'pop3s_login': '******',
    #         'pop3s_password': '******',
    #
    #         'ssh_enabled': True,
    #         'ssh_server': '127.0.0.1',
    #         'ssh_port': 80,
    #         'ssh_active_range': '13:40 - 16:30',
    #         'ssh_sleep_interval': 0,
    #         'ssh_activation_probability': 1,
    #         'ssh_login': '******',
    #         'ssh_password': '******',
    #
    #         'ftp_enabled': True,
    #         'ftp_server': '127.0.0.1',
    #         'ftp_port': 80,
    #         'ftp_active_range': '13:40 - 16:30',
    #         'ftp_sleep_interval': 0,
    #         'ftp_activation_probability': 1,
    #         'ftp_login': '******',
    #         'ftp_password': '******',
    #
    #         'pop3_enabled': True,
    #         'pop3_server': '127.0.0.1',
    #         'pop3_port': 110,
    #         'pop3_active_range': '13:40 - 16:30',
    #         'pop3_sleep_interval': 0,
    #         'pop3_activation_probability': 1,
    #         'pop3_login': '******',
    #         'pop3_password': '******',
    #
    #         'smtp_enabled': True,
    #         'smtp_server': '127.0.0.1',
    #         'smtp_port': 25,
    #         'smtp_active_range': '13:40 - 16:30',
    #         'smtp_sleep_interval': 0,
    #         'smtp_activation_probability': 1,
    #         'smtp_login': '******',
    #         'smtp_password': '******',
    #
    #         'vnc_enabled': True,
    #         'vnc_server': '127.0.0.1',
    #         'vnc_port': 5900,
    #         'vnc_active_range': '13:40 - 16:30',
    #         'vnc_sleep_interval': 0,
    #         'vnc_activation_probability': 1,
    #         'vnc_login': '******',
    #         'vnc_password': '******',
    #
    #         'telnet_enabled': True,
    #         'telnet_server': '127.0.0.1',
    #         'telnet_port': 23,
    #         'telnet_active_range': '13:40 - 16:30',
    #         'telnet_sleep_interval': 0,
    #         'telnet_activation_probability': 1,
    #         'telnet_login': '******',
    #         'telnet_password': '******',
    #     }
    #     self.login('test', 'test')
    #     resp = self.app.post('/ws/client', data=post_data)
    #     self.assertTrue(200, resp.status_code)
    #     self.logout()
    #
    # def test_new_honeypot(self):
    #     """
    #     Tests whether new Honeypot configuration can be posted successfully.
    #     """
    #     post_data = {
    #         'http_enabled': True,
    #         'http_port': 80,
    #         'http_banner': 'Microsoft-IIS/5.0',
    #
    #         'https_enabled': False,
    #         'https_port': 443,
    #         'https_banner': 'Microsoft-IIS/5.0',
    #
    #         'ftp_enabled': False,
    #         'ftp_port': 21,
    #         'ftp_max_attempts': 3,
    #         'ftp_banner': 'Microsoft FTP Server',
    #
    #         'smtp_enabled': False,
    #         'smtp_port': 25,
    #         'smtp_banner': 'Microsoft ESMTP MAIL service ready',
    #
    #         'vnc_enabled': False,
    #         'vnc_port': 5900,
    #
    #         'telnet_enabled': False,
    #         'telnet_port': 23,
    #         'telnet_max_attempts': 3,
    #
    #         'pop3_enabled': False,
    #         'pop3_port': 110,
    #         'pop3_max_attempts': 3,
    #
    #         'pop3s_enabled': False,
    #         'pop3s_port': 110,
    #         'pop3s_max_attempts': 3,
    #
    #         'ssh_enabled': False,
    #         'ssh_port': 22,
    #         'ssh_key': 'server.key'
    #     }
    #     self.login('test', 'test')
    #     resp = self.app.post('/ws/honeypot', data=post_data)
    #     self.assertTrue(200, resp.status_code)
    #     self.logout()
    #
    # def test_new_honeypot_config(self):
    #     """ Tests if a Honeypot config is being returned correctly """
    #
    #     resp = self.app.get('/ws/honeypot/config/' + self.honeypot_id)
    #     self.assertEquals(resp.data, 'test_honeypot_config')
    #
    # def test_new_client_config(self):
    #     """ Tests if a Client config is being returned correctly """
    #
    #     resp = self.app.get('/ws/client/config/' + self.client_id)
    #     self.assertEquals(resp.data, 'test_client_config')

    def test_data_sessions_all(self):
        """ Tests if all sessions are returned properly"""

        self.login('test', self.password)
        self.populate_sessions()
        resp = self.app.get('/data/sessions/all')
        table_data = json.loads(resp.data)
        self.assertEquals(len(table_data), 4)
        self.logout()

    def test_data_sessions_honeybees(self):
        """ Tests if bait_sessions are returned properly """

        self.login('test', self.password)
        self.populate_honeybees()
        resp = self.app.get('/data/sessions/bait_sessions')
        table_data = json.loads(resp.data)
        self.assertEquals(len(table_data), 3)
        self.logout()

    def test_data_sessions_attacks(self):
        """ Tests if attacks are returned properly """

        self.login('test', self.password)
        self.populate_sessions()
        resp = self.app.get('/data/sessions/attacks')
        table_data = json.loads(resp.data)
        self.assertEquals(len(table_data), 4)
        self.logout()

    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 test_login_logout(self):
        """ Tests basic login/logout """

        self.login('admin', self.password)
        self.logout()

    def test_get_baitusers(self):
        """ Tests GET on the '/ws/bait_users' route."""
        self.login('admin', self.password)
        self.populate_bait_users()
        resp = self.app.get('/ws/bait_users')
        table_data = json.loads(resp.data)
        self.assertEquals(len(table_data), 2)
        self.logout()

    def test_add_baituser(self):
        """ Tests POST on the '/ws/bait_users/add' route."""
        self.login('admin', self.password)
        data = [
            {'username': '******', 'password': '******'},
            {'username': '******', 'password': '******'},
            {'username': '******', 'password': '******'}
        ]

        self.app.post('/ws/bait_users/add', data=json.dumps(data), follow_redirects=True)

        resp = self.app.get('/ws/bait_users')
        bait_users = json.loads(resp.data)
        # 22 in bootstrapping, 3 just added
        self.assertEquals(len(bait_users), 22 + 3)
        self.logout()

    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 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_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 login(self, username, password):
        """ Logs into the web-app """

        data = {
            'username': username,
            'password': password
        }
        return self.app.post('/login', data=data, follow_redirects=True)

    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 populate_sessions(self):
        """ Populates the database with 3 Sessions """

        db_session = database.get_session()
        for i in xrange(4):
            s = Session(
                id=str(uuid.uuid4()),
                timestamp=datetime.utcnow(),
                received=datetime.utcnow(),
                protocol='telnet',
                destination_ip='123.123.123.123',
                destination_port=1234,
                source_ip='12.12.12.12',
                source_port=12345,
                classification_id='asd'
            )
            a = Authentication(id=str(uuid.uuid4()), username='******', password='******',
                               successful=False,
                               timestamp=datetime.utcnow())
            s.authentication.append(a)
            db_session.add(s)

        db_session.commit()

    def logout(self):
        return self.app.get('/logout', follow_redirects=True)
示例#10
0
    def __init__(self, work_dir, config, **kwargs):
        """
            Main class for the Web-Interface. It takes care of setting up
            the database, managing the users, etc.

        :param work_dir: The working directory (usually the current working directory).
        :param config_arg: Beeswarm configuration dictionary, None if not configuration was supplied.
        """
        customize = kwargs['customize']
        reset_password = kwargs['reset_password']
        if 'clear_db' in kwargs:
            clear_sessions = kwargs['clear_db']
        else:
            clear_sessions = True

        if 'server_hostname' in kwargs:
            server_hostname = kwargs['server_hostname']
        else:
            server_hostname = None

        max_sessions = kwargs['max_sessions']
        start_webui = kwargs['start_webui']

        self.work_dir = work_dir
        self.config_file = os.path.join(work_dir, 'beeswarmcfg.json')

        if config is None:
            self.prepare_environment(work_dir,
                                     customize,
                                     server_hostname=server_hostname)
            with open(os.path.join(work_dir, self.config_file),
                      'r') as config_file:
                self.config = json.load(config_file, object_hook=asciify)
        else:
            self.config = config
        # list of all self-running (actor) objects that receive or send
        # messages on one or more zmq queues
        self.actors = []
        self.greenlets = []

        proxy_greenlet = gevent.spawn(self.message_proxy, work_dir)
        self.greenlets.append(proxy_greenlet)
        config_actor = ConfigActor(self.config_file, work_dir)
        config_actor.start()
        self.actors.append(config_actor)
        self.greenlets.append(config_actor)

        # make path in sqlite connection string absolute
        connection_string = self.config['sql']['connection_string']
        if connection_string.startswith('sqlite:///'):
            _, relative_path = os.path.split(connection_string)
            connection_string = 'sqlite:///{0}'.format(
                os.path.join(self.work_dir, relative_path))
        database_setup.setup_db(connection_string)
        database_actor = DatabaseActor(max_sessions, clear_sessions)
        database_actor.start()
        self.actors.append(database_actor)
        self.greenlets.append(database_actor)

        for g in self.greenlets:
            g.link_exception(self.on_exception)

        gevent.sleep()

        self.started = False

        if start_webui:
            from beeswarm.server.webapp import app

            self.app = app.app
            self.app.config['CERT_PATH'] = self.config['ssl']['certpath']
            app.ensure_admin_password(reset_password)
        else:
            self.app = None
示例#11
0
    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()
示例#12
0
    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)
示例#13
0
    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)

            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
            server_hostname = raw_input('IP or hostname of server: ')
            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('beeswarmcfg.json', work_dir, True)
            config_actor.start()
            context = beeswarm.shared.zmq_context
            socket = context.socket(zmq.REQ)
            gevent.sleep()
            socket.connect('inproc://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_CONFIG_ITEM, json.dumps({'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:///beeswarm_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.recv()
            config_actor.close()
示例#14
0
class WebAppTests(unittest.TestCase):
    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 tearDown(self):
        self.database_actor.stop()
        self.database_actor = None
        self.config_actor.stop()
        self.config_actor = None
        shutil.rmtree(self.work_dir)
        if os.path.isfile(self.db_file):
            os.remove(self.db_file)

    # TODO: All these posts should be moved to ZMQ tests
    # def test_basic_client_post(self):
    # """
    # Tests if a bait_session dict can be posted without exceptions.
    # """
    # self.login(self.client_id, self.client_password)
    #     data_dict = {
    #         'id': str(uuid.uuid4()),
    #         'client_id': self.client_id,
    #         'honeypot_id': self.honeypot_id,
    #         'protocol': 'pop3',
    #         'destination_ip': '127.0.0.1',
    #         'destination_port': '110',
    #         'source_ip': '123.123.123.123',
    #         'source_port': 12345,
    #         'timestamp': datetime.utcnow().isoformat(),
    #         'did_connect': True,
    #         'did_login': True,
    #         'did_complete': True,
    #         'protocol_data': None,
    #         'login_attempts': [{'id': str(uuid.uuid4()), 'username': '******', 'password': '******', 'successful': True,
    #                             'timestamp': datetime.utcnow().isoformat()}]
    #     }
    #     r = self.app.post('/ws/client_data', data=json.dumps(data_dict), content_type='application/json')
    #     self.assertEquals(r.status, '200 OK')
    #
    # def test_basic_unsuccessful_client_post(self):
    #     """
    #     Tests if an error is returned when data is posted without ID values.
    #     """
    #
    #     self.login(self.client_id, self.client_password)
    #
    #     #missing id's
    #     data_dict = {
    #         'protocol': 'pop3',
    #         'username': '******',
    #         'password': '******',
    #         'server_host': '127.0.0.1',
    #         'server_port': '110',
    #         'source_ip': '123.123.123.123',
    #         'source_port': 12345,
    #         'timestamp': datetime.utcnow().isoformat(),
    #         'did_connect': True,
    #         'did_login': True,
    #         'did_complete': True,
    #         'protocol_data': None
    #     }
    #
    #     r = self.app.post('/ws/client_data', data=json.dumps(data_dict), content_type='application/json')
    #     self.assertEquals(r.status, '500 INTERNAL SERVER ERROR')
    #
    # def test_basic_honeypot_post(self):
    #     """
    #     Tests if a session dict can be posted without exceptions.
    #     """
    #
    #     self.login(self.honeypot_id, self.honeypot_password)
    #
    #     data_dict = {
    #         'id': 'ba9fdb3d-0efb-4764-9a6b-d9b86eccda96',
    #         'honeypot_id': self.honeypot_id,
    #         'destination_ip': '192.168.1.1',
    #         'destination_port': 8023,
    #         'protocol': 'telnet',
    #         'source_ip': '127.0.0.1',
    #         'timestamp': '2013-05-07T22:21:19.453828',
    #         'source_port': 61175,
    #         'login_attempts': [
    #             {'username': '******', 'timestamp': '2013-05-07T22:21:20.846805', 'password': '******',
    #              'id': '027bd968-f8ea-4a69-8d4c-6cf21476ca10', 'successful': False},
    #             {'username': '******', 'timestamp': '2013-05-07T22:21:21.150571', 'password': '******',
    #              'id': '603f40a4-e7eb-442d-9fde-0cd3ba707af7', 'successful': False}, ],
    #         'transcript': [
    #             {'timestamp': '2013-05-07T22:21:20.846805', 'direction': 'in', 'data': 'whoami\r\n'},
    #             {'timestamp': '2013-05-07T22:21:21.136800', 'direction': 'out', 'data': 'james_brown\r\n$:~'}]
    #     }
    #
    #     r = self.app.post('/ws/honeypot_data', data=json.dumps(data_dict), content_type='application/json')
    #     self.assertEquals(r.status, '200 OK')
    #
    # def test_basic_unsuccessful_honeypot_post(self):
    #     """
    #     Tests if an error is returned when data is posted without ID values.
    #     """
    #
    #     self.login(self.honeypot_id, self.honeypot_password)
    #
    #     #missing id
    #     data_dict = {
    #         'honeypot_id': self.honeypot_id,
    #         'destination_ip': '192.168.1.1',
    #         'destination_port': 8023,
    #         'protocol': 'telnet',
    #         'source_ip': '127.0.0.1',
    #         'timestamp': '2013-05-07T22:21:19.453828',
    #         'source_port': 61175,
    #         'login_attempts': [
    #             {'username': '******', 'timestamp': '2013-05-07T22:21:20.846805', 'password': '******',
    #              'id': '027bd968-f8ea-4a69-8d4c-6cf21476ca10', 'successful': False},
    #             {'username': '******', 'timestamp': '2013-05-07T22:21:21.150571', 'password': '******',
    #              'id': '603f40a4-e7eb-442d-9fde-0cd3ba707af7', 'successful': False}, ],
    #         'transcript': [
    #             {'timestamp': '2013-05-07T22:21:20.846805', 'direction': 'in', 'data': 'whoami\r\n'},
    #             {'timestamp': '2013-05-07T22:21:21.136800', 'direction': 'out', 'data': 'james_brown\r\n$:~'}
    #         ]
    #     }
    #     r = self.app.post('/ws/honeypot_data', data=json.dumps(data_dict), content_type='application/json')
    #     self.assertEquals(r.status, '500 INTERNAL SERVER ERROR')
    #
    # def test_new_client(self):
    #     """
    #     Tests if a new Client configuration can be posted successfully
    #     """
    #
    #     post_data = {
    #         'http_enabled': True,
    #         'http_server': '127.0.0.1',
    #         'http_port': 80,
    #         'http_active_range': '13:40 - 16:30',
    #         'http_sleep_interval': 0,
    #         'http_activation_probability': 1,
    #         'http_login': '******',
    #         'http_password': '******',
    #
    #         'https_enabled': True,
    #         'https_server': '127.0.0.1',
    #         'https_port': 80,
    #         'https_active_range': '13:40 - 16:30',
    #         'https_sleep_interval': 0,
    #         'https_activation_probability': 1,
    #         'https_login': '******',
    #         'https_password': '******',
    #
    #         'pop3s_enabled': True,
    #         'pop3s_server': '127.0.0.1',
    #         'pop3s_port': 80,
    #         'pop3s_active_range': '13:40 - 16:30',
    #         'pop3s_sleep_interval': 0,
    #         'pop3s_activation_probability': 1,
    #         'pop3s_login': '******',
    #         'pop3s_password': '******',
    #
    #         'ssh_enabled': True,
    #         'ssh_server': '127.0.0.1',
    #         'ssh_port': 80,
    #         'ssh_active_range': '13:40 - 16:30',
    #         'ssh_sleep_interval': 0,
    #         'ssh_activation_probability': 1,
    #         'ssh_login': '******',
    #         'ssh_password': '******',
    #
    #         'ftp_enabled': True,
    #         'ftp_server': '127.0.0.1',
    #         'ftp_port': 80,
    #         'ftp_active_range': '13:40 - 16:30',
    #         'ftp_sleep_interval': 0,
    #         'ftp_activation_probability': 1,
    #         'ftp_login': '******',
    #         'ftp_password': '******',
    #
    #         'pop3_enabled': True,
    #         'pop3_server': '127.0.0.1',
    #         'pop3_port': 110,
    #         'pop3_active_range': '13:40 - 16:30',
    #         'pop3_sleep_interval': 0,
    #         'pop3_activation_probability': 1,
    #         'pop3_login': '******',
    #         'pop3_password': '******',
    #
    #         'smtp_enabled': True,
    #         'smtp_server': '127.0.0.1',
    #         'smtp_port': 25,
    #         'smtp_active_range': '13:40 - 16:30',
    #         'smtp_sleep_interval': 0,
    #         'smtp_activation_probability': 1,
    #         'smtp_login': '******',
    #         'smtp_password': '******',
    #
    #         'vnc_enabled': True,
    #         'vnc_server': '127.0.0.1',
    #         'vnc_port': 5900,
    #         'vnc_active_range': '13:40 - 16:30',
    #         'vnc_sleep_interval': 0,
    #         'vnc_activation_probability': 1,
    #         'vnc_login': '******',
    #         'vnc_password': '******',
    #
    #         'telnet_enabled': True,
    #         'telnet_server': '127.0.0.1',
    #         'telnet_port': 23,
    #         'telnet_active_range': '13:40 - 16:30',
    #         'telnet_sleep_interval': 0,
    #         'telnet_activation_probability': 1,
    #         'telnet_login': '******',
    #         'telnet_password': '******',
    #     }
    #     self.login('test', 'test')
    #     resp = self.app.post('/ws/client', data=post_data)
    #     self.assertTrue(200, resp.status_code)
    #     self.logout()
    #
    # def test_new_honeypot(self):
    #     """
    #     Tests whether new Honeypot configuration can be posted successfully.
    #     """
    #     post_data = {
    #         'http_enabled': True,
    #         'http_port': 80,
    #         'http_banner': 'Microsoft-IIS/5.0',
    #
    #         'https_enabled': False,
    #         'https_port': 443,
    #         'https_banner': 'Microsoft-IIS/5.0',
    #
    #         'ftp_enabled': False,
    #         'ftp_port': 21,
    #         'ftp_max_attempts': 3,
    #         'ftp_banner': 'Microsoft FTP Server',
    #
    #         'smtp_enabled': False,
    #         'smtp_port': 25,
    #         'smtp_banner': 'Microsoft ESMTP MAIL service ready',
    #
    #         'vnc_enabled': False,
    #         'vnc_port': 5900,
    #
    #         'telnet_enabled': False,
    #         'telnet_port': 23,
    #         'telnet_max_attempts': 3,
    #
    #         'pop3_enabled': False,
    #         'pop3_port': 110,
    #         'pop3_max_attempts': 3,
    #
    #         'pop3s_enabled': False,
    #         'pop3s_port': 110,
    #         'pop3s_max_attempts': 3,
    #
    #         'ssh_enabled': False,
    #         'ssh_port': 22,
    #         'ssh_key': 'server.key'
    #     }
    #     self.login('test', 'test')
    #     resp = self.app.post('/ws/honeypot', data=post_data)
    #     self.assertTrue(200, resp.status_code)
    #     self.logout()
    #
    # def test_new_honeypot_config(self):
    #     """ Tests if a Honeypot config is being returned correctly """
    #
    #     resp = self.app.get('/ws/honeypot/config/' + self.honeypot_id)
    #     self.assertEquals(resp.data, 'test_honeypot_config')
    #
    # def test_new_client_config(self):
    #     """ Tests if a Client config is being returned correctly """
    #
    #     resp = self.app.get('/ws/client/config/' + self.client_id)
    #     self.assertEquals(resp.data, 'test_client_config')

    def test_data_sessions_all(self):
        """ Tests if all sessions are returned properly"""

        self.login('test', self.password)
        self.populate_sessions()
        resp = self.app.get('/data/sessions/all')
        table_data = json.loads(resp.data)
        self.assertEquals(len(table_data), 4)
        self.logout()

    def test_data_sessions_honeybees(self):
        """ Tests if bait_sessions are returned properly """

        self.login('test', self.password)
        self.populate_honeybees()
        resp = self.app.get('/data/sessions/bait_sessions')
        table_data = json.loads(resp.data)
        self.assertEquals(len(table_data), 3)
        self.logout()

    def test_data_sessions_attacks(self):
        """ Tests if attacks are returned properly """

        self.login('test', self.password)
        self.populate_sessions()
        resp = self.app.get('/data/sessions/attacks')
        table_data = json.loads(resp.data)
        self.assertEquals(len(table_data), 4)
        self.logout()

    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 test_login_logout(self):
        """ Tests basic login/logout """

        self.login('admin', self.password)
        self.logout()

    def test_get_baitusers(self):
        """ Tests GET on the '/ws/bait_users' route."""
        self.login('admin', self.password)
        self.populate_bait_users()
        resp = self.app.get('/ws/bait_users')
        table_data = json.loads(resp.data)
        self.assertEquals(len(table_data), 2)
        self.logout()

    def test_add_baituser(self):
        """ Tests POST on the '/ws/bait_users/add' route."""
        self.login('admin', self.password)
        data = [{
            'username': '******',
            'password': '******'
        }, {
            'username': '******',
            'password': '******'
        }, {
            'username': '******',
            'password': '******'
        }]

        self.app.post('/ws/bait_users/add',
                      data=json.dumps(data),
                      follow_redirects=True)

        resp = self.app.get('/ws/bait_users')
        bait_users = json.loads(resp.data)
        # 22 in bootstrapping, 3 just added
        self.assertEquals(len(bait_users), 22 + 3)
        self.logout()

    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 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_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 login(self, username, password):
        """ Logs into the web-app """

        data = {'username': username, 'password': password}
        return self.app.post('/login', data=data, follow_redirects=True)

    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 populate_sessions(self):
        """ Populates the database with 3 Sessions """
        db_session = database.get_session()
        for i in xrange(4):
            s = Session(id=str(uuid.uuid4()),
                        timestamp=datetime.utcnow(),
                        received=datetime.utcnow(),
                        protocol='telnet',
                        destination_ip='123.123.123.123',
                        destination_port=1234,
                        source_ip='12.12.12.12',
                        source_port=12345,
                        classification_id='asd')
            a = Authentication(id=str(uuid.uuid4()),
                               username='******',
                               password='******',
                               successful=False,
                               timestamp=datetime.utcnow())
            s.authentication.append(a)
            db_session.add(s)

        db_session.commit()

    def logout(self):
        return self.app.get('/logout', follow_redirects=True)
示例#15
0
    def __init__(self, work_dir, config, **kwargs):
        """
            Main class for the Web-Interface. It takes care of setting up
            the database, managing the users, etc.

        :param work_dir: The working directory (usually the current working directory).
        :param config_arg: Beeswarm configuration dictionary, None if not configuration was supplied.
        """
        customize = kwargs['customize']
        reset_password = kwargs['reset_password']
        if 'clear_db' in kwargs:
            clear_sessions = kwargs['clear_db']
        else:
            clear_sessions = True

        if 'server_hostname' in kwargs:
            server_hostname = kwargs['server_hostname']
        else:
            server_hostname = None

        max_sessions = kwargs['max_sessions']
        start_webui = kwargs['start_webui']

        self.work_dir = work_dir
        self.config_file = os.path.join(work_dir, 'beeswarmcfg.json')

        if config is None:
            self.prepare_environment(work_dir, customize, server_hostname=server_hostname)
            with open(os.path.join(work_dir, self.config_file), 'r') as config_file:
                self.config = json.load(config_file, object_hook=asciify)
        else:
            self.config = config
        # list of all self-running (actor) objects that receive or send
        # messages on one or more zmq queues
        self.actors = []
        self.greenlets = []

        proxy_greenlet = gevent.spawn(self.message_proxy, work_dir)
        self.greenlets.append(proxy_greenlet)
        config_actor = ConfigActor(self.config_file, work_dir)
        config_actor.start()
        self.actors.append(config_actor)
        self.greenlets.append(config_actor)

        # make path in sqlite connection string absolute
        connection_string = self.config['sql']['connection_string']
        if connection_string.startswith('sqlite:///'):
            _, relative_path = os.path.split(connection_string)
            connection_string = 'sqlite:///{0}'.format(os.path.join(self.work_dir, relative_path))
        database_setup.setup_db(connection_string)
        database_actor = DatabaseActor(max_sessions, clear_sessions)
        database_actor.start()
        self.actors.append(database_actor)
        self.greenlets.append(database_actor)

        for g in self.greenlets:
            g.link_exception(self.on_exception)

        gevent.sleep()

        self.started = False

        if start_webui:
            from beeswarm.server.webapp import app

            self.app = app.app
            self.app.config['CERT_PATH'] = self.config['ssl']['certpath']
            app.ensure_admin_password(reset_password)
        else:
            self.app = None