def perform_add_to_campaign(ids, action):
    demisto.debug('starting add to campaign')
    campaign_id = demisto.incident()['id']
    campaign_incident_context = demisto.executeCommand('getContext', {'id': campaign_id})
    demisto.debug(f'got incident context: {campaign_incident_context}')

    if isError(campaign_incident_context):
        return_error(COMMAND_ERROR_MSG.format(action=action, ids=','.join(ids),
                                              error=get_error(campaign_incident_context)))

    incident_context = demisto.dt(campaign_incident_context, 'Contents.context.EmailCampaign.incidents')
    if isinstance(incident_context, dict) or isinstance(incident_context, str):
        incident_context = [incident_context]

    for incident_id in ids:
        search_path = f'Contents.context.EmailCampaign.LowerSimilarityIncidents(val.id=={incident_id})'
        similar_incident_data = demisto.dt(campaign_incident_context, search_path)

        if similar_incident_data:
            similar_incident_data = similar_incident_data[0]
            _add_campaign_to_incident(incident_id, campaign_id)

            # Add the incident to context under "incidents":
            incident_context.append(similar_incident_data)

    _remove_incident_from_lower_similarity_context(campaign_incident_context, ids)

    res = demisto.executeCommand('SetByIncidentId', {'key': 'EmailCampaign.incidents',
                                                     'value': incident_context})
    if is_error(res):
        return_error('Failed to change current context. Error details:\n{}'.format(get_error(res)))

    return COMMAND_SUCCESS.format(action=action, ids=','.join(ids))
Exemplo n.º 2
0
def fill_nested_fields(incidents_df: pd.DataFrame, incidents: List, *list_of_field_list: List[str],
                       keep_unique_value=False) -> \
        pd.DataFrame:
    """
    Handle nested fields by concatening values for each sub list of the field
    :param incidents_df: DataFrame of incidents
    :param incidents: List of incident
    :param list_of_field_list: field which can be nested. Can be also no nested field and will remain the same
    :return: DataFrame with nested field columns updated
    """
    for field_type in list_of_field_list:
        for field in field_type:
            if '.' in field:
                if isinstance(incidents, list):
                    value_list = [wrapped_list(demisto.dt(incident, field)) for incident in incidents]
                    if not keep_unique_value:
                        value_list = [' '.join(  # type: ignore
                            set(
                                list(
                                    filter(lambda x: x not in ['None', None, 'N/A'], x)
                                )
                            )
                        )
                            for x in value_list]
                    else:
                        value_list = [most_frequent(list(filter(lambda x: x not in ['None', None, 'N/A'], x)))
                                      for x in value_list]
                else:
                    value_list = wrapped_list(demisto.dt(incidents, field))
                    value_list = ' '.join(  # type: ignore
                        set(list(filter(lambda x: x not in ['None', None, 'N/A'], value_list))))  # type: ignore
                incidents_df[field] = value_list
    return incidents_df
Exemplo n.º 3
0
def fill_nested_fields(incidents_df: pd.DataFrame, incidents: pd.DataFrame, *list_of_field_list: List[str]) -> \
        pd.DataFrame:
    for field_type in list_of_field_list:
        for field in field_type:
            if '.' in field:
                if isinstance(incidents, list):
                    value_list = [
                        wrapped_list(demisto.dt(incident, field))
                        for incident in incidents
                    ]
                    value_list = [
                        ' '.join(
                            set(
                                list(
                                    filter(
                                        lambda x: x not in
                                        ['None', None, 'N/A'], x))))
                        for x in value_list
                    ]
                else:
                    value_list = wrapped_list(demisto.dt(incidents, field))
                    value_list = ' '.join(  # type: ignore
                        set(
                            list(
                                filter(
                                    lambda x: x not in ['None', None, 'N/A'],
                                    value_list))))  # type: ignore
                incidents_df[field] = value_list
    return incidents_df
Exemplo n.º 4
0
def query_command():
    relevance = demisto.args().get('relevance')
    results = query(relevance)

    if results is None:
        demisto.results('No results')
        sys.exit(0)

    output = demisto.dt(results, 'Result.Answer.#text')
    if not isinstance(output, list):
        output = [output]

    demisto.results({
        'Type':
        entryTypes['note'],
        'ContentsFormat':
        formats['json'],
        'Contents':
        results,
        'HumanReadable':
        tableToMarkdown('Query Results: {}'.format(relevance), output,
                        ['Results']),
        'EntryContext': {
            'Bigfix.QueryResults': output
        }
    })
Exemplo n.º 5
0
    def template_params(self, paramsStr):
        """
        Translate the template params if they exist from the context
        """
        actualParams = {}
        if paramsStr:
            try:
                params = json.loads(paramsStr)

            except ValueError as e:
                return_error('Unable to parse templateParams: {}'.format(
                    str(e)))
            # Build a simple key/value

            for p in params:
                if params[p].get('value'):
                    actualParams[p] = params[p]['value']

                elif params[p].get('key'):
                    actualParams[p] = demisto.dt(demisto.context(),
                                                 params[p]['key'])

            return actualParams

        else:
            return None
