def query_loggings(query_data):
    '''
    This function handles all the querying of Cortex Logging service
    '''
    api_url = demisto.getIntegrationContext().get('api_url', 'https://api.us.paloaltonetworks.com')
    credentials = Credentials(
        access_token=get_access_token()
    )
    logging_service = LoggingService(
        url=api_url,
        credentials=credentials
    )

    query_result = logging_service.query(query_data).json()

    try:
        query_id = query_result['queryId']  # access 'queryId' from 'query' response
    except Exception as e:
        raise Exception('Received error %s when querying logs. Please check if your authentication token is valid' % e)
    poll_params = {  # Prepare 'poll' params
        "maxWaitTime": 3000  # waiting for response up to 3000ms
    }

    # we poll the logging service until we have a complete response
    full_response = logging_service.poll(query_id, 0, poll_params)

    # delete the query from the service
    logging_service.delete(query_id)

    return full_response
Beispiel #2
0
def send_request(query_path, body=None, params=None, json=None, headers=None, method='post', is_login=False):
    if headers is None:
        headers = HEADERS
    full_url = BASE_URL + query_path
    try:
        res = requests.request(
            method,
            full_url,
            headers=headers,
            verify=VERIFY_CERTIFICATE,
            data=body,
            params=params,
            json=json
        )

        if not res.ok and not is_login:
            if params and not body:
                params['authToken'] = login()
            else:
                body = body.replace(demisto.getIntegrationContext().get('auth_token'), login())
            return requests.request(
                method,
                full_url,
                headers=headers,
                verify=VERIFY_CERTIFICATE,
                data=body,
                params=params,
                json=json
            )
        return res

    except Exception as ex:
        demisto.debug(str(ex))
        return_error('Connection Error. Please check integration parameters')
Beispiel #3
0
def update_access_token():
    """
    Check if we have a valid token and if not get one and update global HEADERS
    """
    ctx = demisto.getIntegrationContext()
    if ctx.get('token') and ctx.get('stored'):
        if epoch_seconds() - ctx.get('stored') < 60 * 60 - 30:
            HEADERS['Authorization'] = 'Bearer ' + ctx.get('token')
            return
    headers = {
        'Authorization': TOKEN,
        'Accept': 'application/json'
    }
    token_retrieval_url = 'https://demistobot.demisto.com/azurecompute-token'  # disable-secrets-detection
    parameters = {'tenant': TENANT_ID, 'product': 'AzureCompute'}
    r = requests.get(token_retrieval_url, headers=headers, params=parameters, verify=USE_SSL)
    if r.status_code not in {200, 201}:
        return_error('Error in authentication with the application. Try checking the credentials you entered.')
    try:
        response = r.json()
    except ValueError:
        err_msg = 'There was a problem in retrieving an updated access token.'
        err_msg += ' The response from the Demistobot server did not contain the expected content.'
        return_error(err_msg)
    demisto.setIntegrationContext({
        'token': response.get('token'),
        'stored': epoch_seconds(),
        'subscription_id': response.get('subscription_id')
    })
    HEADERS['Authorization'] = 'Bearer ' + response.get('token')
Beispiel #4
0
def get_access_token(new_token, is_fetch=False):
    integration_context = demisto.getIntegrationContext()
    token_expiration_time = integration_context.get('token_expiration_time')
    current_time = date_to_timestamp(datetime.utcnow())
    if new_token or not token_expiration_time or token_expiration_time < current_time:
        token = get_new_access_token(is_fetch=is_fetch)
        return token
    else:
        return integration_context.get('access_token')
def get_access_token():
    integration_context = demisto.getIntegrationContext()
    access_token = integration_context.get('access_token')
    stored = integration_context.get('stored')
    if access_token and stored:
        if epoch_seconds() - stored < 60 * 60 - 30:
            return access_token
    headers = {
        'Authorization': AUTH_ID,
        'Accept': 'application/json'
    }

    dbot_response = requests.get(
        TOKEN_RETRIEVAL_URL,
        headers=headers,
        params={'token': get_encrypted(TOKEN, ENC_KEY)},
        verify=USE_SSL
    )
    if dbot_response.status_code not in {200, 201}:
        msg = 'Error in authentication. Try checking the credentials you entered.'
        try:
            demisto.info('Authentication failure from server: {} {} {}'.format(
                dbot_response.status_code, dbot_response.reason, dbot_response.text))
            err_response = dbot_response.json()
            server_msg = err_response.get('message')
            if server_msg:
                msg += ' Server message: {}'.format(server_msg)
        except Exception as ex:
            demisto.error('Failed parsing error response: [{}]. Exception: {}'.format(err_response.content, ex))
        raise Exception(msg)
    try:
        parsed_response = dbot_response.json()
    except ValueError:
        raise Exception(
            'There was a problem in retrieving an updated access token.\n'
            'The response from the Demistobot server did not contain the expected content.'
        )
    access_token = parsed_response.get('access_token')
    api_url = parsed_response.get('url')
    token = parsed_response.get('token')

    demisto.setIntegrationContext({
        'access_token': access_token,
        'stored': epoch_seconds(),
        'api_url': api_url,
        'token': token
    })
    return access_token
Beispiel #6
0
def request_new_access_token(using_refresh):
    url = BASE_URL + "token"
    refresh_token = demisto.getIntegrationContext().get('refresh_token')

    if using_refresh:
        payload = f'client_id={CLIENT_ID}&grant_type=refresh_token&refresh_token={refresh_token}'
    else:
        payload = f'client_id={CLIENT_ID}&grant_type=password&username={USERNAME}&password={PASSWORD}'

    headers = {
        'Accept': "application/json",
        'Content-Type': "application/x-www-form-urlencoded",
    }

    response = http_request('POST', url, payload, custom_headers=headers)
    return response
Beispiel #7
0
def load_extended_keys():
    global EXTENDED_KEYS
    if demisto.command() == 'fetch-incidents':
        last_run = demisto.getLastRun()
        EXTENDED_KEYS = last_run.get('extended_keys', {})
    else:
        integration_context = demisto.getIntegrationContext()
        EXTENDED_KEYS = integration_context.get('extended_keys', {})

    if not EXTENDED_KEYS:
        session = login()
        url = REST_ADDRESS + '/eventAttributeType/all'
        response = session.get(url, verify=VERIFY_SSL, auth=AUTH)
        EXTENDED_KEYS = dict((attr['attributeId'], attr['displayName']) for attr in response.json())

        if demisto.command() != 'fetch-incidents':
            demisto.setIntegrationContext({'extended_keys': EXTENDED_KEYS})
def query_loggings(query_data):
    """
    This function handles all the querying of Cortex Logging service
    """
    api_url = demisto.getIntegrationContext().get('api_url', 'https://api.us.paloaltonetworks.com')
    credentials = Credentials(
        access_token=get_access_token(),
        verify=USE_SSL
    )
    logging_service = LoggingService(
        url=api_url,
        credentials=credentials
    )

    response = logging_service.query(query_data)
    query_result = response.json()

    if not response.ok:
        status_code = query_result.get('statusCode', '')
        error = query_result.get('error', '')
        message = query_result.get('payload', {}).get('message', '')
        raise Exception(f"Error in query to Cortex [{status_code}] - {error}: {message}")

    try:
        query_id = query_result['queryId']  # access 'queryId' from 'query' response
    except Exception as e:
        raise Exception('Received error %s when querying logs.' % e)
    poll_params = {  # Prepare 'poll' params
        "maxWaitTime": 3000  # waiting for response up to 3000ms
    }

    # we poll the logging service until we have a complete response
    full_response = logging_service.poll(query_id, 0, poll_params)

    # delete the query from the service
    logging_service.delete(query_id)

    return full_response
