Beispiel #1
0
    async def get_watchlist_users(self, watchlists: dict, query: Optional[Query] = Query()) -> Results:
        """

        Args:
            watchlists (dict): {<watchlist_id>: <watchlist_name>}
            query (OptionL[Query]):

        Returns:
            results (Results):

        """
        if not self.logged_in:
            await self.login()

        results = Results(data=[])

        for k, v in watchlists.items():
            logger.debug(f'Getting watchlist {k}: {v}, users from Exabeam...')
            tasks = [asyncio.create_task(self.request(method='get',
                                                      end_point=f'/uba/api/watchlist/{k}/',
                                                      request_id=uuid4().hex,
                                                      params=query.dict()))]
            res = await self.process_results(Results(data=await asyncio.gather(*tasks)), 'users')
            for r in res.success:
                r['watchlist'] = v

            results.data.extend(res.data)
            results.success.extend(res.success)
            results.failure.extend(res.failure)

        logger.debug(f'-> Complete; Retrieved {len(results.data)}, watchlist users.')

        return results
Beispiel #2
0
    async def delete_records(
            self, query: Union[List[ArtifactQuery],
                               List[ContainerQuery]]) -> Results:
        """

        Args:
            query (List[Union[ArtifactQuery, ContainerQuery]]):

        Returns:
            results (Results)"""
        logger.debug(f'Deleting {type(query)}, record(s)...')

        if not type(query) is list:
            query = [query]

        tasks = [
            asyncio.create_task(
                self.request(method='delete',
                             end_point=q.end_point,
                             request_id=uuid4().hex)) for q in query
        ]

        results = Results(data=await asyncio.gather(*tasks))

        logger.debug('-> Complete.')

        return await self.process_results(results)
Beispiel #3
0
    async def login(self) -> Results:
        payload = {
            'username': self.cfg['Auth']['Username'],
            'password': self.cfg['Auth']['Password']
        }

        logger.debug('Logging in to Bricata...')

        tasks = [
            asyncio.create_task(
                self.request(method='post',
                             end_point='/login/',
                             request_id=uuid4().hex,
                             json=payload))
        ]
        results = Results(data=await asyncio.gather(*tasks))

        logger.debug('-> Complete.')

        results = await self.process_results(results)

        self.header = {
            **self.HDR,
            **{
                'Authorization':
                f'{results.success[0]["token_type"]} {results.success[0]["token"]}'
            }
        }
        await self.session.close()

        self.session = aio.ClientSession(headers=self.header,
                                         json_serialize=rapidjson.dumps)
        return results
Beispiel #4
0
    async def update_records(
            self, requests: List[Union[ContainerRequest,
                                       ArtifactRequest]]) -> Results:
        """

        Args:
            requests (Union[
        ContainerRequest, ArtifactRequest, List[Union[ContainerRequest, ArtifactRequest]]]):

        Returns:
            results (Results)"""
        logger.debug(f'Updating record(s)...')

        if not type(requests) is list:
            requests = [requests]

        tasks = [
            asyncio.create_task(
                self.request(method='post',
                             end_point=r.end_point,
                             request_id=uuid4().hex,
                             json=r.dict())) for r in requests
        ]

        results = Results(data=await asyncio.gather(*tasks))

        logger.debug('-> Complete.')

        return await self.process_results(results)
Beispiel #5
0
    async def get_record_count(
            self, query: Union[ArtifactQuery, ContainerQuery,
                               UserQuery]) -> Results:
        """
        Performs a single page query to get the 'results_count' & 'num_paqges' based on specified Query.
        Args:
            query (Optional[ContainerQuery]):

        Returns:
            results (Results)
        """
        logger.debug(f'Getting {type(query)} record count...')

        if not query.page:
            query.page = 0
        if not query.page_size:
            query.page_size = 1

        tasks = [
            asyncio.create_task(
                self.request(method='get',
                             end_point=query.end_point,
                             request_id=uuid4().hex,
                             params=query.dict()))
        ]

        logger.debug('-> Complete.')
        return await self.process_results(
            Results(data=await asyncio.gather(*tasks)))