Exemplo n.º 6
0
def delete_group_command(client: MsGraphClient,
                         args: Dict) -> Tuple[str, Dict, Dict]:
    """Delete a group by group id and return outputs in Demisto's format

    Args:
        client: Client object with request
        args: Usually demisto.args()

    Returns:
        Outputs.
    """
    group_id = str(args.get('group_id'))
    client.delete_group(group_id)

    # get the group data from the context
    group_data = demisto.dt(
        demisto.context(),
        f'{INTEGRATION_CONTEXT_NAME}(val.ID === "{group_id}")')
    if isinstance(group_data, list):
        group_data = group_data[0]

    # add a field that indicates that the group was deleted
    group_data['Deleted'] = True  # add a field with the members to the group
    entry_context = {
        f'{INTEGRATION_CONTEXT_NAME}(val.ID === obj.ID)': group_data
    }

    human_readable = f'Group: "{group_id}" was deleted successfully.'
    return human_readable, entry_context, NO_OUTPUTS
Exemplo n.º 7
0
def delete_ticket_command(client, args) -> Tuple[str, dict, dict]:
    """Function which deleted a specific ticket by ticket id.
        Args:
            client : Integretion client which communicates with the api.
            args: Users arguments of the command.
       Returns:
           human readable, context, raw response of this command.
    """
    ticket_id = args.get('ticket_id')
    try:
        response = client.delete_ticket_request(ticket_id)
    except Exception as e:
        raise DemistoException(e)
    if response.get('Result') == 'Success':
        context = {}
        old_context = demisto.dt(demisto.context(),
                                 f'QuestKace.Ticket(val.ID === {ticket_id})')
        if old_context:
            if isinstance(old_context, list):
                old_context = old_context[0]
            old_context['IsDeleted'] = True
            context = {'QuestKace.Ticket(val.ID === obj.ID)': old_context}
        return f'Ticket was deleted successfully. Ticket number {ticket_id}', context, {}
    else:
        raise DemistoException('Error while deleting the ticket.')
Exemplo n.º 8
0
def policy_delete_command(client: AzureWAFClient, **args: Dict[str, str]):
    """
    Gets a policy name and resource group (or taking instance's default)
    and delete the policy from the resource group.
    """
    policy_name = str(args.get('policy_name', ''))
    resource_group_name = str(
        args.get('resource_group_name', client.resource_group_name))

    # policy_path is unique and used as unique id in the product.
    policy_id = f'/{SUBSCRIPTION_PATH.format(client.subscription_id)}/' \
                f'{RESOURCE_PATH.format(resource_group_name)}/{POLICY_PATH}/{policy_name}'
    status = client.delete_policy(policy_name, resource_group_name)
    md = ""
    context = None

    if status.status_code in [200, 202]:
        old_context = demisto.dt(demisto.context(),
                                 f'AzureWAF.Policy(val.id === "{policy_id}")')

        # updating the context with deleted policy.
        if old_context:
            if isinstance(old_context, list):
                old_context = old_context[0]
            old_context['IsDeleted'] = True
            context = {'AzureWAF.Policy(val.id === obj.id)': old_context}

        md = f"Policy {policy_name} was deleted successfully."

    if status.status_code == 204:
        md = f"Policy {policy_name} was not found."

    return CommandResults(outputs=context, readable_output=md)
Exemplo n.º 9
0
    def get(self,
            key: Optional[str],
            node: Optional[Any] = None,
            ignore_errors=False) -> Any:
        """ Get the context value given the key

        :param key: The dt expressions (string within ${}).
        :param node: The current node.
        :param ignore_errors: Set to True to ignore errors, otherwise False.
        :return: The value.
        """
        if key is not None:
            dx = self.__demisto
            if key != '..' and not key.startswith('..=') and key.startswith(
                    '..'):
                dx = node
                key = key[2:]
            elif key != '.' and not key.startswith('.=') and key.startswith(
                    '.'):
                dx = self.__value
                key = key[1:]

            if not key or key == '.':
                return dx
            try:
                return demisto.dt(dx, key)
            except Exception:
                if not ignore_errors:
                    raise
        return None
Exemplo n.º 10
0
def file_upload_raw(body, file_entry_id, filename_to_upload):
    uri = 'php/fileupload.php'
    if not filename_to_upload:  # first priority for the file name is user's argument
        # second priority for the file name is the file name in the context
        filename_dq = demisto.dt(
            demisto.context(), 'File(val=val.EntryID=="' + file_entry_id + '")=val.Name')
        if filename_dq and filename_dq[0]:
            filename_to_upload = filename_dq
        else:
            # last priority for the file name is demisto's entryID
            filename_to_upload = file_entry_id

    with open(demisto.getFilePath(file_entry_id)['path'], 'rb') as file_to_upload:
        file_up = {'amas_filename': file_to_upload}
        result = http_request(
            uri,
            'post',
            API_HEADERS,
            body,
            '',
            files=file_up,
        )

    if not result['success']:
        return_error('Failed to upload sample due to: ' + result['errorMessage'])
    return result