def get_token(refresh_token=False):
    """
    Check if we have a valid token and if not get one
    """
    ctx = demisto.getIntegrationContext()
    if {'token', 'stored', 'expires'} <= set(ctx) and not refresh_token:
        if epoch_seconds() - ctx.get('stored') < ctx.get('expires'):
            return ctx.get('token')
    response = requests.get(
        DEMISTOBOT,
        headers=HEADERS,
        params={"tenant": TENANT, "product": PRODUCT},
        verify=USE_SSL,
    )
    data = response.json()
    if not response.ok:
        return_error(f'API call to MS Graph failed [{data.get("status")} {data.get("title")}] - {data.get("detail")}')

    demisto.setIntegrationContext({
        'token': data.get('token'),
        'stored': epoch_seconds(),
        'expires': data.get('expires', 3600) - 30
    })
    return data.get('token')
Beispiel #10
0
def get_access_token():
    integration_context = demisto.getIntegrationContext()
    access_token = integration_context.get('access_token')
    valid_until = integration_context.get('valid_until')
    calling_context = demisto.callingContext.get(
        'context', {})  # type: ignore[attr-defined]
    brand_name = calling_context.get('IntegrationBrand', '')
    instance_name = calling_context.get('IntegrationInstance', '')
    if access_token and valid_until:
        if epoch_seconds() < valid_until:
            return access_token
    headers = {'Accept': 'application/json'}
    headers['X-Content-Version'] = CONTENT_RELEASE_VERSION
    headers['X-Branch-Name'] = CONTENT_BRANCH_NAME
    headers['X-Content-Name'] = brand_name or instance_name or 'Name not found'

    dbot_response = requests.post(TOKEN_RETRIEVAL_URL,
                                  headers=headers,
                                  data=json.dumps({
                                      'app_name':
                                      APP_NAME,
                                      'registration_id':
                                      AUTH_ID,
                                      'encrypted_token':
                                      get_encrypted(TENANT_ID, ENC_KEY)
                                  }),
                                  verify=USE_SSL)
    if dbot_response.status_code not in {200, 201}:
        msg = 'Error in authentication. Try checking the credentials you entered.'
        try:
            demisto.info('Authentication failure from server: {} {} {}'.format(
                dbot_response.status_code, dbot_response.reason,
                dbot_response.text))
            err_response = dbot_response.json()
            server_msg = err_response.get('message')
            if not server_msg:
                title = err_response.get('title')
                detail = err_response.get('detail')
                if title:
                    server_msg = f'{title}. {detail}'
            if server_msg:
                msg += ' Server message: {}'.format(server_msg)
        except Exception as ex:
            demisto.error(
                'Failed parsing error response - Exception: {}'.format(ex))
        raise Exception(msg)
    try:
        gcloud_function_exec_id = dbot_response.headers.get(
            'Function-Execution-Id')
        demisto.info(
            f'Google Cloud Function Execution ID: {gcloud_function_exec_id}')
        parsed_response = dbot_response.json()
    except ValueError:
        raise Exception(
            'There was a problem in retrieving an updated access token.\n'
            'The response from the Demistobot server did not contain the expected content.'
        )
    access_token = parsed_response.get('access_token')
    expires_in = parsed_response.get('expires_in', 3595)
    time_now = epoch_seconds()
    time_buffer = 5  # seconds by which to shorten the validity period
    if expires_in - time_buffer > 0:
        # err on the side of caution with a slightly shorter access token validity period
        expires_in = expires_in - time_buffer

    demisto.setIntegrationContext({
        'access_token': access_token,
        'valid_until': time_now + expires_in
    })
    return access_token
Beispiel #11
0
def main():
    """ COMMANDS MANAGER / SWITCH PANEL """
    params = demisto.params()

    self_deployed = params.get('self_deployed', False)

    # params related to common instance configuration
    base_url = 'https://graph.microsoft.com/v1.0/'
    use_ssl = not params.get('insecure', False)
    proxy = params.get('proxy', False)
    ok_codes = (200, 201, 202)
    refresh_token = params.get('refresh_token', '')
    auth_and_token_url = params.get('auth_id', '')
    enc_key = params.get('enc_key', '')
    app_name = 'ms-graph-mail-listener'

    # params related to mailbox to fetch incidents
    mailbox_to_fetch = params.get('mailbox_to_fetch', '')
    folder_to_fetch = params.get('folder_to_fetch', 'Inbox')
    first_fetch_interval = params.get('first_fetch', '15 minutes')
    emails_fetch_limit = int(params.get('fetch_limit', '50'))

    # params related to self deployed
    tenant_id = refresh_token if self_deployed else ''

    # params related to oproxy
    # In case the script is running for the first time, refresh token is retrieved from integration parameters,
    # in other case it's retrieved from integration context.
    refresh_token = (
        demisto.getIntegrationContext().get('current_refresh_token')
        or refresh_token)

    client = MsGraphClient(self_deployed, tenant_id, auth_and_token_url,
                           enc_key, app_name, base_url, use_ssl, proxy,
                           ok_codes, refresh_token, mailbox_to_fetch,
                           folder_to_fetch, first_fetch_interval,
                           emails_fetch_limit)
    try:
        command = demisto.command()
        args = prepare_args(command, demisto.args())
        LOG(f'Command being called is {command}')

        if command == 'test-module':
            # cannot use test module due to the lack of ability to set refresh token to integration context
            raise Exception("Please use !msgraph-mail-test instead")
        if command == 'msgraph-mail-test':
            client.test_connection()
        if command == 'fetch-incidents':
            next_run, incidents = client.fetch_incidents(demisto.getLastRun())
            demisto.setLastRun(next_run)
            demisto.incidents(incidents)
        elif command == 'msgraph-mail-create-draft':
            human_readable, ec, raw_response = client.create_draft(**args)
            return_outputs(human_readable, ec, raw_response)
        elif command == 'msgraph-mail-reply-to':
            human_readable = client.reply_to(**args)  # pylint: disable=E1123
            return_outputs(human_readable)
        elif command == 'msgraph-mail-send-draft':
            human_readable = client.send_draft(**args)  # pylint: disable=E1123
            return_outputs(human_readable)
        elif command == 'send-mail':
            human_readable, ec = client.send_email(**args)
            return_outputs(human_readable, ec)
    except Exception as e:
        return_error(str(e))
Beispiel #12
0
        contents = decode_arcsight_output(query_viewers)
        outputs = {'ArcSightESM.AllQueryViewers': contents}
        human_readable = tableToMarkdown(name='',
                                         t=query_viewers,
                                         headers='Query Viewers',
                                         removeNull=True)
        return_outputs(readable_output=human_readable,
                       outputs=outputs,
                       raw_response=contents)

    else:
        demisto.results('No Query Viewers were found')


AUTH_TOKEN = demisto.getIntegrationContext().get('auth_token') or login()
try:
    if demisto.command() == 'test-module':
        test()
        demisto.results('ok')

    elif demisto.command() == 'as-fetch-incidents' or demisto.command(
    ) == 'fetch-incidents':
        fetch()

    elif demisto.command() == 'as-get-matrix-data' or demisto.command(
    ) == 'as-get-query-viewer-results':
        get_query_viewer_results_command()

    elif demisto.command() == 'as-get-all-cases':
        get_all_cases_command()