Beispiel #6
0
    async def get_records(
            self, query: Union[Query, ComputerQuery, UserQuery]) -> Results:
        entries = self.connection.extend.standard.paged_search(
            search_base=query.search_base
            or self.cfg['Defaults']['SearchBase'],
            search_filter=query.search_filter,
            search_scope=query.search_scope,
            attributes=query.attributes,
            paged_size=query.paged_size)

        return Results(data=entries,
                       success=[e['attributes'] for e in entries])
Beispiel #7
0
    async def check_credentials(self, username, password) -> Results:
        """

        Args:
            username (str):
            password (str):

        Returns:
            results (Results)"""
        connection: Connection = Connection(
            self.adserver,
            user=username,
            password=password,
            authentication=self.cfg['Auth']['Type'] or None)
        connection.bind()

        cr = connection.result

        if cr['description'] == 'success':
            return Results(data=connection.result, success=[cr])
        else:
            return Results(data=connection.result, failure=[cr])
Beispiel #8
0
    async def delete_tag(self, tag_name: str) -> Results:
        await self.__check_login()

        logger.debug(f'Deleting tag: {tag_name}, from Bricata...')

        tasks = [
            asyncio.create_task(
                self.request(method='delete',
                             end_point=f'/tags/{tag_name}/',
                             request_id=uuid4().hex))
        ]
        results = Results(data=await asyncio.gather(*tasks))

        logger.debug('-> Complete.')

        return await self.process_results(results)
Beispiel #9
0
    async def untag_alert(self, uuid: str, tag: str):
        await self.__check_login()

        logger.debug(f'Untagging: {tag} from alert: {uuid}, in Bricata...')

        tasks = [
            asyncio.create_task(
                self.request(method='delete',
                             end_point=f'/alerts/{uuid}/tag/{tag}/',
                             request_id=uuid4().hex))
        ]
        results = Results(data=await asyncio.gather(*tasks))

        logger.debug('-> Complete.')

        return await self.process_results(results)
Beispiel #10
0
    async def get_alert(self, uuid: str) -> Results:
        await self.__check_login()

        logger.debug(f'Getting alert: {uuid}, from Bricata...')

        tasks = [
            asyncio.create_task(
                self.request(method='get',
                             end_point=f'/alert/{uuid}',
                             request_id=uuid4().hex))
        ]
        results = Results(data=await asyncio.gather(*tasks))

        logger.debug('-> Complete.')

        return await self.process_results(results)
Beispiel #11
0
    async def put_tag(self, tag: TagRequest) -> Results:
        await self.__check_login()

        logger.debug(f'Creating tag: {tag} in Bricata...')

        tasks = [
            asyncio.create_task(
                self.request(method='put',
                             end_point=f'/tags/{tag.name}/',
                             request_id=uuid4().hex,
                             json=tag.dict))
        ]
        results = Results(data=await asyncio.gather(*tasks))

        logger.debug('-> Complete.')

        return await self.process_results(results)
Beispiel #12
0
    async def get_tags(self) -> Results:
        await self.__check_login()

        logger.debug('Getting tags from Bricata...')

        tasks = [
            asyncio.create_task(
                self.request(
                    method='get',
                    end_point='/tags/',
                    request_id=uuid4().hex,
                ))
        ]
        results = Results(data=await asyncio.gather(*tasks))

        logger.debug('-> Complete.')

        return await self.process_results(results)
Beispiel #13
0
    async def get_alerts(self,
                         filters: Optional[AlertsFilter] = None) -> Results:
        await self.__check_login()

        logger.debug('Getting alerts from Bricata...')

        tasks = [
            asyncio.create_task(
                self.request(method='get',
                             end_point='/alerts/',
                             request_id=uuid4().hex,
                             params=filters.dict if filters else None))
        ]
        results = Results(data=await asyncio.gather(*tasks))

        logger.debug(f'-> Complete; Retrieved {len(results.data)}, alerts.')

        return await self.process_results(results, 'objects')