Exemplo n.º 11
0
def list_members_command(client: MsGraphClient,
                         args: Dict) -> Tuple[str, Dict, Dict]:
    """List a group members by group id. return outputs in Demisto's format.

    Args:
        client: Client object with request
        args: Usually demisto.args()

    Returns:
        Outputs.
    """
    group_id = str(args.get('group_id'))
    next_link = args.get('next_link')
    top = args.get('top')
    filter_ = args.get('filter')
    members = client.list_members(group_id, next_link, top, filter_)

    if not members['value']:
        human_readable = f'The group {group_id} has no members.'
        return human_readable, NO_OUTPUTS, NO_OUTPUTS

    members_readable, members_outputs = parse_outputs(members['value'])

    # get the group data from the context
    group_data = demisto.dt(
        demisto.context(),
        f'{INTEGRATION_CONTEXT_NAME}(val.ID === "{group_id}")')
    if not group_data:
        return_error(
            'Could not find group data in the context, please run "!msgraph-groups-get-group" to retrieve group data.'
        )
    if isinstance(group_data, list):
        group_data = group_data[0]

    if '@odata.nextLink' in members:
        next_link_response = members['@odata.nextLink']
        group_data[
            'Members'] = members_outputs  # add a field with the members to the group
        group_data['MembersNextLink'] = next_link_response
        entry_context = {
            f'{INTEGRATION_CONTEXT_NAME}(val.ID === obj.ID)': group_data
        }
        title = f'Group {group_id} members ' \
                f'(Note that there are more results. Please use the next_link argument to see them. The value can be ' \
                f'found in the context under {INTEGRATION_CONTEXT_NAME}.MembersNextLink): '
    else:
        group_data[
            'Members'] = members_outputs  # add a field with the members to the group
        entry_context = {
            f'{INTEGRATION_CONTEXT_NAME}(val.ID === obj.ID)': group_data
        }
        title = f'Group {group_id} members:'

    human_readable = tableToMarkdown(
        name=title,
        t=members_readable,
        headers=['ID', 'Display Name', 'Job Title', 'Mail'],
        removeNull=True)

    return human_readable, entry_context, members
Exemplo n.º 12
0
def domain_delete_command(client: Client, args: dict) -> CommandResults:
    """
    :param client: Cisco Umbrella Client for the api request.
    :param args: args from the user for the command.
    :returns (str) confirmation or error regarding deleting a domain.
    """
    response = {}
    domain_name = args.get('name', '')
    domain_id = args.get('id', '')
    if not domain_name and not domain_id:
        raise DemistoException(
            'Both domain name and domain id do not exist, Please supply one of them in order to set the domain to '
            'delete command')
    try:
        response = client.delete_domains(domain_id=domain_id,
                                         domain_name=domain_name)
    except Exception as e:
        # When deleting a domain by id and the id does not exist.
        if any(exp in str(e)
               for exp in ["Domain not in domain list", "Not Found"]):
            return CommandResults(
                readable_output=
                'The domain was not found in the list, Please insert an existing domain name or id.'
            )
    if domain_name:
        curr_context = demisto.dt(
            demisto.context(),
            f'UmbrellaEnforcement.Domains(val.name == "{domain_name}")')
    else:
        curr_context = demisto.dt(
            demisto.context(),
            f'UmbrellaEnforcement.Domains(val.id == "{domain_id}")')

    if curr_context:
        if isinstance(curr_context, list):
            curr_context = curr_context[0]
        curr_context['IsDeleted'] = True
    if response and int(response.status_code) == 204:  # type: ignore
        message = f"{domain_name if domain_name else domain_id} domain was removed from blacklist"
    else:
        # When deleting a domain by name, if name does not exist the returned code is 200 but the response is empty.
        message = f"{domain_name if domain_name else domain_id} domain not in the blacklist or Error"
    return CommandResults(readable_output=message,
                          outputs_prefix='UmbrellaEnforcement.Domains',
                          outputs_key_field='id',
                          outputs=curr_context)
Exemplo n.º 13
0
def extract_dt(dtstr: str, dx: Optional[Dict[str, Any]]) -> Any:
    """ Extract dt expression

      :param dtstr: The dt expressions (string within ${}).
      :param dx: The demisto context.
      :return: The value extracted.
    """
    return demisto.dt(dx, dtstr) if dx else dtstr