Beispiel #13
0
async def listen(**payload):
    """
    Listens to Slack RTM messages
    :param payload: The message payload
    """
    data: dict = payload.get('data', {})
    data_type: str = payload.get('type', '')
    client: slack.WebClient = payload.get('web_client')

    if data_type == 'error':
        error = payload.get('error', {})
        await handle_listen_error(
            'Slack API has thrown an error. Code: {}, Message: {}.'.format(
                error.get('code'), error.get('msg')))
        return
    try:
        subtype = data.get('subtype', '')
        text = data.get('text', '')
        user_id = data.get('user', '')
        channel = data.get('channel', '')
        message_bot_id = data.get('bot_id', '')

        if subtype == 'bot_message' or message_bot_id:
            return

        integration_context = demisto.getIntegrationContext()
        user = await get_user_by_id_async(client, integration_context, user_id)
        if channel and channel[0] == 'D':
            # DM
            await handle_dm(user, text, client)
        elif await check_and_handle_entitlement(text, user):
            await client.chat_postMessage(
                channel=channel,
                text='Response received by {}'.format(user.get('name')))
        else:
            if not integration_context or 'mirrors' not in integration_context:
                return

            channel_id = data.get('channel')
            mirrors = json.loads(integration_context['mirrors'])
            mirror_filter = list(
                filter(lambda m: m['channel_id'] == channel_id, mirrors))
            if not mirror_filter:
                return

            for mirror in mirror_filter:
                if mirror['mirror_direction'] == 'FromDemisto' or mirror[
                        'mirror_type'] == 'none':
                    return

                if not mirror['mirrored']:
                    # In case the investigation is not mirrored yet
                    mirror = mirrors.pop(mirrors.index(mirror))
                    if mirror['mirror_to'] and mirror[
                            'mirror_direction'] and mirror['mirror_type']:
                        investigation_id = mirror['investigation_id']
                        mirror_type = mirror['mirror_type']
                        auto_close = mirror['auto_close']
                        direction = mirror['mirror_direction']
                        if isinstance(auto_close, str):
                            auto_close = bool(strtobool(auto_close))
                            demisto.info(
                                'Mirroring: {}'.format(investigation_id))
                        demisto.mirrorInvestigation(
                            investigation_id,
                            '{}:{}'.format(mirror_type, direction), auto_close)
                        mirror['mirrored'] = True
                        mirrors.append(mirror)
                        set_to_latest_integration_context('mirrors', mirrors)

                investigation_id = mirror['investigation_id']
                await handle_text(client, investigation_id, text, user)
        # Reset module health
        demisto.updateModuleHealth("")
    except Exception as e:
        await handle_listen_error(
            'Error occurred while listening to Slack: {}'.format(str(e)))
Beispiel #14
0
def slack_send_request(to: str,
                       channel: str,
                       group: str,
                       entry: str = '',
                       ignore_add_url: bool = False,
                       thread_id: str = '',
                       message: str = '',
                       file: dict = None) -> dict:
    """
    Requests to send a message or a file to Slack.
    :param to: A Slack user to send to.
    :param channel: A Slack channel to send to.
    :param group: A Slack private channel to send to.
    :param entry: WarRoom entry to send.
    :param ignore_add_url: Do not add a Demisto URL to the message.
    :param thread_id: The Slack thread ID to send to.
    :param message: A message to send.
    :param file: A file to send.
    :return: The Slack send response.
    """

    integration_context = demisto.getIntegrationContext()
    conversations: list = []
    mirrors: list = []
    if integration_context:
        if 'conversations' in integration_context:
            conversations = json.loads(integration_context['conversations'])
        if 'mirrors' in integration_context:
            mirrors = json.loads(integration_context['mirrors'])

    destinations = []

    if to:
        if isinstance(to, list):
            to = to[0]
        user = get_user_by_name(to)
        if not user:
            demisto.error('Could not find the Slack user {}'.format(to))
        else:
            im = CLIENT.im_open(user=user.get('id'))
            destinations.append(im.get('channel', {}).get('id'))
    if channel or group:
        if not destinations:
            destination_name = channel or group
            conversation_filter = list(
                filter(lambda c: c.get('name') == destination_name,
                       conversations))
            if conversation_filter:
                conversation = conversation_filter[0]
                conversation_id = conversation.get('id')
            else:
                mirrored_channel_filter = list(
                    filter(
                        lambda m: 'incident-{}'.format(m['investigation_id'])
                        == destination_name, mirrors))
                if mirrored_channel_filter:
                    channel_mirror = mirrored_channel_filter[0]
                    conversation_id = channel_mirror['channel_id']
                else:
                    conversation = get_conversation_by_name(destination_name)
                    if not conversation:
                        return_error(
                            'Could not find the Slack conversation {}'.format(
                                destination_name))
                    conversations.append(conversation)
                    set_to_latest_integration_context('conversations',
                                                      conversations)
                    conversation_id = conversation.get('id')

            if conversation_id:
                destinations.append(conversation_id)

    if not destinations:
        return_error('Could not find any destination to send to.')

    if file:
        response = send_file(destinations, file, integration_context,
                             thread_id)
        return response

    response = send_message(destinations, entry, ignore_add_url,
                            integration_context, message, thread_id)

    return response
Beispiel #15
0
def main():
    user_profile = None
    params = demisto.params()
    base_url = urljoin(params['url'].strip('/'), '/api/v1/')
    token = params.get('apitoken')
    mapper_in = params.get('mapper-in')
    mapper_out = params.get('mapper-out')
    verify_certificate = not params.get('insecure', False)
    proxy = params.get('proxy', False)
    command = demisto.command()
    args = demisto.args()

    is_create_enabled = params.get("create-user-enabled")
    is_disable_enabled = params.get("disable-user-enabled")
    is_update_enabled = demisto.params().get("update-user-enabled")
    create_if_not_exists = demisto.params().get("create-if-not-exists")

    is_fetch = params.get('isFetch')
    first_fetch_str = params.get('first_fetch')
    fetch_limit = int(params.get('max_fetch'))
    auto_generate_query_filter = params.get('auto_generate_query_filter')
    fetch_query_filter = params.get('fetch_query_filter')
    context = demisto.getIntegrationContext()

    headers = {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
        'Authorization': f'SSWS {token}'
    }

    client = Client(base_url=base_url,
                    verify=verify_certificate,
                    proxy=proxy,
                    headers=headers,
                    ok_codes=(200, ))

    demisto.debug(f'Command being called is {command}')

    if command == 'iam-get-user':
        user_profile = get_user_command(client, args, mapper_in)

    elif command == 'iam-create-user':
        user_profile = create_user_command(client, args, mapper_out,
                                           is_create_enabled,
                                           is_update_enabled)

    elif command == 'iam-update-user':
        user_profile = update_user_command(client, args, mapper_out,
                                           is_update_enabled,
                                           is_create_enabled,
                                           create_if_not_exists)

    elif command == 'iam-disable-user':
        user_profile = disable_user_command(client, args, is_disable_enabled)

    if user_profile:
        return_results(user_profile)

    try:
        if command == 'test-module':
            test_module(client, is_fetch, fetch_query_filter,
                        auto_generate_query_filter, context, first_fetch_str)

        elif command == 'get-mapping-fields':
            return_results(get_mapping_fields_command(client))

        elif command == 'okta-get-app-user-assignment':
            return_results(get_app_user_assignment_command(client, args))

        elif command == 'okta-iam-list-applications':
            return_results(list_apps_command(client, args))

        elif command == 'okta-iam-list-user-applications':
            return_results(list_user_apps_command(client, args))

        elif command == 'okta-iam-get-configuration':
            return_results(get_configuration(context))

        elif command == 'okta-iam-set-configuration':
            context = set_configuration(args)
            demisto.setIntegrationContext(context)

        elif command == 'fetch-incidents':
            last_run = demisto.getLastRun()
            context = demisto.getIntegrationContext()
            incidents, next_run = fetch_incidents(client, last_run,
                                                  first_fetch_str, fetch_limit,
                                                  fetch_query_filter,
                                                  auto_generate_query_filter,
                                                  context)
            demisto.incidents(incidents)
            demisto.setLastRun(next_run)

    except Exception:
        # For any other integration command exception, return an error
        return_error(
            f'Failed to execute {command} command. Traceback: {traceback.format_exc()}'
        )
