Пример #1
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()
Пример #2
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()
Пример #3
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)
Пример #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

        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
Пример #5
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()
Пример #6
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)