Exemplo n.º 14
0
def build_grid(context_path: str, keys: List[str], columns: List[str],
               unpack_nested_elements: bool) -> pd.DataFrame:
    """ Build new DateFrame from current context retrieved by DT.
        There are 3 cases:
            1. DT returns dict - In this case we will insert it in the table as key, value in each row.
            2. DT returns list - In this case each entry in the list will represent a row.
            3. DT return unknown obj (str..) - return empty list.

    Args:
        context_path: DT context path.
        keys: Keys to be included
        columns: Grid columns name.
        unpack_nested_elements: True for unpacking nested elements, False otherwise.

    Returns:
        pd.DataFrame: New Table include data from Entry Context
    """
    # Retrieve entry context data
    entry_context_data = demisto.dt(demisto.context(), context_path)
    # Validate entry context structure
    data_type = validate_entry_context(context_path, entry_context_data, keys,
                                       unpack_nested_elements)

    demisto.debug('context object is valid. starting to build the grid.')
    # Building new Grid
    if unpack_nested_elements:
        # Handle entry context as dict, with unpacking of nested elements
        table = pd.DataFrame(
            unpack_all_data_from_dict(entry_context_data, keys, columns))
        table.rename(columns=dict(zip(table.columns, columns)), inplace=True)
    elif data_type == 'list':
        # Handle entry context as list of value
        table = pd.DataFrame(entry_context_data)
        table.rename(columns=dict(zip(table.columns, columns)), inplace=True)
    elif isinstance(entry_context_data, list):
        # Handle entry context as list of dicts
        entry_context_data = [
            filter_dict(item, keys, len(columns))
            for item in entry_context_data
        ]
        table = pd.DataFrame(entry_context_data)
        table.rename(columns=dict(zip(table.columns, columns)), inplace=True)
    elif isinstance(entry_context_data, dict):
        # Handle entry context key-value of primitive types option
        # If the keys arg is * it means we don't know which keys we have in the context - Will create key-value table.
        if keys == ['*']:
            entry_context_data = filter_dict(entry_context_data, keys).items()
            table = pd.DataFrame(entry_context_data, columns=columns[:2])
        else:
            entry_context_data = filter_dict(entry_context_data, keys)
            table = pd.DataFrame([entry_context_data])
            table.rename(columns=dict(zip(table.columns, columns)),
                         inplace=True)

    else:
        table = []

    return table
Exemplo n.º 15
0
    def get_file_details(self):
        file_path_data = demisto.getFilePath(demisto.args().get("entryID"))
        self.file_path = file_path_data.get('path')
        self.file_name = file_path_data.get('name')
        file_entry = demisto.dt(self.get_context(), "File(val.EntryID === '{}')".format(demisto.args().get('entryID')))
        if isinstance(file_entry, list):
            file_entry = file_entry[0]

        self.file_type = file_entry.get("Type")
def _remove_incident_from_lower_similarity_context(incident_context, incident_ids):
    lower_similarity_incident_context = demisto.dt(incident_context,
                                                   'Contents.context.EmailCampaign.LowerSimilarityIncidents')

    lower_similarity_incident_context = list(filter(
        lambda x: x.get('id') not in incident_ids, lower_similarity_incident_context))

    demisto.executeCommand('DeleteContext', {'key': 'EmailCampaign.LowerSimilarityIncidents'})

    res = demisto.executeCommand('SetByIncidentId', {'key': 'EmailCampaign.LowerSimilarityIncidents',
                                                     'value': lower_similarity_incident_context})
    if is_error(res):
        return_error('Failed to change context. Error details:\n{}'.format(get_error(res)))
Exemplo n.º 17
0
    def get_file_details(self):
        cmd_res = demisto.executeCommand('getFilePath', {'id': demisto.args().get("entryID")})
        file_res = cmd_res[0]
        if isError(file_res):
            file_res["Contents"] = "Error fetching entryID: " + file_res["Contents"]
            self.res = file_res
        else:  # Got file path:
            self.file_path = file_res.get('Contents').get('path')
            self.file_name = file_res.get('Contents').get('name')
            file = demisto.dt(demisto.context(), "File(val.EntryID === '{}')".format(demisto.args().get('entryID')))
            if isinstance(file, list):
                file = file[0]

            self.file_type = file.get("Type")
Exemplo n.º 18
0
def publish():
    now_utc = datetime.now(timezone.utc)
    object_id = demisto.getArg('object.id')
    roles = execute_command('getRoles', {})

    execute_command(
        'setThreatIntelReport',
        {
            'id': object_id,
            'xsoarReadOnlyRoles': demisto.dt(roles, 'DemistoRoles.name'),
            'reportstatus': 'Published',
            'published': now_utc.isoformat(),
        },
    )

    demisto.results('ok')
Exemplo n.º 19
0
    def get(self, key: Optional[str] = None,) -> Any:
        """ Get the context value given the key

        :param key: The dt expressions (string within ${})
        :return: The value.
        """
        if key is not None:
            dx = self.__demisto
            if key != '.' and key.startswith('.'):
                dx = self.__value
                key = key[1:]

            if not key or key == '.':
                return dx
            elif isinstance(dx, (list, dict)):
                return demisto.dt(dx, key)
        return None