Beispiel #16
0
def xdr_iocs_sync_command(client: Client, first_time: bool = False):
    if first_time or not demisto.getIntegrationContext():
        sync(client)
    else:
        iocs_to_keep(client)
Beispiel #17
0
def get_outbound_mimetype() -> str:
    """Returns the mimetype of the export_iocs"""
    ctx = demisto.getIntegrationContext().get('last_output')
    return ctx.get(CTX_MIMETYPE_KEY, 'text/plain')
Beispiel #18
0
def print_cache_command(client: Client, args: Dict[str, str]):
    cache = demisto.getIntegrationContext()
    return_outputs(cache, {}, {})
Beispiel #19
0
def main():
    params = demisto.params()
    credentials = params.get('credentials')
    base_url = params.get('url').strip('/')
    first_fetch_time = demisto.params().get('fetch_time', '3 days').strip()

    cache = demisto.getIntegrationContext()
    if not cache.get('fieldValueList'):
        cache['fieldValueList'] = {}
        demisto.setIntegrationContext(cache)

    client = Client(base_url,
                    credentials.get('identifier'), credentials.get('password'),
                    params.get('instanceName'),
                    params.get('userDomain'),
                    verify=not params.get('insecure', False),
                    proxy=params.get('proxy', False))
    commands = {
        'archer-search-applications': search_applications_command,
        'archer-get-application-fields': get_application_fields_command,
        'archer-get-field': get_field_command,
        'archer-get-mapping-by-level': get_mapping_by_level_command,
        'archer-get-record': get_record_command,
        'archer-create-record': create_record_command,
        'archer-delete-record': delete_record_command,
        'archer-update-record': update_record_command,
        'archer-execute-statistic-search-by-report': execute_statistics_command,
        'archer-get-reports': get_reports_command,
        'archer-get-search-options-by-guid': search_options_command,
        'archer-reset-cache': reset_cache_command,
        'archer-get-valuelist': get_value_list_command,
        'archer-upload-file': upload_file_command,
        'archer-get-file': download_file_command,
        'archer-list-users': list_users_command,
        'archer-search-records': search_records_command,
        'archer-search-records-by-report': search_records_by_report_command,
        'archer-print-cache': print_cache_command,
    }

    command = demisto.command()
    LOG(f'Command being called is {command}')

    try:
        if command == 'fetch-incidents':
            # Set and define the fetch incidents command to run after activated via integration settings.
            next_run, incidents = fetch_incidents(
                client=client,
                last_run=demisto.getLastRun(),
                first_fetch_time=first_fetch_time,
                params=params)

            demisto.setLastRun(next_run)
            demisto.incidents(incidents)
        elif command == 'test-module':
            demisto.results(test_module(client, params))
        elif command in commands:
            return commands[command](client, demisto.args())
        else:
            return_error('Command not found.')
    except Exception as e:
        return_error(f'Unexpected error: {str(e)}, traceback: {traceback.format_exc()}')
Beispiel #20
0
def get_edl_mimetype() -> str:
    """Returns the mimetype of the EDL"""
    ctx = demisto.getIntegrationContext()
    return ctx.get(EDL_MIMETYPE_KEY, 'text/plain')
Beispiel #21
0
def fetch_incidents_command():
    """
    Parent command to wrap events and behavior fetch commands
    """

    # Check if it's been run
    now = datetime.today()
    yesterday = datetime.strftime(now - timedelta(days=1), "%Y-%m-%d")
    last_run = demisto.getLastRun()
    start_date = yesterday
    end_date = yesterday

    if "start_time" not in last_run or "complete_for_today" not in last_run:
        # first time integration is running
        start_date = datetime.strftime(now - timedelta(days=FIRST_RUN), "%Y-%m-%d")

    if last_run.get('complete_for_today') is True and last_run.get('start_time') == yesterday:
        # wait until tomorrow to try again
        demisto.incidents([])
        return

    # Refresh JWT
    token = do_auth()

    # Fetch Events
    more_events = True
    no_events_found = True
    page_token = None
    incidents = []

    # Check if we've stored any events in the integration cache
    cache = demisto.getIntegrationContext()
    stored_incidents = cache.get("incidents")

    if stored_incidents is None:
        demisto.debug("Did not detect any stored incidents")
        while more_events:
            event_incidents, page_token, no_events_found = fetch_events_incidents_command(start_date, end_date, token, page_token)
            for incident in event_incidents:
                demisto.debug("Adding event incident name={name}, type={type}, severity={severity}".format(**incident))
            incidents += event_incidents
            if page_token is None:
                more_events = False

        # Fetch Behavior
        if BEHAVIOR_ENABLED:
            more_behavior = True
            next_offset = None

            while more_behavior:
                behavior_incidents, next_offset = fetch_behavior_incidents_command(start_date, token, next_offset)
                for incident in behavior_incidents:
                    demisto.debug("Adding behavior incident name={name}, type={type}, severity={severity}".format(**incident))
                incidents += behavior_incidents
                if next_offset is None:
                    more_behavior = False

        if len(incidents) == 0 and no_events_found:
            # return and try again later, API may not have updated.
            demisto.debug("Will retry - no events returned")
            demisto.incidents([])
            return
        elif len(incidents) > PAGE_LIMIT:
            incidents_to_send = incidents[:PAGE_LIMIT]
            del incidents[:PAGE_LIMIT]
            demisto.incidents(incidents_to_send)
        else:
            demisto.incidents(incidents)
            incidents = []

        # Add remaining incidents to cache
        if len(incidents) > 0:
            demisto.debug("Updating cache to store {} incidents".format(len(incidents)))
            cache["incidents"] = incidents
            demisto.setIntegrationContext(cache)
            demisto.setLastRun({
                "complete_for_today": False,
                "start_time": yesterday
            })
        else:
            cache["incidents"] = None
            demisto.setIntegrationContext(cache)
            demisto.setLastRun({
                "complete_for_today": True,
                "start_time": yesterday
            })
    else:
        demisto.debug("Found {} stored incidents".format(len(stored_incidents)))
        # Send next PAGE_LIMIT number of incidents to demisto
        if len(stored_incidents) > PAGE_LIMIT:
            incidents_to_send = stored_incidents[:PAGE_LIMIT]
            del stored_incidents[:PAGE_LIMIT]
            demisto.debug("Updating cache to store {} incidents".format(len(stored_incidents)))
            demisto.setLastRun({
                "complete_for_today": False,
                "start_time": yesterday
            })
        else:
            incidents_to_send = list(stored_incidents)
            stored_incidents = None
            demisto.debug("Updating cache to store 0 incidents")
            demisto.setLastRun({
                "complete_for_today": True,
                "start_time": yesterday
            })
        demisto.incidents(incidents_to_send)

        # Update Cache
        cache["incidents"] = stored_incidents
        demisto.setIntegrationContext(cache)