Beispiel #14
0
    async def logout(self) -> Results:
        payload = {'username': self.cfg['Auth']['Username']}

        logger.debug('Logging out of Bricata...')

        tasks = [
            asyncio.create_task(
                self.request(method='post',
                             end_point='/logout/',
                             request_id=uuid4().hex,
                             json=payload))
        ]
        results = Results(data=await asyncio.gather(*tasks))

        logger.debug('-> Complete.')

        self.header = None

        return await self.process_results(results)
Beispiel #15
0
    async def __date_filter(query: Union[ContainerQuery],
                            results: Results) -> Results:
        """Date Filter
           - Filters Results by date

        Args:
            query (Union[ContainerQuery]):
            results (Results):

        Returns:
            results (Results):
        """
        results.success = [
            r for r in results.success
            if query.date_filter_start <= parse(r[query.date_filter_field],
                                                dayfirst=False) <=
            query.date_filter_end
        ]
        return results
Beispiel #16
0
    async def login(self) -> Results:
        """

        Returns:
            results (Results):
        """
        payload = {'username': self.cfg['Auth']['Username'], 'password': self.cfg['Auth']['Password']}

        logger.debug('Logging in to Exabeam...')

        tasks = [asyncio.create_task(self.request(method='post',
                                                  end_point='/api/auth/login',
                                                  request_id=uuid4().hex,
                                                  json=payload))]
        results = Results(data=await asyncio.gather(*tasks))

        logger.debug('-> Complete.')

        self.logged_in = True

        return await self.process_results(results)
Beispiel #17
0
    async def get_case_count(self, query: Optional[Query] = Query(maxRecords=1, offset=0)) -> Results:
        """
        Performs a single page query to get the 'totalResult' based on specified Query.
        Args:
            query (Optional[Query]):

        Returns:
            results (Results)
        """
        # todo: need to see actual output to verify this
        logger.debug('Getting case count...')

        tasks = [asyncio.create_task(self.request(method='get',
                                                  end_point='/cases',
                                                  request_id=uuid4().hex,
                                                  params=query.params()))]

        results = Results(data=await asyncio.gather(*tasks))

        logger.debug('-> Complete.')

        return await self.process_results(results)
Beispiel #18
0
    async def get_records(
            self, query: Union[ArtifactQuery, AuditQuery,
                               ContainerQuery]) -> Results:
        """
        Args:
            query (ContainerQuery):

        Returns:
            results (Results)"""
        logger.debug(f'Getting {type(query)}, record(s)...')

        if type(query) is AuditQuery:
            page_limit = 1
        else:
            if not query.id:
                page_limit = (
                    await self.get_record_count(query)).success[0]['num_pages']
            else:  # When we're getting a single container we can skip paging
                page_limit = 1

        tasks = [
            asyncio.create_task(
                self.request(method='get',
                             end_point=query.end_point,
                             request_id=uuid4().hex,
                             params={
                                 **query.dict(), 'page': i
                             })) for i in range(0, page_limit)
        ]

        results = await self.process_results(
            Results(data=await asyncio.gather(*tasks)), query.data_key)

        if query.date_filter_field:
            results = await self.__date_filter(query=query, results=results)

        logger.debug('-> Complete.')

        return results
Beispiel #19
0
    async def get_cases(self, case_id: Optional[str], query: Optional[Query] = Query()) -> Results:
        """
        Can retrieve:
            - All cases
            - A single case
        Args:
            case_id (Optional[int]):
            query (Optional[Query]):

        Returns:
            results (Results)
        """
        if case_id:
            ep = f'/cases/{case_id}'
        else:
            ep = '/cases'

        if not case_id:
            # todo: rewrite for phishlabs
            # page_limit = (await self.get_case_count(query=query)).success[0]['num_pages']
            page_limit = 0
        else:  # When we're getting a single container we can skip paging
            page_limit = 1

        logger.debug('Getting cases(s)...')

        tasks = [asyncio.create_task(self.request(method='get',
                                                  end_point=ep,
                                                  request_id=uuid4().hex,
                                                  params=query.params(offset=i)))
                 for i in range(0, page_limit, query.maxRecords)]

        results = Results(data=await asyncio.gather(*tasks))

        logger.debug('-> Complete.')

        return await self.process_results(results, 'data')