Exemplo n.º 20
0
def template_params():
    """
    Translate the template params if they exist from the context
    """
    actualParams = {}
    paramsStr = demisto.getArg('templateParams')
    if paramsStr:
        try:
            params = json.loads(paramsStr)
        except ValueError as e:
            return_error_mail_sender('Unable to parse templateParams: %s' % (str(e)))
        # Build a simple key/value
        for p in params:
            if params[p].get('value'):
                actualParams[p] = params[p]['value']
            elif params[p].get('key'):
                actualParams[p] = demisto.dt(demisto.context(), params[p]['key'])
    return actualParams
Exemplo n.º 21
0
def concat_text_fields(data, target_field, text_fields):
    for d in data:
        text = ''
        for fields in text_fields:
            for field in fields.strip().split("|"):
                field = field.strip()
                if "." in field:
                    value = demisto.dt(d, field)
                    if type(value) is list and len(value) > 0:
                        value = value[0]
                else:
                    value = d.get(field) or d.get(field.lower(), '')
                if value and isinstance(value, str):
                    text += value
                    text += ' '
                    break
        text = text.strip()
        d[target_field] = text
    return data
Exemplo n.º 22
0
def hash_incident():
    args = demisto.args()
    fieldsToHash_list = args.pop('fieldsToHash', '').split(',')
    fieldsToHash_list = set([x.strip() for x in fieldsToHash_list if x])
    res = demisto.executeCommand('GetIncidentsByQuery', args)
    if is_error(res):
        return_error(get_error(res))
    else:
        entry = res[0]
        incident_list = json.loads(entry['Contents'])
        new_incident_list = []
        for incident in incident_list:
            for field in fieldsToHash_list:
                if field in incident:
                    incident[field] = hash_multiple(incident.get(field))
            new_ctx = {}
            context_keys = [x for x in demisto.args().get('contextKeys', '').split(",") if x]
            if context_keys:
                ctx = get_context(incident['id'])
            for key in context_keys:
                if key in ctx:
                    new_ctx[key] = demisto.dt(ctx, key)
            incident['context'] = new_ctx
            new_incident_list.append(incident)
    file_name = str(uuid.uuid4())
    output_format = args['outputFormat']
    if output_format == 'pickle':
        data_encoded = pickle.dumps(new_incident_list)
    elif output_format == 'json':
        data_encoded = json.dumps(new_incident_list)
    else:
        return_error("Invalid output format: %s" % output_format)
    entry = fileResult(file_name, data_encoded)
    entry['Contents'] = new_incident_list
    entry['HumanReadable'] = "Fetched %d incidents successfully by the query: %s" % (len(new_incident_list), args.get('query'))
    entry['EntryContext'] = {
        'HashIncidentsFields': {
            'Filename': file_name,
            'FileFormat': output_format,
        }
    }
    return entry
Exemplo n.º 23
0
def upload_file_command():
    ticket_type = get_table_name(demisto.args().get('ticket_type'))
    ticket_id = demisto.args()['id']
    file_id = demisto.args()['file_id']
    file_name = demisto.args().get('file_name',
                                   demisto.dt(demisto.context(), "File(val.EntryID=='" + file_id + "').Name"))
    file_name = file_name[0] if isinstance(file_name, list) else file_name

    res = upload_file(ticket_id, file_id, file_name, ticket_type)

    if not res or 'result' not in res or not res['result']:
        return_error('Unable to retrieve response')

    hr = {
        'Filename': res['result'].get('file_name'),
        'Download link': res['result'].get('download_link'),
        'System ID': res['result'].get('sys_id')
    }

    context = {
        'ID': ticket_id,
        'File': {}
    }
    context['File']['Filename'] = res['result'].get('file_name')
    context['File']['Link'] = res['result'].get('download_link')
    context['File']['SystemID'] = res['result'].get('sys_id')

    entry = {
        'Type': entryTypes['note'],
        'Contents': res,
        'ContentsFormat': formats['json'],
        'ReadableContentsFormat': formats['markdown'],
        'HumanReadable': tableToMarkdown('File uploaded successfully', hr),
        'EntryContext': {
            'ServiceNow.Ticket(val.ID===obj.ID)': context,
            'Ticket(val.ID===obj.ID)': context
        }
    }

    return entry