Beispiel #22
0
def main():
    base_url = demisto.params().get('base_url',
                                    'https://manage.office.com/api/v1.0/')
    verify_certificate = not demisto.params().get('insecure', False)

    first_fetch_delta = demisto.params().get('first_fetch_delta',
                                             '10 minutes').strip()
    first_fetch_datetime, _ = parse_date_range(first_fetch_delta)

    proxy = demisto.params().get('proxy', False)

    LOG(f'Command being called is {demisto.command()}')
    try:
        if demisto.command() == 'test-module':
            result = test_module()
            return_error(result)

        args = demisto.args()
        params = demisto.params()
        refresh_token = params.get('refresh_token', '')
        self_deployed = params.get('self_deployed', False)
        tenant_id = refresh_token if self_deployed else ''
        auth_id = params['auth_id']
        enc_key = params['enc_key']

        refresh_token = (
            demisto.getIntegrationContext().get('current_refresh_token')
            or refresh_token)

        client = Client(base_url=base_url,
                        tenant_id=tenant_id,
                        verify=verify_certificate,
                        proxy=proxy,
                        self_deployed=self_deployed,
                        refresh_token=refresh_token,
                        auth_and_token_url=auth_id,
                        enc_key=enc_key,
                        auth_code=params.get('auth_code', ''))

        access_token, token_data = client.get_access_token_data()
        client.access_token = access_token
        client.tenant_id = token_data['tid']

        if demisto.command() == 'fetch-incidents':
            next_run, incidents = fetch_incidents(
                client=client,
                last_run=demisto.getLastRun(),
                first_fetch_datetime=first_fetch_datetime)

            demisto.setLastRun(next_run)
            demisto.incidents(incidents)

        elif demisto.command() == 'ms-management-activity-start-subscription':
            start_or_stop_subscription_command(client, args, 'start')

        elif demisto.command() == 'ms-management-activity-stop-subscription':
            start_or_stop_subscription_command(client, args, 'stop')

        elif demisto.command() == 'ms-management-activity-list-subscriptions':
            list_subscriptions_command(client)

        elif demisto.command() == 'ms-management-activity-list-content':
            list_content_command(client, args)

    # Log exceptions
    except Exception as e:
        return_error(
            f'Failed to execute {demisto.command()} command. Error: {str(e)}')
Beispiel #23
0
    def _get_access_token(self):
        """
        Obtains access and refresh token from Oprxoy server. Access token is used and stored in the integration context
        until expiration time. After expiration, new refresh token and access token are obtained and stored in the
        integration context.

        :return: Access token that will be added to authorization header
        :rtype: ``str``
        """
        integration_context = demisto.getIntegrationContext()
        access_token = integration_context.get('access_token')
        valid_until = integration_context.get('valid_until')
        if access_token and valid_until:
            if epoch_seconds() < valid_until:
                return access_token

        oproxy_response = requests.post(self._token_retrieval_url,
                                        json={
                                            'app_name':
                                            self._app_name,
                                            'registration_id':
                                            self._auth_id,
                                            'encrypted_token':
                                            get_encrypted(
                                                self._refresh_token,
                                                self._enc_key)
                                        },
                                        verify=self._verify)

        if oproxy_response.status_code not in {200, 201}:
            msg = 'Error in authentication. Try checking the credentials you entered.'
            try:
                demisto.info(
                    'Authentication failure from server: {} {} {}'.format(
                        oproxy_response.status_code, oproxy_response.reason,
                        oproxy_response.text))
                err_response = oproxy_response.json()
                server_msg = err_response.get('message')
                if not server_msg:
                    title = err_response.get('title')
                    detail = err_response.get('detail')
                    if title:
                        server_msg = f'{title}. {detail}'
                if server_msg:
                    msg += ' Server message: {}'.format(server_msg)
            except Exception as ex:
                demisto.error(
                    'Failed parsing error response - Exception: {}'.format(ex))
            raise Exception(msg)
        try:
            gcloud_function_exec_id = oproxy_response.headers.get(
                'Function-Execution-Id')
            demisto.info(
                f'Google Cloud Function Execution ID: {gcloud_function_exec_id}'
            )
            parsed_response = oproxy_response.json()
        except ValueError:
            raise Exception(
                'There was a problem in retrieving an updated access token.\n'
                'The response from the Oproxy server did not contain the expected content.'
            )
        access_token = parsed_response.get('access_token')
        expires_in = parsed_response.get('expires_in', 3595)
        current_refresh_token = parsed_response.get('refresh_token')
        time_now = epoch_seconds()
        time_buffer = 5  # seconds by which to shorten the validity period
        if expires_in - time_buffer > 0:
            # err on the side of caution with a slightly shorter access token validity period
            expires_in = expires_in - time_buffer

        demisto.setIntegrationContext({
            'access_token':
            access_token,
            'valid_until':
            time_now + expires_in,
            'current_refresh_token':
            current_refresh_token
        })
        return access_token
from CommonServerPython import *
from CommonServerUserPython import *
''' IMPORTS '''
import os
import requests
import json
from pancloud import LoggingService, Credentials
import base64
from cryptography.hazmat.primitives.ciphers.aead import AESGCM

# disable insecure warnings
requests.packages.urllib3.disable_warnings()
''' GLOBAL VARS '''
AUTH_ID = demisto.params().get('auth_id')
# If there's a stored token in integration context, it's newer than current
TOKEN = demisto.getIntegrationContext().get('token')
if not TOKEN:
    TOKEN = demisto.params().get('token')

ENC_KEY = demisto.params().get('auth_key')

USE_SSL = not demisto.params().get('insecure', False)
TOKEN_RETRIEVAL_URL = 'https://demistobot.demisto.com/panw-token'
FETCH_QUERY = None

FIRST_FETCH_TIMESTAMP = demisto.params().get('first_fetch_timestamp',
                                             '').strip()
if not FIRST_FETCH_TIMESTAMP:
    FIRST_FETCH_TIMESTAMP = '24 hours'

if not demisto.params().get('proxy', False):
def edl_update_internal_list(list_name: str, list_items: list, add: bool,
                             verbose: bool):
    dict_of_lists = demisto.getIntegrationContext()

    if not dict_of_lists:
        demisto.debug('PAN-OS EDL Management integration context is empty.')
        dict_of_lists = {list_name: list_items}
        if verbose:
            md = tableToMarkdown('List items:',
                                 list_items,
                                 headers=[list_name])
        else:
            md = 'Instance context updated successfully.'
    else:
        if not dict_of_lists.get(list_name, None) and not add:
            raise Exception(
                f'Cannot remove items from an empty list: {list_name}.')

        if dict_of_lists.get(list_name, None):
            if add:
                chosen_list = dict_of_lists.get(list_name)
                if not isinstance(chosen_list, list):
                    chosen_list = [chosen_list]

                list_items = list(set(chosen_list + list_items))
            else:  # remove
                list_items = [
                    item for item in dict_of_lists.get(list_name)
                    if item not in list_items
                ]

        if not add and len(list_items) == 0:
            # delete list from instance context, can happen only upon remove of objects
            demisto.debug(
                f'PAN-OS EDL Management deleting {list_name} from the integration context.'
            )
            dict_of_lists.pop(list_name, None)
            md = 'List is empty, deleted from instance context.'
        else:
            # update list in instance context, can happen upon removal or addition of objects
            dict_of_lists.update({list_name: list_items})
            if verbose:
                md = tableToMarkdown('List items:',
                                     list_items,
                                     headers=[list_name])
            else:
                md = 'Instance context updated successfully.'

    if not dict_of_lists:  # to be removed, debugging purposes only
        demisto.debug(
            'PAN-OS EDL Management updating an empty object to the integration context.'
        )

    demisto.debug(
        f'PAN-OS EDL Management updating {list_name} with {len(list_items)} in the integration context.'
    )
    demisto.setIntegrationContext(dict_of_lists)

    demisto.results({
        'ContentsFormat': formats['markdown'],
        'Type': entryTypes['note'],
        'Contents': md
    })