Beispiel #20
0
    async def get_notable_users(self, query: Optional[NotableUsersQuery] = NotableUsersQuery()) -> Results:
        """

        Args:
            query (OptionL[NotableUsersQuery]):

        Returns:
            results (Results):

        """
        if not self.logged_in:
            await self.login()

        logger.debug('Getting notable users from Exabeam...')

        tasks = [asyncio.create_task(self.request(method='get',
                                                  end_point='/uba/api/users/notable',
                                                  request_id=uuid4().hex,
                                                  params=query.dict()))]
        results = Results(data=await asyncio.gather(*tasks))

        logger.debug(f'-> Complete; Retrieved {len(results.data)}, notable users.')

        return await self.process_results(results, 'users')
Beispiel #21
0
    async def create_containers(
        self, containers: Union[List[ContainerRequest], ContainerRequest]
    ) -> Tuple[Results, Any]:
        # todo: handle revert_failure
        # todo: handle failure (already exists)
        # todo: handle update_existing
        if type(containers) is not list:
            containers = [containers]

        logger.debug('Creating container(s)...')
        tasks = [
            asyncio.create_task(
                self.request(method='post',
                             end_point='/container',
                             request_id=c.data['request_id'],
                             json=c.dict())) for c in containers
        ]

        container_results = await self.process_results(
            Results(data=await asyncio.gather(*tasks)))
        logger.debug('-> Complete.')

        # print('container_results:\n', container_results)

        [
            c.update_id(
                next((_['id'] for _ in container_results.success
                      if _['request_id'] == c.data['request_id']), None))
            for c in containers
        ]

        artifact_results, containers = await self.create_artifacts(containers)
        container_results.success.extend(artifact_results.success)
        container_results.failure.extend(artifact_results.failure)

        return container_results, containers
Beispiel #22
0
    async def create_artifacts(
        self, containers: Union[List[ContainerRequest], ContainerRequest]
    ) -> Tuple[Results, List[ContainerRequest]]:
        # todo: handle failure (already exists?)
        logger.debug('Creating artifact(s)...')
        if type(containers) is not list:
            containers = [containers]

        # if type(containers[0]) is ContainerRequest:
        tasks = [
            asyncio.create_task(
                self.request(method='post',
                             end_point='/artifact',
                             request_id=a.data['request_id'],
                             json=a.dict())) for x in containers
            for a in x.artifacts
        ]
        # else:  # ArtifactRequest
        #     tasks = [asyncio.create_task(self.request(method='post',
        #                                               end_point='/artifact',
        #                                               request_id=a.data['request_id'],
        #                                               json=a.dict())) for a in containers]

        results = await self.process_results(
            Results(data=await asyncio.gather(*tasks)))

        [
            a.update_id(
                next((_['id'] for _ in results.success
                      if _['request_id'] == a.data['request_id']), None))
            for x in containers for a in x.artifacts
        ]

        logger.debug('-> Complete.')

        return results, containers
Beispiel #23
0
    async def get_records(self, query: Union[AlertQuery]) -> Results:
        """
        Args:
            query (Union[AlertQuery]):

        Returns:
            results (Results)"""
        await self.__check_login()

        logger.debug(f'Getting {type(query)}, record(s)...')
        tasks = [
            asyncio.create_task(
                self.request(method='get',
                             end_point=query.end_point,
                             request_id=uuid4().hex,
                             params=query.dict()))
        ]

        results = await self.process_results(
            Results(data=await asyncio.gather(*tasks)), query.data_key)

        logger.debug('-> Complete.')

        return results