Exemplo n.º 24
0
def build_grid(context_path: str, keys: List[str],
               columns: List[str]) -> pd.DataFrame:
    """ Build new DateFrame from current context retrieved by DT.
        There is 3 cases:
            1. DT returns dict (list including 1 item only)- In this case we will insert it in the table as key,
            value each row.
            2. DT returns list - In this case each entry in the list will represent a row.
            3. DT return unknown obj (str..) - return empty list.

    Args:
        context_path: DT context path.
        keys: Keys to be included
        columns: Grid columns name.

    Returns:
        pd.DataFrame: New Table include data from Entry Context
    """
    # Retrieve entry context data
    entry_context_data = demisto.dt(demisto.context(), context_path)
    # Validate entry context structure
    validate_entry_context(entry_context_data, keys)
    # Building new Grid
    if len(entry_context_data) > 1:
        # Handle entry context list option
        entry_context_data = [
            filter_dict(item, keys, len(columns))
            for item in entry_context_data
        ]
        table = pd.DataFrame(entry_context_data)
        table.rename(columns=dict(zip(table.columns, columns)), inplace=True)
    elif len(entry_context_data) == 1 and isinstance(entry_context_data[0],
                                                     dict):
        # Handle entry context key-vlaue option
        entry_context_data = filter_dict(entry_context_data[0], keys).items()
        table = pd.DataFrame(entry_context_data, columns=columns[:2])
    else:
        table = []

    return table
Exemplo n.º 25
0
def map_scim(scim):
    try:
        scim = json.loads(scim)
    except Exception:
        pass
    if type(scim) != dict:
        raise Exception('Provided client data is not JSON compatible')

    mapping = {
        "userName": "******",
        "email": "emails(val.primary && val.primary==true).[0].value",
        "first_name": "name.givenName",
        "last_name": "name.familyName",
        "id": "id",
        "timezone": "timezone",
    }
    parsed_scim = dict()
    for k, v in mapping.items():
        try:
            parsed_scim[k] = demisto.dt(scim, v)
        except Exception:
            parsed_scim[k] = None
    return parsed_scim
Exemplo n.º 26
0
def search_destination_domains(client, organizationId, destinationListId,
                               domains):
    demisto.debug(f'domains: {domains}')
    page_limit, page, r = get_first_page_of_destinations(
        client, organizationId, destinationListId)

    destination_domains = []
    while r.get('meta').get('total') <= page_limit:
        if r.get('meta').get('total') == 0:
            # currently, r.meta.total continually returns 100 until the last page, where it will return a value <= 100
            # and will never return 0. but if it does, then it's likely the API changed
            uri = f'/{organizationId}/destinationlists/{destinationListId}/destinations'
            demisto.info(
                f'Unexpected "total" value of 0 returned from Umbrella {uri} API call'
            )
            break
        destination_domains += r.get('data')
        page += 1
        r = client.get_destinations(organizationId,
                                    destinationListId,
                                    params={
                                        'page': page,
                                        'limit': page_limit
                                    })

    destination_domains_found = []
    for domain in domains:
        if domain in demisto.dt(destination_domains, 'destination'):
            destination_domains_found += [
                d for d in destination_domains
                if d.get('destination') == domain
            ]
            demisto.debug(
                f'destination_domains_found: {destination_domains_found}')

    return destination_domains_found
Exemplo n.º 27
0
dt = get_arg_and_encode('dt')
pollingCommand = demisto.getArg('pollingCommand')
pollingCommandArgName = demisto.getArg('pollingCommandArgName')
tag = get_arg_and_encode('tag')
playbookId = ' playbookId="{}"'.format(demisto.getArg('playbookId') if 'playbookId' in demisto.args() else '')
interval = int(demisto.getArg('interval'))
timeout = int(demisto.getArg('timeout'))

args_names = demisto.getArg('additionalPollingCommandArgNames').strip()
args_values = get_arg_and_encode('additionalPollingCommandArgValues').strip()

if interval <= 0 or timeout <= 0:
    return_error("Interval and timeout must be positive numbers")

# Verify correct dt path (does not verify condition!)
if not demisto.dt(demisto.context(), dt):
    if not demisto.dt(demisto.context(), re.sub('\(.*\)', '', dt)):
        return_error("Incorrect dt path: no ids found")
    demisto.results("Warning: no ids matching the dt condition were found.\nVerify that the condition is correct and "
                    "that all ids have finished running.")
command_string = '''!GenericPollingScheduledTask pollingCommand="{0}" pollingCommandArgName="{1}"{2} ids="{3}" \
                    pendingIds="{4}" interval="{5}" timeout="{6}" tag="{7}" additionalPollingCommandArgNames="{8}" \
                    additionalPollingCommandArgValues="{9}"'''.format(pollingCommand, pollingCommandArgName, playbookId,
                                                                      ids.replace('"', r'\"'), dt.replace('"', r'\"'),
                                                                      interval, timeout, tag, args_names, args_values)
res = demisto.executeCommand("ScheduleCommand",
                             {
                                 'command': command_string,
                                 'cron': '*/{} * * * *'.format(interval),
                                 'times': 1
                             })