Beispiel #26
0
def main():
    command = demisto.command()
    params = demisto.params()

    is_fetch = params.get('isFetch')
    report_url = params.get('report_url')
    verify_certificate = not params.get('insecure', False)
    proxy = params.get('proxy', False)
    mapper_in = params.get('mapper_in', DEFAULT_MAPPER_IN)
    workday_username = params.get('credentials', {}).get('identifier')
    workday_password = params.get('credentials', {}).get('password')

    demisto.debug(f'Command being called is {command}')

    client = Client(
        base_url='',  # using report_url in _http_request
        verify=verify_certificate,
        headers={
            'Accept': 'application/json',
            'Content-Type': 'application/json'
        },
        proxy=proxy,
        ok_codes=(200, 204),
        auth=requests.auth.HTTPBasicAuth(workday_username, workday_password))

    try:
        if command == 'test-module':
            return_results(test_module(client, is_fetch, report_url,
                                       mapper_in))

        if command == 'fetch-incidents':
            '''
                Checks if there are events are stored in the integration context.
                If yes, it gets it from there. Else, it makes a call to Workday to get a new report
                Returns the first x events (x being the fetch limit) and stores the remaining in integration context
            '''
            workday_context = demisto.getIntegrationContext()
            last_run = demisto.getLastRun()
            events = workday_context.get('events', [])
            report_url = params.get('report_url')

            if params.get('fetch_samples'):
                sample_events = fetch_samples(client=client,
                                              mapper_in=mapper_in,
                                              report_url=report_url)
                demisto.incidents(sample_events)

            else:
                if not last_run.get('synced_users') and params.get(
                        'first_run'):
                    workday_first_run_command(client, mapper_in, report_url)

                elif not events:
                    # Get the events from Workday by making an API call. Last run is updated only when API call is made
                    events = fetch_incidents(client=client,
                                             mapper_in=mapper_in,
                                             report_url=report_url)

                fetch_limit = int(params.get('max_fetch'))

                demisto.setLastRun({'synced_users': True})
                demisto.incidents(events[:fetch_limit])

                # Set the remaining events back to integration context
                workday_context = {'events': events[fetch_limit:]}
                demisto.setIntegrationContext(workday_context)

    except Exception as e:
        return_error(
            f'Failed to execute {demisto.command()} command, Error: {e}. Traceback: {traceback.format_exc()}'
        )
Beispiel #27
0
def iocs_to_keep_time():
    hour, minute = demisto.getIntegrationContext().get('iocs_to_keep_time',
                                                       (0, 0))
    time_now = datetime.now(timezone.utc)
    return time_now.hour == hour and time_now.min == minute
from CommonServerUserPython import *
''' IMPORTS '''
import os
import requests
import json
from pancloud import LoggingService, Credentials
import base64
from cryptography.hazmat.primitives.ciphers.aead import AESGCM

# disable insecure warnings
requests.packages.urllib3.disable_warnings()

''' GLOBAL VARS '''
AUTH_ID = demisto.params().get('auth_id')
# If there's a stored token in integration context, it's newer than current
TOKEN = demisto.getIntegrationContext().get('token')
if not TOKEN:
    TOKEN = demisto.params().get('token')

ENC_KEY = demisto.params().get('auth_key')

USE_SSL = not demisto.params().get('insecure', False)
TOKEN_RETRIEVAL_URL = 'https://demistobot.demisto.com/panw-token'
FETCH_QUERY = None

FIRST_FETCH_TIMESTAMP = demisto.params().get('first_fetch_timestamp', '').strip()
if not FIRST_FETCH_TIMESTAMP:
    FIRST_FETCH_TIMESTAMP = '24 hours'

if not demisto.params().get('proxy', False):
    os.environ.pop('HTTP_PROXY', '')
Beispiel #29
0
def main():
    """
    PARSE AND VALIDATE INTEGRATION PARAMS
    """
    params = demisto.params()
    service_principal = params.get('credentials', {}).get('identifier')
    secret = params.get('credentials', {}).get('password')

    # Remove trailing slash to prevent wrong URL path to service
    server_url = params['url'][:-1] if (
        params['url'] and params['url'].endswith('/')) else params['url']
    api_version = params.get('api_version')

    verify_certificate = not params.get('insecure', False)
    # How many time before the first fetch to retrieve incidents
    fetch_time = params.get('fetch_time', '60 minutes')

    threat_status = argToList(params.get('threat_status'))

    threat_type = argToList(params.get('threat_type'))

    event_type_filter = params.get('events_type')

    fetch_limit = 50
    # Remove proxy if not set to true in params
    proxies = handle_proxy()

    command = demisto.command()
    LOG(f'Command being called is {command}')

    try:
        client = Client(server_url, api_version, verify_certificate,
                        service_principal, secret, proxies)
        commands = {
            'proofpoint-get-events': get_events_command,
            'proofpoint-get-forensics': get_forensic_command
        }
        if command == 'test-module':
            results = test_module(client, fetch_time, event_type_filter)
            return_outputs(results)

        elif demisto.command() == 'fetch-incidents':
            integration_context = demisto.getIntegrationContext()
            next_run, incidents, remained_incidents = fetch_incidents(
                client=client,
                last_run=demisto.getLastRun(),
                first_fetch_time=fetch_time,
                event_type_filter=event_type_filter,
                threat_status=threat_status,
                threat_type=threat_type,
                limit=fetch_limit,
                integration_context=integration_context)
            # Save last_run, incidents, remained incidents into integration
            demisto.setLastRun(next_run)
            demisto.incidents(incidents)
            # preserve context dict
            integration_context['incidents'] = remained_incidents
            demisto.setIntegrationContext(integration_context)

        elif command in commands:
            return_outputs(*commands[command](client, demisto.args()))

    except Exception as e:
        return_error(str(e))
Beispiel #30
0
def access_token_not_expired():
    epoch_time_now = time.time()
    epoch_time_when_token_granted = demisto.getIntegrationContext().get('access_token_creation_time')
    token_time_until_expiration = demisto.getIntegrationContext().get('access_token_expires_in')
    return int(epoch_time_now) - int(epoch_time_when_token_granted) < int(token_time_until_expiration)
Beispiel #31
0
        return_error("Failed to get query viewers:\nStatus Code: {}\nResponse: {}".format(res.status_code, res.text))

    res_json = res.json()
    if 'qvs.findAllIdsResponse' in res_json and 'qvs.return' in res_json.get('qvs.findAllIdsResponse'):
        query_viewers = res_json.get('qvs.findAllIdsResponse').get('qvs.return')

        contents = decode_arcsight_output(query_viewers)
        outputs = {'ArcSightESM.AllQueryViewers': contents}
        human_readable = tableToMarkdown(name='', t=query_viewers, headers='Query Viewers', removeNull=True)
        return_outputs(readable_output=human_readable, outputs=outputs, raw_response=contents)

    else:
        demisto.results('No Query Viewers were found')


AUTH_TOKEN = demisto.getIntegrationContext().get('auth_token') or login()
try:
    if demisto.command() == 'test-module':
        test()
        demisto.results('ok')

    elif demisto.command() == 'as-fetch-incidents' or demisto.command() == 'fetch-incidents':
        fetch()

    elif demisto.command() == 'as-get-matrix-data' or demisto.command() == 'as-get-query-viewer-results':
        get_query_viewer_results_command()

    elif demisto.command() == 'as-get-all-cases':
        get_all_cases_command()

    elif demisto.command() == 'as-get-case':
