Example #1
0
def get_qsessions() -> dict:
    """
        Get session ids of currently queued RTR sessions
    """
    endpoint_url = '/real-time-response/queries/sessions/v1'

    if helpers.is_expiring(BATCH_LIFE_TIME, BATCH_REQ_TIME):
        refresh_rtr_session()

    params = {'sort': 'created_at|desc', 'filter': 'commands_queued:1'}
    response = http_request('GET', endpoint_url, params=params)

    return response
Example #2
0
def delete_rtr_session() -> dict:
    """
        Retrieves a script given its ID
        :return: Response JSON which contains errors (if exist) and retrieved resource
    """
    endpoint_url = '/real-time-response/entities/sessions/v1'

    if helpers.is_expiring(BATCH_LIFE_TIME, BATCH_REQ_TIME):
        refresh_rtr_session()

    params = {'session_id': BATCH_ID}
    response = http_request('DELETE', endpoint_url, params=params)
    return response
Example #3
0
def delete_qsession(session_id: str) -> dict:
    """
        Delete a queued RTR session by session ID
        :param session_id: Session ID of session to delete
    """
    endpoint_url = '/real-time-response/entities/sessions/v1'

    if helpers.is_expiring(BATCH_LIFE_TIME, BATCH_REQ_TIME):
        refresh_rtr_session()

    params = {'session_id': session_id}
    response = http_request('DELETE', endpoint_url, params=params)

    return response
Example #4
0
def get_qsessions_metadata(session_ids: list) -> dict:
    """
        Get metadata of currently queued RTR sessions by session IDs
        :param session_ids: List of session ids to retrieve metadata for
    """
    endpoint_url = '/real-time-response/entities/queued-sessions/GET/v1'

    if helpers.is_expiring(BATCH_LIFE_TIME, BATCH_REQ_TIME):
        refresh_rtr_session()

    body = json.dumps({'ids': session_ids})
    response = http_request('POST', endpoint_url, data=body)

    return response
Example #5
0
def delete_qsession_command(session_id: str, cloud_request_id: str) -> dict:
    """
        Delete a queued RTR session command by session ID and cloud request ID
        :param session_id:
        :param cloud_request_id:
    """

    endpoint_url = '/real-time-response/entities/queued-sessions/command/v1'

    if helpers.is_expiring(BATCH_LIFE_TIME, BATCH_REQ_TIME):
        refresh_rtr_session()

    params = {'session_id': session_id, 'cloud_request_id': cloud_request_id}
    response = http_request('DELETE', endpoint_url, params=params)

    return response
Example #6
0
def run_batch_cmd(command_type: str, full_command: str) -> dict:
    """
        Batch executes a RTR active-responder command across the hosts mapped to the given batch id
        :param command_type: Command type we are going to execute, for example: ls or cd.
        :param full_command: Full command string for the command.
    """
    endpoint_url = '/real-time-response/combined/batch-command/v1'

    if helpers.is_expiring(BATCH_LIFE_TIME, BATCH_REQ_TIME):
        refresh_rtr_session()

    params = {'timeout_duration': '2m'}
    body = json.dumps({
        'base_command': command_type,
        'batch_id': BATCH_ID,
        'command_string': full_command
    })
    response = http_request('POST', endpoint_url, params=params, data=body)

    return response
Example #7
0
def get_token(new_token: bool = False) -> str:
    """
        Retrieves the token from the server if it's expired and updates the global HEADERS to include it
        :param new_token: If set to True will generate a new token regardless of time passed
        :return: Token
    """
    global HEADERS, TOKEN
    auth_token = TOKEN

    if new_token:
        auth_token = get_token_request()
    else:
        if helpers.is_expiring(TOKEN_LIFE_TIME, TOKEN_REQ_TIME):
            auth_token = get_token_request()

    HEADERS['Authorization'] = 'Bearer {}'.format(auth_token)
    TOKEN = auth_token
    with open(TOKEN_PATH, 'w') as outfile:
        outfile.write(auth_token)
    return auth_token
Example #8
0
def http_request(method: str,
                 url_suffix: str,
                 params: dict = None,
                 data: dict = None,
                 headers: dict = HEADERS,
                 files: dict = None,
                 safe: bool = False,
                 get_token_flag: bool = True) -> dict:
    """
        A wrapper for requests lib to send our requests and handle requests and responses better.
        :param method: HTTP method for the request.
        :param url_suffix: The suffix of the URL (endpoint)
        :param params: The URL params to be passed.
        :param data: The body data of the request.
        :param headers: Request headers
        :param files: The files data of the request
        :param safe: If set to true will return None in case of http error
        :param get_token_flag: If set to True will call get_token()
        :return: Returns the http request response json
    """
    response = ""

    if get_token_flag:
        token = get_token()
        headers['Authorization'] = 'Bearer {}'.format(token)
    url = SERVER + url_suffix
    try:
        response = requests.request(method,
                                    url,
                                    verify=USE_SSL,
                                    params=params,
                                    data=data,
                                    headers=headers,
                                    files=files)
    except requests.exceptions.RequestException:
        print(
            'Error in connection to the server. Please make sure you entered the URL correctly.'
        )
    try:
        resp_json = response.json()
        # print(url_suffix, response.status_code)  # debug
        if response.status_code not in {200, 201, 202}:
            reason = response.reason
            resources = resp_json.get('resources', {})
            if resources and type(resources) is dict:
                for host_id, resource in resources.items():
                    errors = resource.get('errors', [])
                    if errors:
                        error_message = errors[0].get('message')
                        reason += f'\nHost ID {host_id} - {error_message}'
            elif resp_json.get('errors'):
                errors = resp_json.get('errors', [])
                for error in errors:
                    reason += f"\n{error.get('message')}"
            err_msg = 'Error in API call to CrowdStrike Falcon: code: {code} - reason: {reason}'.format(
                code=response.status_code, reason=reason)
            # try to create a new token
            if response.status_code in (401, 403):
                if helpers.is_expiring(TOKEN_LIFE_TIME, TOKEN_REQ_TIME):
                    get_token(new_token=True)
                    return http_request(method,
                                        url_suffix,
                                        params,
                                        data,
                                        HEADERS,
                                        files,
                                        safe,
                                        get_token_flag=False)
            elif safe:
                return None
            print(err_msg)
        return resp_json
    except ValueError as exception:
        if url_suffix == '/real-time-response/entities/sessions/v1' and method == 'DELETE':  # empty json when success
            pass
        else:
            raise ValueError(
                f'Failed to parse json object from response: {exception} - {response.content}'
            )