Exemplo n.º 28
0
def get_endpoint_details(computer_id):
    fullurl = BASE_URL + '/api/computer/{}'.format(computer_id)
    res = requests.get(fullurl,
                       auth=(USERNAME, PASSWORD),
                       verify=VERIFY_CERTIFICATE)

    if res.status_code < 200 or res.status_code >= 300:
        return_error(
            'Failed to get computer {}.\nRequest URL: {}\nStatusCode: {}\nResponse Body: {}'
            .format(computer_id, fullurl, res.status_code, res.content))

    raw_endpoint = json.loads(xml2json(res.content))
    if not raw_endpoint or 'BESAPI' not in raw_endpoint:
        return None

    raw_endpoint = demisto.get(raw_endpoint, 'BESAPI.Computer')

    endpoint = {
        'ID':
        get_first(
            demisto.dt(raw_endpoint,
                       'Property(val["@Name"] == "ID")=val["#text"]')),
        'Resource':
        demisto.get(raw_endpoint, '@Resource'),
        'LastReportTime':
        get_first(
            demisto.dt(
                raw_endpoint,
                'Property(val["@Name"] == "Last Report Time")=val["#text"]')),
        'ActiveDirectoryPath':
        get_first(
            demisto.dt(
                raw_endpoint,
                'Property(val["@Name"] == "Active Directory Path")=val["#text"]'
            )),
        'AgentType':
        get_first(
            demisto.dt(raw_endpoint,
                       'Property(val["@Name"] == "Agent Type")=val["#text"]')),
        'AgentVersion':
        get_first(
            demisto.dt(
                raw_endpoint,
                'Property(val["@Name"] == "Agent Version")=val["#text"]')),
        'BESRelaySelectionMethod':
        get_first(
            demisto.dt(
                raw_endpoint,
                'Property(val["@Name"] == "BES Relay Selection Method")=val["#text"]'
            )),
        'BESRelayServiceInstalled':
        get_first(
            demisto.dt(
                raw_endpoint,
                'Property(val["@Name"] == "BES Relay Selection Method")=val["#text"]'
            )),
        'BESRootServer':
        get_first(
            demisto.dt(
                raw_endpoint,
                'Property(val["@Name"] == "BES Root Server")=val["#text"]')),
        'BIOS':
        get_first(
            demisto.dt(raw_endpoint,
                       'Property(val["@Name"] == "BIOS")=val["#text"]')),
        'CPU':
        get_first(
            demisto.dt(raw_endpoint,
                       'Property(val["@Name"] == "CPU")=val["#text"]')),
        'ClientSettings':
        demisto.dt(raw_endpoint,
                   'Property(val["@Name"] == "Client Settings")=val["#text"]'),
        'ComputerName':
        get_first(
            demisto.dt(
                raw_endpoint,
                'Property(val["@Name"] == "Computer Name")=val["#text"]')),
        'ComputerType':
        get_first(
            demisto.dt(
                raw_endpoint,
                'Property(val["@Name"] == "Computer Type")=val["#text"]')),
        'DNSName':
        get_first(
            demisto.dt(raw_endpoint,
                       'Property(val["@Name"] == "DNS Name")=val["#text"]')),
        'IPAddress':
        get_first(
            demisto.dt(raw_endpoint,
                       'Property(val["@Name"] == "IP Address")=val["#text"]')),
        'DeviceType':
        get_first(
            demisto.dt(
                raw_endpoint,
                'Property(val["@Name"] == "Device Type")=val["#text"]')),
        'DistancetoBESRelay':
        get_first(
            demisto.dt(
                raw_endpoint,
                'Property(val["@Name"] == "Distance to BES Relay")=val["#text"]'
            )),
        'FreeSpaceonSystemDrive':
        get_first(
            demisto.dt(
                raw_endpoint,
                'Property(val["@Name"] == "Free Space on System Drive")=val["#text"]'
            )),
        'LicenseType':
        get_first(
            demisto.dt(
                raw_endpoint,
                'Property(val["@Name"] == "License Type")=val["#text"]')),
        'Locked':
        get_first(
            demisto.dt(raw_endpoint,
                       'Property(val["@Name"] == "Locked")=val["#text"]')),
        'OS':
        get_first(
            demisto.dt(raw_endpoint,
                       'Property(val["@Name"] == "OS")=val["#text"]')),
        'RAM':
        get_first(
            demisto.dt(raw_endpoint,
                       'Property(val["@Name"] == "RAM")=val["#text"]')),
        'Relay':
        get_first(
            demisto.dt(raw_endpoint,
                       'Property(val["@Name"] == "Relay")=val["#text"]')),
        'RelayNameOfClient':
        get_first(
            demisto.dt(
                raw_endpoint,
                'Property(val["@Name"] == "Relay Name of Client")=val["#text"]'
            )),
        'SubnetAddress':
        get_first(
            demisto.dt(
                raw_endpoint,
                'Property(val["@Name"] == "Subnet Address")=val["#text"]')),
        'SubscribedSites':
        get_first(
            demisto.dt(
                raw_endpoint,
                'Property(val["@Name"] == "Subscribed Sites")=val["#text"]')),
        'TotalSizeofSystemDrive':
        get_first(
            demisto.dt(
                raw_endpoint,
                'Property(val["@Name"] == "Total Size of System Drive")=val["#text"]'
            )),
        'UserName':
        get_first(
            demisto.dt(raw_endpoint,
                       'Property(val["@Name"] == "User Name")=val["#text"]'))
    }

    return endpoint