Beispiel #32
0
    path = engine_path + secret

    return send_request(path, 'get')


''' EXECUTION CODE '''

LOG('Executing command: ' + demisto.command())

if USERNAME and PASSWORD:
    TOKEN = login()
elif not TOKEN:
    return_error(
        'Either an authentication token or user credentials must be provided')

integ_context = demisto.getIntegrationContext()
if not integ_context or 'configs' not in integ_context:
    integ_context['configs'] = []

ENGINE_CONFIGS = integ_context['configs']

try:
    if demisto.command() == 'test-module':
        path = 'sys/health'
        send_request(path)
        demisto.results('ok')
    elif demisto.command() == 'fetch-credentials':
        fetch_credentials()
    elif demisto.command() == 'hashicorp-list-secrets-engines':
        list_secrets_engines_command()
    elif demisto.command() == 'hashicorp-list-secrets':
Beispiel #33
0
from CommonServerUserPython import *
from typing import Union, Optional


''' IMPORTS '''
import requests
import base64
import os
import binascii

# Disable insecure warnings
requests.packages.urllib3.disable_warnings()

""" GLOBALS/PARAMS """
# Global annotation
CONTEXT = demisto.getIntegrationContext()
DEMISTOBOT = 'https://demistobot.demisto.com/msg-mail-token'
# Credentials
TOKEN = demisto.params().get('token')
TENANT_ID = demisto.params().get('tenant_id')
# Remove trailing slash to prevent wrong URL path to service
URL = demisto.params().get('url')
SERVER = URL[:-1] if (URL and URL.endswith('/')) else URL
# Should we use SSL
USE_SSL = not demisto.params().get('unsecure', False)
# Service base URL
BASE_URL = str(SERVER) + '/v1.0'

# Remove proxy if not set to true in params
if not demisto.params().get('proxy'):
    os.environ.pop('HTTP_PROXY', '')
    def get_access_token(self,
                         resource: str = '',
                         scope: Optional[str] = None):
        """
        Obtains access and refresh token from oproxy server or just a token from a self deployed app.
        Access token is used and stored in the integration context
        until expiration time. After expiration, new refresh token and access token are obtained and stored in the
        integration context.

        Args:
            scope: A scope to get instead of the default on the API.

        Returns:
            str: Access token that will be added to authorization header.
        """
        integration_context = demisto.getIntegrationContext()
        refresh_token = integration_context.get('current_refresh_token', '')
        # Set keywords. Default without the scope prefix.
        access_token_keyword = f'{scope}_access_token' if scope else 'access_token'
        valid_until_keyword = f'{scope}_valid_until' if scope else 'valid_until'

        if self.multi_resource:
            access_token = integration_context.get(resource)
        else:
            access_token = integration_context.get(access_token_keyword)

        valid_until = integration_context.get(valid_until_keyword)

        if access_token and valid_until:
            if self.epoch_seconds() < valid_until:
                return access_token

        auth_type = self.auth_type
        if auth_type == OPROXY_AUTH_TYPE:
            if self.multi_resource:
                for resource_str in self.resources:
                    access_token, expires_in, refresh_token = self._oproxy_authorize(
                        resource_str)
                    self.resource_to_access_token[resource_str] = access_token
                    self.refresh_token = refresh_token
            else:
                access_token, expires_in, refresh_token = self._oproxy_authorize(
                    scope=scope)

        else:
            access_token, expires_in, refresh_token = self._get_self_deployed_token(
                refresh_token, scope=scope)
        time_now = self.epoch_seconds()
        time_buffer = 5  # seconds by which to shorten the validity period
        if expires_in - time_buffer > 0:
            # err on the side of caution with a slightly shorter access token validity period
            expires_in = expires_in - time_buffer
        valid_until = time_now + expires_in
        integration_context.update({
            access_token_keyword: access_token,
            valid_until_keyword: valid_until,
            'current_refresh_token': refresh_token
        })

        # Add resource access token mapping
        if self.multi_resource:
            integration_context.update(self.resource_to_access_token)

        demisto.setIntegrationContext(integration_context)

        if self.multi_resource:
            return self.resource_to_access_token[resource]

        return access_token
Beispiel #35
0
def get_ioc_values_str_from_context() -> str:
    """
    Extracts output values from cache
    """
    cache_dict = demisto.getIntegrationContext()
    return cache_dict.get(EDL_VALUES_KEY, '')
Beispiel #36
0
def mirror_investigation():
    """
    Updates the integration context with a new or existing mirror.
    """
    mirror_type = demisto.args().get('type', 'all')
    auto_close = demisto.args().get('autoclose', 'true')
    mirror_direction = demisto.args().get('direction', 'both')
    mirror_to = demisto.args().get('mirrorTo', 'group')
    channel_name = demisto.args().get('channelName', '')
    channel_topic = demisto.args().get('channelTopic', '')
    kick_admin = bool(strtobool(demisto.args().get('kickAdmin', 'false')))

    investigation = demisto.investigation()

    if investigation.get('type') == PLAYGROUND_INVESTIGATION_TYPE:
        return_error('Can not perform this action in playground.')

    integration_context = demisto.getIntegrationContext()

    if not integration_context or not integration_context.get('mirrors', []):
        mirrors: list = []
    else:
        mirrors = json.loads(integration_context['mirrors'])
    if not integration_context or not integration_context.get(
            'conversations', []):
        conversations: list = []
    else:
        conversations = json.loads(integration_context['conversations'])

    investigation_id = investigation.get('id')
    users = investigation.get('users')
    slack_users = search_slack_users(users)
    send_first_message = False
    users_to_invite = list(map(lambda u: u.get('id'), slack_users))
    current_mirror = list(
        filter(lambda m: m['investigation_id'] == investigation_id, mirrors))
    channel_filter: list = []
    if channel_name:
        channel_filter = list(
            filter(lambda m: m['channel_name'] == channel_name, mirrors))

    if not current_mirror:
        channel_name = channel_name or 'incident-{}'.format(investigation_id)

        if not channel_filter:
            if mirror_to == 'channel':
                conversation = CHANNEL_CLIENT.channels_create(
                    name=channel_name).get('channel', {})
            else:
                conversation = CHANNEL_CLIENT.groups_create(
                    name=channel_name).get('group', {})

            conversation_name = conversation.get('name')
            conversation_id = conversation.get('id')
            conversations.append(conversation)

            send_first_message = True
        else:
            mirrored_channel = channel_filter[0]
            conversation_id = mirrored_channel['channel_id']
            conversation_name = mirrored_channel['channel_name']

        mirror = {
            'channel_id': conversation_id,
            'channel_name': conversation_name,
            'investigation_id': investigation.get('id'),
            'mirror_type': mirror_type,
            'mirror_direction': mirror_direction,
            'mirror_to': mirror_to,
            'auto_close': bool(strtobool(auto_close)),
            'mirrored': False
        }
    else:
        mirror = mirrors.pop(mirrors.index(current_mirror[0]))
        conversation_id = mirror['channel_id']
        if mirror_type:
            mirror['mirror_type'] = mirror_type
        if auto_close:
            mirror['auto_close'] = bool(strtobool(auto_close))
        if mirror_direction:
            mirror['mirror_direction'] = mirror_direction
        if mirror_to and mirror['mirror_to'] != mirror_to:
            return_error('Cannot change the Slack channel type from Demisto.')
        if channel_name:
            return_error('Cannot change the Slack channel name.')
        if channel_topic:
            return_error('Cannot change the Slack channel topic.')
        conversation_name = mirror['channel_name']
        mirror['mirrored'] = False

    set_topic = False
    if channel_topic:
        set_topic = True
    else:
        mirror_name = 'incident-{}'.format(investigation_id)
        channel_filter = list(
            filter(lambda m: m['channel_name'] == conversation_name, mirrors))
        if 'channel_topic' in mirror:
            channel_topic = mirror['channel_topic']
        elif channel_filter:
            channel_mirror = channel_filter[0]
            channel_topic = channel_mirror['channel_topic']
        else:
            channel_topic = ''
        mirrored_investigations_ids = list(
            map(lambda m: 'incident-{}'.format(m['investigation_id']),
                channel_filter))
        if not channel_topic or channel_topic.find('incident-') != -1:
            new_topic = ', '.join(mirrored_investigations_ids + [mirror_name])
            if channel_topic != new_topic:
                channel_topic = new_topic
                set_topic = True

    if set_topic:
        CHANNEL_CLIENT.conversations_setTopic(channel=conversation_id,
                                              topic=channel_topic)
    mirror['channel_topic'] = channel_topic

    if mirror_type != 'none':
        if integration_context.get('bot_id'):
            bot_id = integration_context['bot_id']
        else:
            bot_id = get_bot_id()
        users_to_invite += [bot_id]
        invite_users_to_conversation(conversation_id, users_to_invite)

        integration_context['bot_id'] = bot_id

    mirrors.append(mirror)

    set_to_latest_integration_context('mirrors', mirrors)
    set_to_latest_integration_context('conversations', conversations)

    if kick_admin:
        CHANNEL_CLIENT.conversations_leave(channel=conversation_id)
    if send_first_message:
        CLIENT.chat_postMessage(
            channel=conversation_id,
            text='This is the mirrored channel for incident {}.'.format(
                investigation_id))

    demisto.results('Investigation mirrored successfully, channel: {}'.format(
        conversation_name))
Beispiel #37
0
def main():
    os.environ['PAN_CREDENTIALS_DBFILE'] = os.path.join(gettempdir(), 'pancloud_credentials.json')
    params = demisto.params()
    registration_id_and_url = params.get(REGISTRATION_ID_CONST).split('@')
    if len(registration_id_and_url) != 2:
        token_retrieval_url = "https://oproxy.demisto.ninja"  # guardrails-disable-line
    else:
        token_retrieval_url = registration_id_and_url[1]
    registration_id = registration_id_and_url[0]
    # If there's a stored token in integration context, it's newer than current
    refresh_token = demisto.getIntegrationContext().get(REFRESH_TOKEN_CONST) or params.get(REFRESH_TOKEN_CONST)
    enc_key = params.get(ENCRYPTION_KEY_CONST)
    use_ssl = not params.get('insecure', False)
    proxy = params.get('proxy', False)
    client = Client(token_retrieval_url, registration_id, use_ssl, proxy, refresh_token, enc_key)
    args = demisto.args()
    fetch_table = params.get('fetch_table')
    fetch_fields = params.get('fetch_fields') or '*'

    command = demisto.command()
    LOG(f'command is {command}')
    try:
        if command == 'test-module':
            test_module(client, fetch_table, fetch_fields, params.get('isFetch'))
        elif command == 'cdl-query-logs':
            return_outputs(*query_logs_command(args, client))
        elif command == 'cdl-get-critical-threat-logs':
            return_outputs(*get_critical_logs_command(args, client))
        elif command == 'cdl-get-social-applications':
            return_outputs(*get_social_applications_command(args, client))
        elif command == 'cdl-search-by-file-hash':
            return_outputs(*search_by_file_hash_command(args, client))
        elif command == 'cdl-query-traffic-logs':
            return_outputs(*query_traffic_logs_command(args, client))
        elif command == 'cdl-query-threat-logs':
            return_outputs(*query_threat_logs_command(args, client))
        elif command == 'cdl-query-url-logs':
            return_outputs(*query_url_logs_command(args, client))
        elif command == 'cdl-query-file-data':
            return_outputs(*query_file_data_command(args, client))
        elif command == 'fetch-incidents':
            first_fetch_timestamp = params.get('first_fetch_timestamp', '24 hours').strip()
            fetch_severity = params.get('firewall_severity')
            fetch_table = params.get('fetch_table')
            fetch_fields = params.get('fetch_fields') or '*'
            fetch_subtype = params.get('firewall_subtype')
            fetch_limit = params.get('limit')
            last_run = demisto.getLastRun()
            next_run, incidents = fetch_incidents(client,
                                                  first_fetch_timestamp,
                                                  fetch_severity,
                                                  fetch_table,
                                                  fetch_subtype,
                                                  fetch_fields,
                                                  fetch_limit,
                                                  last_run)
            demisto.setLastRun(next_run)
            demisto.incidents(incidents)
    except Exception as e:
        error_message = str(e)
        return_error(error_message)
Beispiel #38
0
def main():
    params = demisto.params()
    args = demisto.args()
    url = params.get("url")
    collection_to_fetch = params.get("collection_to_fetch")
    credentials = params.get("credentials") or {}
    username = credentials.get("identifier")
    password = credentials.get("password")
    proxies = handle_proxy()
    verify_certificate = not params.get("insecure", False)
    skip_complex_mode = COMPLEX_OBSERVATION_MODE_SKIP == params.get(
        "observation_operator_mode")
    feed_tags = argToList(params.get("feedTags"))
    tlp_color = params.get('tlp_color', '')

    initial_interval = params.get("initial_interval")
    fetch_full_feed = params.get("fetch_full_feed") or False
    limit = try_parse_integer(params.get("limit") or -1)
    limit_per_request = try_parse_integer(params.get("limit_per_request"))

    command = demisto.command()
    demisto.info(f"Command being called in {CONTEXT_PREFIX} is {command}")
    try:
        client = Taxii2FeedClient(url=url,
                                  collection_to_fetch=collection_to_fetch,
                                  proxies=proxies,
                                  verify=verify_certificate,
                                  skip_complex_mode=skip_complex_mode,
                                  username=username,
                                  password=password,
                                  tags=feed_tags,
                                  limit_per_request=limit_per_request,
                                  tlp_color=tlp_color)
        client.initialise()
        commands = {
            "taxii2-reset-fetch-indicators": reset_fetch_command,
            "taxii2-get-indicators": get_indicators_command,
            "taxii2-get-collections": get_collections_command,
        }

        if demisto.command() == "test-module":
            # This is the call made when pressing the integration Test button.
            module_test_command(client, limit, fetch_full_feed)

        elif demisto.command() == "fetch-indicators":
            if fetch_full_feed:
                limit = -1
            integration_ctx = demisto.getIntegrationContext() or {}
            (indicators, integration_ctx) = fetch_indicators_command(
                client,
                initial_interval,
                limit,
                integration_ctx,
                fetch_full_feed,
            )
            for iter_ in batch(indicators, batch_size=2000):
                demisto.createIndicators(iter_)

            demisto.setIntegrationContext(integration_ctx)
        else:
            return_results(commands[command](client,
                                             **args))  # type: ignore[operator]

    except Exception as e:
        err_msg = f"Failed to execute {command} command. Error: {str(e)}\n\ntraceback: {traceback.format_exc()}"
        if isinstance(e, requests.exceptions.SSLError):
            LOG(err_msg)
            err_msg = (
                "Encountered an HTTPS certificate error. This error can be ignored by enabling "
                '"Trust any certificate (not secure)" in the instance configuration.'
            )
        return_error(err_msg)