Exemplo n.º 29
0
def build_report_context(report_summary, upload_data, status, threshold, task_id):
    context = {}  # type: dict
    if report_summary and report_summary['Subject']:
        subject = report_summary['Subject']
        context = {
            'DBotScore': {
                'Vendor': 'McAfee Advanced Threat Defense',
                'Score': 0
            }
        }

        if 'FileType' in subject:
            context['DBotScore']['Indicator'] = subject['md5']
            context['DBotScore']['Type'] = 'hash'
            # default threshold for McAfee ATD is 3
            if report_summary['Verdict']['Severity'] > threshold:
                context['DBotScore']['Score'] = 3
                if subject['Type'] == 'application/url':
                    context['URL(val.Name == obj.Data)'] = {
                        'Type': subject['Type'],
                        'MD5': subject['md5'],
                        'SHA1': subject['sha-1'],
                        'SHA256': subject['sha-256'],
                        'Size': subject['size'],
                        'Name': subject['Name'],
                        'Malicious': {
                            'Vendor': 'McAfee Advanced Threat Defense',
                            'Description': 'Severity: ' + report_summary['Verdict']['Severity']
                        }
                    }
                else:
                    context['File(val.MD5 == obj.MD5)'] = {
                        'Type': subject['Type'],
                        'MD5': subject['md5'],
                        'SHA1': subject['sha-1'],
                        'SHA256': subject['sha-256'],
                        'Size': subject['size'],
                        'Name': subject['Name'],
                        'Malicious': {
                            'Vendor': 'McAfee Advanced Threat Defense',
                            'Description': 'Severity: ' + report_summary['Verdict']['Severity']
                        }
                    }
            else:
                context['DBotScore']['Score'] = 1

        else:  # detonation did not return any data
            # retrieve submission url by the task ID, if exist
            submission_dt = demisto.dt(
                demisto.context(), 'ATD.Task(val.taskId === "{}")'.format(task_id))
            if isinstance(submission_dt, list):
                submission = submission_dt[0]
            else:
                submission = submission_dt
            if isinstance(submission, dict):
                if submission.get('url') and len(str(submission.get('url'))) > 0:
                    context['DBotScore']['Type'] = 'application/url'
                    context['DBotScore']['Indicator'] = submission.get('url')
                else:  # if does not exist, submission is a file
                    if submission.get('SHA256') and len(str(submission.get('SHA256'))) > 0:
                        context['DBotScore']['Indicator'] = submission.get('SHA256')
                        context['DBotScore']['Type'] = 'hash'
                    elif submission.get('SHA1') and len(str(submission.get('SHA1'))) > 0:
                        context['DBotScore']['Indicator'] = submission.get('SHA1')
                        context['DBotScore']['Type'] = 'hash'

        context['IP'] = {}
        if 'Ips' in report_summary:
            ip_addresses = []
            for i in range(len(report_summary['Ips'])):
                ip_addresses.append(report_summary['Ips'][i]['Ipv4'])
            context['IP']['Address'] = ip_addresses

        if upload_data:
            context['ATD'] = {}
            context['ATD']['Task(val.taskId == obj.taskId)'] = {
                'status': status,
                'taskId': upload_data['taskId'],
                'jobId': upload_data['subId'] if 'subId' in upload_data else None,
                'messageId': upload_data['messageId'],
                'url': upload_data['url'],
                'srcIp': upload_data['srcIp'],
                'destIp': upload_data['destIp'],
                'MD5': upload_data['md5'],
                'SHA1': upload_data['sha1'],
                'SHA256': upload_data['sha256'],
                'Report': {
                    'Attachments': report_summary['Attachments'] if 'Attachment' in report_summary else None,
                    'Environment': report_summary['Environment'] if 'Environment' in report_summary else None,
                    'Ips': report_summary['Ips'] if 'Ips' in report_summary else None,
                    'Verdict': report_summary['Verdict'] if 'Verdict' in report_summary else None,
                    'Data': report_summary['Data'] if 'Data' in report_summary else None,
                    'Selectors': report_summary['Selectors'] if 'Selectors' in report_summary else None
                }
            }
    return context
Exemplo n.º 30
0
import demistomock as demisto  # noqa: F401
from CommonServerPython import *  # noqa: F401

args = demisto.args()
value = args["value"]
dt = args["dt"]

res = demisto.dt(value, dt)
return_results(encode_string_results(res))