예제 #1
0
def get_token():
    """
    Retrieve the token using the credentials
    """
    demisto_params = demisto.params()
    said = demisto_params.get('credentials').get('identifier')
    sasecret = demisto_params.get('credentials').get('password')
    auth_payload = parse.urlencode({
        'grant_type': 'client_credentials',
        'audience': 'beyond-api',
        'client_id': said,
        'client_secret': sasecret
    })
    response = requests.post("https://auth.wiz.io/oauth/token",
                             headers=HEADERS_AUTH,
                             data=auth_payload)

    if response.status_code != requests.codes.ok:
        raise Exception('Error authenticating to Wiz [%d] - %s' %
                        (response.status_code, response.text))
    try:

        response_json = response.json()
        TOKEN = response_json.get('access_token')
        if not TOKEN:
            demisto.debug(json.dumps(response_json))
            message = 'Could not retrieve token from Wiz: {}'.format(
                response_json.get("message"))
            raise Exception(message)
    except ValueError as exception:
        demisto.log(exception)  # pylint: disable=E9012
        raise Exception('Could not parse API response')
    HEADERS["Authorization"] = "Bearer " + TOKEN

    return TOKEN
예제 #2
0
def remove_identity_key(source):
    """
    this function removes identity key (application, device or user) from LastModifiedBy and CreatedBy keys and
    convert it to "type" key.
    :param source: LastModifiedBy and CreatedBy dictionaries
    :return: camel case dictionary with identity key as type.
    """
    if not isinstance(source, dict):
        LOG("Input is not dictionary. Exist function.")
        return source

    dict_keys = list(source.keys())
    if len(dict_keys) != 1:
        demisto.log("Got more then one identity creator. Exit function")
        return source

    identity_key = dict_keys[0]
    new_source = {}
    if source[identity_key].get("ID"):
        new_source["ID"] = source[identity_key].get("ID")

    new_source["DisplayName"] = source[identity_key].get("DisplayName")
    new_source["Type"] = identity_key

    return new_source
예제 #3
0
    def create_new_folder(self, object_type, object_type_id, parent_id, folder_name):
        """
        Create a new folder in a Drive with a specified parent item or path.
        :param object_type: ms graph resource.
        :param object_type_id: the selected object type id.
        :param parent_id: an ID of the Drive to upload the folder to.
        :param folder_name: folder name
        :return: graph api raw response
        """
        if object_type == "drives":
            url = f"{object_type}/{object_type_id}/items/{parent_id}/children"

        elif object_type in ["groups", "sites", "users"]:
            url = f"{object_type}/{object_type_id}/drive/items/{parent_id}/children"

        # send request
        url = self.base_url + f"/{url}"

        payload = {
            "name": folder_name,
            "folder": {},
            "@microsoft.graph.conflictBehavior": "rename",
        }
        self.headers["Content-Type"] = "application/json"
        demisto.log(f"sending POST to {url}, with the next payload: {payload}")
        return self.http_call(
            "POST", full_url=url, json_data=payload, headers=self.headers, url_suffix=""
        )
예제 #4
0
    def __status_and_id(self,
                        status_name: str = None,
                        status_id: str = None) -> Dict:
        """

        :param status_name: the status name for search (the status id)
        :param status_id: the status id for search (the status name)
        :return: {"name": <status name>, "id": <status id>}
        """
        if not status_id:
            looking_for = status_name if status_name else 'Open'
            looking_in = 'name'
        else:
            looking_for = status_id
            looking_in = 'id'
        if not self.__cache['status']:

            def filter_statuses_data(status_dict):
                try:
                    status_dict.pop('showInCasePane')
                    status_dict.pop('default')
                except KeyError:
                    pass
                return status_dict

            self.__cache['status'] = list(
                map(filter_statuses_data,
                    (self.get_case_statuses(raw=True))[2]))
        for status in self.__cache['status']:
            if status.get(looking_in) == looking_for:
                return status
        demisto.log(f'{looking_for} is not a {looking_in}(status).')
        return {}
예제 #5
0
def parse_tag_field(tags_str):
    tags = []
    regex = re.compile(
        r'key=([\w\d_:.-]+),value=([ /\w\d@_,.*-]+)', flags=re.I)
    if demisto.args().get('tag_key') and demisto.args().get('tag_value'):
        if demisto.args().get('tags'):
            return_error(
                "Please select either the arguments 'tag_key' and 'tag_value' or only 'tags'.")
        tags.append({
            'Key': demisto.args().get('tag_key'),
            'Value': demisto.args().get('tag_value')
        })
    else:
        if tags_str is not None:
            for f in tags_str.split(';'):
                match = regex.match(f)
                if match is None:
                    demisto.log('could not parse field: %s' % (f,))
                    continue

                tags.append({
                    'Key': match.group(1),
                    'Value': match.group(2)
                })

    return tags
예제 #6
0
def test_close_task_set_context(mocker):
    demisto.log('stuff')

    def executeCommand(name, args=None):
        if name == 'taskComplete':
            # Success
            return {}
        else:
            raise ValueError('Unimplemented command called: {}'.format(name))

    mocker.patch.object(demisto,
                        'args',
                        return_value={
                            "entry_id": "waiter",
                            "context_key": "XMatters.UserResponseOut",
                            "comments": "This is a comment"
                        })

    # mocker.patch.object(demisto, 'executeCommand', side_effect=executeCommand)
    mocker.patch.object(demisto, 'results')

    main()

    # If we got here we're good.
    assert True
예제 #7
0
    def __username_and_id(self,
                          user_name: str = None,
                          user_id: str = None) -> Dict:
        """

        :param user_name: the user name for search (the user id)
        :param user_id: the user id for search (the user name)
        :return: {"name": <user name>, "id": <user id>}
        """
        if user_name:
            if user_name.lower() == 'me':
                user_name = self.__user_name

            looking_in = 'username'
            looking_for = user_name
        elif user_id:
            looking_in = 'id'
            looking_for = user_id
        else:
            return {}

        if not self.__cache.get('users'):
            _, _, self.__cache['users'] = self.get_user_list()
        for user in self.__cache['users']:
            if user.get(looking_in) == looking_for:
                return {'id': user.get('id'), 'name': user.get('username')}

        demisto.log(f'{looking_for} is not a {looking_in}(user).')
        return {}
    def get_stats_archive(self, job_id):

        # Get firewall system name, serial number
        system_info = self.get_system_info()

        resp = xmltodict.parse(system_info.content)
        system_name = resp['response']['result']['system']['devicename']
        system_serial = resp['response']['result']['system']['serial']

        time_stamp = time.strftime(DATE_FORMAT)
        output_file = str(system_name) + '-' + str(system_serial) + '-' + str(
            time_stamp) + '-stats_dump.tar.gz'

        if self.params['ngfw_verbose'] is True:
            demisto.log('Constructed archive name as: [`' + output_file + '`]')

        params = {
            'type': 'export',
            'category': 'stats-dump',
            'action': 'get',
            'job-id': job_id,
            'key': self.api_key
        }

        response = self._http_request('GET',
                                      'api',
                                      params=params,
                                      resp_type='content',
                                      proxies=self.proxies,
                                      timeout=self.params['ngfw_timeout'])

        result = {'file_name': output_file, 'file_contents': response}

        return result
예제 #9
0
def main():
    try:
        args = demisto.args()
        pwd_generation_script = args.get("pwdGenerationScript")
        user_profile = args.get("userProfile")
        to_email = args.get("email")
        mapper_in = args.get("mapperIn", DEFAULT_OUTGOING_MAPPER)

        if not user_profile:
            # no user was created
            return

        # Generate a random password
        outputs = demisto.executeCommand(pwd_generation_script, {})
        password_dict = demisto.get(outputs[0], 'Contents')
        password = password_dict.get("NEW_PASSWORD")

        user = demisto.mapObject(json.loads(user_profile), mapper_in,
                                 MAPPING_TYPE)
        user_email = user.get("email")
        username = user_email.split("@")[0]
        display_name = user.get("displayname")

        # setting a new password
        ad_create_user_arguments = {
            'username': username,
            'password': password,
            'attribute-name': 'pwdLastSet',
            'attribute-value': -1
        }
        flow_worked = True

        password_outputs = demisto.executeCommand("ad-set-new-password",
                                                  ad_create_user_arguments)
        if is_error(password_outputs):
            flow_worked = False
            return_results(password_outputs)

        enable_outputs = demisto.executeCommand("ad-enable-account",
                                                ad_create_user_arguments)
        if is_error(enable_outputs):
            flow_worked = False
            return_results(enable_outputs)

        update_outputs = demisto.executeCommand("ad-update-user",
                                                ad_create_user_arguments)
        if is_error(update_outputs):
            flow_worked = False
            return_results(update_outputs)

        if flow_worked:
            send_email(display_name, username, user_email, password, to_email)
            return_results("User was enabled and a password was set.")
        else:
            return_results("Some commands failed, please check the errors.")

    except Exception as e:
        demisto.log(traceback.format_exc())
        return_error(str(e))
예제 #10
0
def portal_check():
    '''
    Poking to the portal to make sure it's up
    '''
    try:
        Portal(bearer=API_KEY)
        return True
    except Exception:
        demisto.log(traceback.format_exc())
        return False
def get_host_id_from_ip_address(ip_address):
    '''
        Get host ID within Frontline.Cloud given IP address.
        Host ID used to pull vulnerability data for that specific host.
    '''
    hosts_with_given_ip = get_fvm_data(HOST_ENDPOINT, params={'_0_eq_host_ip_address': str(ip_address)})
    if len(hosts_with_given_ip) < 1:
        msg = 'Host not found within Frontline.Cloud given host IP Address. Host will not be included in querying vulnerabilities'
        demisto.error('Frontline.Cloud get_host_id_from_ip_address -- ' + msg)  # print to demisto log in ERROR
        demisto.log('Frontline.Cloud get_host_id_from_ip_address -- ' + msg)    # print to war room
    first_relevant_host = hosts_with_given_ip[0]
    return first_relevant_host.get('id')
예제 #12
0
def parse_tag_field(tags_str):
    tags = []
    regex = re.compile(r'key=([\w\d_:.-]+),value=([ /\w\d@_,.\*-]+)',
                       flags=re.I)
    for f in tags_str.split(';'):
        match = regex.match(f)
        if match is None:
            demisto.log('could not parse field: %s' % (f, ))
            continue

        tags.append({'Key': match.group(1), 'Value': match.group(2)})
    return tags
예제 #13
0
def get_mssp_sub_accounts():
    account_id = demisto.getParam('credentials')['identifier']
    accounts = req('GET', 'public/v1/mssp/customers', json_response=True)
    if not accounts:
        return_error("intsights-mssp-get-sub-accounts failed to return data.")

    # Fix accounts _id keys
    for account in accounts:
        account["ID"] = account["_id"]
        del account["_id"]

    if len(accounts) < 1:
        return_error('Current MSSP Account has no sub accounts.')

    account_ids = [i["ID"] for i in accounts]
    if mssp_account_id not in account_ids:
        demisto.log("[DEBUG] - MSSP sub accounts:" + str(accounts))
        return_error(
            'Entered sub account id ({}) is not part of this mssp account'.
            format(mssp_account_id))

    for i, account in enumerate(account_ids):
        # Call account
        HEADERS['Account-Id'] = account
        account_ua = req('GET',
                         'public/v1/account/used-assets',
                         json_response=True)

        if not account_ua:
            continue

        accounts[i].update(account_ua)

    demisto.results({
        'Type':
        entryTypes['note'],
        'EntryContext': {
            'IntSights.MsspAccount(val.ID === obj.ID)': accounts
        },
        'HumanReadable':
        tableToMarkdown(
            'IntSights MSSP accounts used assets ' + account_id,
            [a for a in accounts],
            ["ID", 'CompanyName', "Status", "AssetsLimit", "AssetsCount"]),
        'Contents':
        accounts,
        'ContentsFormat':
        formats['json']
    })

    # Restore the header
    HEADERS['Account-Id'] = mssp_account_id
예제 #14
0
def parse_response(lst: list):
    """Convert a Api response to wanted format.
        Args:
            lst: A list of dictionaries that return from api call.
        Returns:
            converted list of dictionaries from snake case to camel case.
        """
    list_res = []
    for dic in lst:
        context_dict = convert_dict_snake_to_camel(dic)
        list_res.append(context_dict)
    demisto.log('log test')
    return list_res
예제 #15
0
def main():
    try:
        args = demisto.args()
        user_profile = args.get("value")

        title = user_profile.get("title")

        profile_id = title.get(title)
        return profile_id

    except Exception as e:
        demisto.log(traceback.format_exc())
        return_error(str(e))
예제 #16
0
def parse_subnet_mappings(subnets_str):
    subnets = []
    regex = re.compile(r"subnetid=([\w\d_:.-]+),allocationid=([ /\w\d@_,.*-]+)", flags=re.I)
    for f in subnets_str.split(';'):
        match = regex.match(f)
        if match is None:
            demisto.log('could not parse field: %s' % (f,))
            continue

        subnets.append({
            'SubnetId': match.group(1),
            'AllocationId': match.group(2)
        })
    return subnets
예제 #17
0
def main():
    """
        PARSE AND VALIDATE INTEGRATION PARAMS
    """
    params = demisto.params()

    base_url = params['url']
    api_key = params['api_key']

    # Flag if use server proxy
    use_proxy = params.get('proxy', False)

    # Flag if use server 'verification'
    insecure = not params.get('insecure', False)

    headers = {
        "Authorization":
        f"Bearer {api_key}"  # Replace ${token} with the token you have obtained
    }

    demisto.debug(" ---- MAIN CALL -----")
    demisto.debug(" ---- PARAMS -----")
    demisto.debug(f"base_url: {base_url}")
    demisto.debug(f"insecure: {insecure}")
    demisto.debug(f"use_proxy: {use_proxy}")

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

    client = Client(base_url=base_url,
                    headers=headers,
                    proxy=use_proxy,
                    verify=insecure)

    try:
        # This is the call made when pressing the integration Test button.
        if demisto.command() == 'test-module':
            return api_test(client)

        elif demisto.command() == 'cymptom-get-mitigations':
            return_results(get_mitigations(client))

        elif demisto.command() == 'cymptom-get-users-with-cracked-passwords':
            return_results(get_users_with_cracked_passwords(client))

    # Log exceptions
    except Exception as e:
        demisto.log(str(e))
        return_error(
            f'Failed to execute {demisto.command()} command. Error: {str(e)}')
예제 #18
0
def parse_filter_field(filter_str):
    filters = []
    regex = re.compile(r'name=([\w\d_:.-]+),values=([ /\w\d@_,.*-]+)',
                       flags=re.I)
    for f in filter_str.split(';'):
        match = regex.match(f)
        if match is None:
            demisto.log('could not parse filter: %s' % (f, ))
            continue

        filters.append({
            'Name': match.group(1),
            'Values': match.group(2).split(',')
        })

    return filters
예제 #19
0
def checkAPIerrors(query, variables):
    if not TOKEN:
        get_token()

    data = {"variables": variables, "query": query}

    try:
        result = requests.post(url=URL, json=data, headers=HEADERS)

    except Exception as e:
        if '502: Bad Gateway' not in str(e) and '503: Service Unavailable' not in str(e):
            demisto.error("<p>Wiz-API-Error: %s</p>" % str(e))
            return(e)
        else:
            demisto.log("Retry")

    return result.json()
예제 #20
0
def main():
    try:
        args = demisto.args()
        user_profile = args.get("value")

        location = user_profile.get("location")

        timezonesidkey = location_to_timezonesidkey.get(location)

        if not timezonesidkey:
            timezonesidkey = location_default

        return timezonesidkey

    except Exception as e:
        demisto.log(traceback.format_exc())
        return_error(str(e))
    def xmlapi_request_validate(self, response):

        # Load result into an XML object
        result = xmltodict.parse(response.content)

        # Get API response status
        status = result['response']['@status']

        if self.params['ngfw_verbose'] is True:
            demisto.log('Got execution status back from API: ' + str(status))
            demisto.log(str(response.text))

        if "success" in status:
            return True
        else:

            message = result['response']['msg']['line']

            raise Exception('API call encountered an error, received "' +
                            str(status) +
                            ' " as status code with error message: ' +
                            str(message))
예제 #22
0
def get_token():
    """
    Retrieve the token using the credentials
    """
    response = requests.post(URL + 'login',
                             headers=HEADERS,
                             verify=VERIFY,
                             json={
                                 'customerName':
                                 demisto.getParam('customer') or '',
                                 'username':
                                 demisto.getParam('credentials')['identifier'],
                                 'password':
                                 demisto.getParam('credentials')['password']
                             })

    if response.status_code != requests.codes.ok:  # pylint: disable=no-member
        raise Exception('Error authenticating to RedLock service [%d] - %s' %
                        (response.status_code, response.text))
    try:
        response_json = response.json()
        TOKEN = response_json.get('token')
        if not TOKEN:
            demisto.debug(json.dumps(response_json))
            message = 'Could not retrieve token from server: {}'.format(
                response_json.get("message"))
            if response_json.get('message') == 'login_needs_customer_name':
                available_customer_names = [
                    name.get('customerName')
                    for name in response_json.get('customerNames')
                ]
                message = 'In order to login a customer name need to be configured. Available customer names: {}'.format(
                    {", ".join(available_customer_names)})
            raise Exception(message)
    except ValueError as exception:
        demisto.log(exception)
        raise Exception('Could not parse API response.')
    HEADERS['x-redlock-auth'] = TOKEN
예제 #23
0
    def __org_and_id(self, org_name: str = None, org_id: str = None) -> Dict:
        """

        :param org_name: the org name for search (the org id)
        :param org_id: the org id for search (the org name)
        :return: {"name": <org name>, "id": <org id>}
        """
        if not org_id:
            if not org_name:
                org_name = 'None'

            looking_for = org_name
            looking_in = 'name'
        else:
            looking_for = org_id
            looking_in = 'id'
        if not self.__cache['org']:
            _, _, self.__cache['org'] = self.get_organization_list(raw=True)
        for org in self.__cache['org']:
            if org.get(looking_in) == looking_for:
                return org
        demisto.log(f'{looking_for} is not a {looking_in}(org).')
        return {}
def upload_stats_to_panw(csp, input_file):
    get_path = demisto.getFilePath(input_file)

    file_data = {
        'file_friendly_name': get_path.get('name'),
        'file_actual_name': get_path.get('path')
    }

    demisto.log('Got file name [' + file_data['file_friendly_name'] +
                '] as path [' + file_data['file_actual_name'] + ']')

    result = csp.upload_to_panw(file_data)

    send_to = demisto.params().get('slr_send_to')
    slr_id = result['Id']
    readable_output = 'Success! The SLR Report will be emailed to ' + str(
        send_to) + ' (SLR ID: `' + str(slr_id) + '`)'

    context = {'id': slr_id, 'send_to': send_to}

    return CommandResults(readable_output=readable_output,
                          outputs_prefix='AutoSLR.upload',
                          outputs_key_field=['id', 'send_to'],
                          outputs=context)
def ngfw_get_stats_dump_status(xmlapi, job_id):
    state = False

    while not state:
        demisto.log('Checking status for job ID: `' + str(job_id) + '`')

        result = xmlapi.get_stats_job_id_status(job_id)

        if 'FIN' in result['status']:
            state = True
        elif 'ACT' in result['status']:
            demisto.log('Job `' + str(job_id) +
                        '` is currently executing, current progress: `' +
                        result['progress'] + '%`')
        elif 'PEND' in result['status']:
            demisto.log(
                'Another job is currently executing, this job is currently in the queue'
            )
        else:
            raise Exception(
                'Unexpected value returned from API, expected [`ACT/FIN/PEND`] got: `'
                + str(result) + '`')

        time.sleep(1)

    if state is True:
        readable_output = 'Successfully finished executing stats_dump generation job for job ID: `' + str(
            job_id) + '`'

        return CommandResults(readable_output=readable_output,
                              outputs_prefix='AutoSLR.generate.job_status',
                              outputs_key_field='job_status',
                              outputs=state)

    else:
        raise Exception('Could not check stats_dump generation task [ID: `' +
                        str(job_id) + '`]')
    def upload_to_panw(self, file_data):
        file_handler = open(file_data['file_actual_name'], 'rb')

        file = {
            "files":
            (file_data['file_friendly_name'], file_handler, 'application/gzip')
        }

        payload = {
            "EmailIdList": self.slr_params['slr_send_to'],
            "RequestedBy": self.slr_params['slr_requested_by'],
            "PreparedBy": self.slr_params['slr_prepared_by'],
            "AccountName": self.slr_params['slr_account_name'],
            "Industry": self.slr_params['slr_industry'],
            "Country": self.slr_params['slr_country'],
            "GeographicRegion": self.slr_params['slr_geographic_region'],
            "DeploymentLocation": self.slr_params['slr_deployment_location'],
            "Language": self.slr_params['slr_language']
        }

        if self.params['csp_verbose'] is True:
            demisto.log('Upload -> Parameters -> [' + str(payload) + ']')
            demisto.log('Upload -> Files -> [' + str(file) + ']')

        demisto.log('Uploading ' + file_data['file_friendly_name'] +
                    ' to Palo Alto Networks...')

        response = self._http_request('POST',
                                      '/API/v1/Create/',
                                      data=payload,
                                      files=file,
                                      resp_type='json',
                                      proxies=self.proxies,
                                      timeout=self.params['csp_timeout'])

        return response
예제 #27
0
def remedy_update_ticket_command():
    demisto.log('TODO')
예제 #28
0
                    'Type':
                    entryTypes['error'],
                    'ContentsFormat':
                    formats['text'],
                    'Contents':
                    'More than one sensor returned.\nResult:\n' + str(matches)
                })
                sys.exit()
        else:
            demisto.results({
                'Type': entryTypes['error'],
                'ContentsFormat': formats['text'],
                'Contents': 'Sensor not found.'
            })
            sys.exit()
demisto.log('[*] Located sensor ID ' + sensorId)
# Get a live session to the endpoint
resSessions = demisto.executeCommand('cb-list-sessions', {})
if isError(resSessions[0]):
    demisto.results(resSessions)
    sys.exit()
else:
    existingSessions = [
        s for s in resSessions[0]['Contents']
        if str(s['sensor_id']) == sensorId
        and s['status'] in ['pending', 'active']
    ]
    if not existingSessions:
        resSessionCreate = demisto.executeCommand('cb-session-create',
                                                  {'sensor': sensorId})
        if isError(resSessionCreate[0]):
예제 #29
0
파일: URLScan.py 프로젝트: wjsetzer/content
def format_results(uuid):
    # Scan Lists sometimes returns empty
    scan_lists = None
    while scan_lists is None:
        try:
            response = urlscan_submit_request(uuid)
            scan_data = response['data']
            scan_lists = response['lists']
            scan_tasks = response['task']
            scan_page = response['page']
            scan_stats = response['stats']
            scan_meta = response['meta']
            url_query = scan_tasks['url']
        except Exception:
            pass

    ec = makehash()
    dbot_score = makehash()
    human_readable = makehash()
    cont = makehash()
    file_context = makehash()
    url_cont = makehash()

    LIMIT = int(demisto.args().get('limit'))
    if 'certificates' in scan_lists:
        cert_md = []
        cert_ec = []
        certs = scan_lists['certificates']
        for x in certs[:LIMIT]:
            info, ec_info = cert_format(x)
            cert_md.append(info)
            cert_ec.append(ec_info)
        CERT_HEADERS = ['Subject Name', 'Issuer', 'Validity']
        cont['Certificates'] = cert_ec
    url_cont['Data'] = url_query
    if 'urls' in scan_lists:
        url_cont['Data'] = demisto.args().get('url')
        cont['URL'] = demisto.args().get('url')
    # effective url of the submitted url
    human_readable['Effective URL'] = response['page']['url']
    cont['EffectiveURL'] = response['page']['url']
    if 'uuid' in scan_tasks:
        ec['URLScan']['UUID']
    if 'ips' in scan_lists:
        ip_asn_MD = []
        ip_ec_info = makehash()
        ip_list = scan_lists['ips']
        asn_list = scan_lists['asns']

        ip_asn_dict = dict(zip(ip_list, asn_list))
        i = 1
        for k in ip_asn_dict:
            if i - 1 == LIMIT:
                break
            v = ip_asn_dict[k]
            ip_info = {'Count': i, 'IP': k, 'ASN': v}
            ip_ec_info[i]['IP'] = k
            ip_ec_info[i]['ASN'] = v
            ip_asn_MD.append(ip_info)
            i = i + 1
        cont['RelatedIPs'] = ip_ec_info
        IP_HEADERS = ['Count', 'IP', 'ASN']
    # add redirected URLs
    if 'requests' in scan_data:
        redirected_urls = []
        demisto.log(str(scan_data['requests']))
        for o in scan_data['requests']:
            if 'redirectResponse' in o['request']:
                if 'url' in o['request']['redirectResponse']:
                    url = o['request']['redirectResponse']['url']
                    redirected_urls.append(url)
        cont['RedirectedURLs'] = redirected_urls
    if 'countries' in scan_lists:
        countries = scan_lists['countries']
        human_readable['Associated Countries'] = countries
        cont['Country'] = countries
    if None not in scan_lists['hashes']:
        hashes = scan_lists['hashes']
        cont['RelatedHash'] = hashes
        human_readable['Related Hashes'] = hashes
    if 'domains' in scan_lists:
        subdomains = scan_lists['domains']
        cont['Subdomains'] = subdomains
        human_readable['Subdomains'] = subdomains
    if 'asn' in scan_page:
        cont['ASN'] = scan_page['asn']
    if 'malicious' in scan_stats:
        human_readable['Malicious URLs Found'] = scan_stats['malicious']
        if int(scan_stats['malicious']) >= THRESHOLD:
            human_readable['Malicious'] = 'Malicious'
            url_cont['Data'] = demisto.args().get('url')
            cont['Data'] = demisto.args().get('url')
            dbot_score['Indicator'] = demisto.args().get('url')
            url_cont['Malicious']['Vendor'] = 'urlscan.io'
            cont['Malicious']['Vendor'] = 'urlscan.io'
            dbot_score['Vendor'] = 'urlscan.io'
            url_cont['Malicious'][
                'Description'] = 'Match found in Urlscan.io database'
            cont['Malicious'][
                'Description'] = 'Match found in Urlscan.io database'
            dbot_score['Score'] = 3
            dbot_score['Type'] = 'url'
        else:
            dbot_score['Vendor'] = 'urlscan.io'
            dbot_score['Indicator'] = demisto.args().get('url')
            dbot_score['Score'] = 0
            dbot_score['Type'] = 'url'
            human_readable['Malicious'] = 'Benign'
    if 'url' in scan_meta['processors']['gsb']['data'] is None:
        mal_url_list = []
        matches = scan_meta['processors']['gsb']['data']['matches']
        for match in matches:
            mal_url = match['threat']['url']
            mal_url_list.append(mal_url)
        human_readable['Related Malicious URLs'] = mal_url_list
    if len(scan_meta['processors']['download']['data']) > 0:
        meta_data = scan_meta['processors']['download']['data'][0]
        sha256 = meta_data['sha256']
        filename = meta_data['filename']
        filesize = meta_data['filesize']
        filetype = meta_data['mimeType']
        human_readable['File']['Hash'] = sha256
        cont['File']['Hash'] = sha256
        file_context['SHA256'] = sha256
        human_readable['File']['Name'] = filename
        cont['File']['FileName'] = filename
        file_context['Name'] = filename
        human_readable['File']['Size'] = filesize
        cont['File']['FileSize'] = filesize
        file_context['Size'] = filesize
        human_readable['File']['Type'] = filetype
        cont['File']['FileType'] = filetype
        file_context['Type'] = filetype
        file_context['Hostname'] = demisto.args().get('url')

    ec = {
        'URLScan(val.URL && val.URL == obj.URL)': cont,
        'DBotScore': dbot_score,
        'URL': url_cont,
        outputPaths['file']: file_context
    }

    if 'screenshotURL' in scan_tasks:
        human_readable['Screenshot'] = scan_tasks['screenshotURL']
        screen_path = scan_tasks['screenshotURL']
        response_img = requests.request("GET", screen_path)
        stored_img = fileResult('screenshot.png', response_img.content)

    demisto.results({
        'Type':
        entryTypes['note'],
        'ContentsFormat':
        formats['markdown'],
        'Contents':
        response,
        'HumanReadable':
        tableToMarkdown('{} - Scan Results'.format(url_query), human_readable),
        'EntryContext':
        ec
    })

    if len(cert_md) > 0:
        demisto.results({
            'Type':
            entryTypes['note'],
            'ContentsFormat':
            formats['markdown'],
            'Contents':
            tableToMarkdown('Certificates', cert_md, CERT_HEADERS),
            'HumanReadable':
            tableToMarkdown('Certificates', cert_md, CERT_HEADERS)
        })
    if 'ips' in scan_lists:
        demisto.results({
            'Type':
            entryTypes['note'],
            'ContentsFormat':
            formats['markdown'],
            'Contents':
            tableToMarkdown('Related IPs and ASNs', ip_asn_MD, IP_HEADERS),
            'HumanReadable':
            tableToMarkdown('Related IPs and ASNs', ip_asn_MD, IP_HEADERS)
        })

    if 'screenshotURL' in scan_tasks:
        demisto.results({
            'Type': entryTypes['image'],
            'ContentsFormat': formats['text'],
            'File': stored_img['File'],
            'FileID': stored_img['FileID'],
            'Contents': ''
        })
예제 #30
0
파일: URLScan.py 프로젝트: demisto/content
def format_results(uuid):
    # Scan Lists sometimes returns empty
    scan_lists = None
    while scan_lists is None:
        try:
            response = urlscan_submit_request(uuid)
            scan_data = response['data']
            scan_lists = response['lists']
            scan_tasks = response['task']
            scan_page = response['page']
            scan_stats = response['stats']
            scan_meta = response['meta']
            url_query = scan_tasks['url']
        except Exception:
            pass

    ec = makehash()
    dbot_score = makehash()
    human_readable = makehash()
    cont = makehash()
    file_context = makehash()
    url_cont = makehash()

    LIMIT = int(demisto.args().get('limit'))
    if 'certificates' in scan_lists:
        cert_md = []
        cert_ec = []
        certs = scan_lists['certificates']
        for x in certs[:LIMIT]:
            info, ec_info = cert_format(x)
            cert_md.append(info)
            cert_ec.append(ec_info)
        CERT_HEADERS = ['Subject Name', 'Issuer', 'Validity']
        cont['Certificates'] = cert_ec
    url_cont['Data'] = url_query
    if 'urls' in scan_lists:
        url_cont['Data'] = demisto.args().get('url')
        cont['URL'] = demisto.args().get('url')
    # effective url of the submitted url
    human_readable['Effective URL'] = response['page']['url']
    cont['EffectiveURL'] = response['page']['url']
    if 'uuid' in scan_tasks:
        ec['URLScan']['UUID']
    if 'ips' in scan_lists:
        ip_asn_MD = []
        ip_ec_info = makehash()
        ip_list = scan_lists['ips']
        asn_list = scan_lists['asns']

        ip_asn_dict = dict(zip(ip_list, asn_list))
        i = 1
        for k in ip_asn_dict:
            if i - 1 == LIMIT:
                break
            v = ip_asn_dict[k]
            ip_info = {
                'Count': i,
                'IP': k,
                'ASN': v
            }
            ip_ec_info[i]['IP'] = k
            ip_ec_info[i]['ASN'] = v
            ip_asn_MD.append(ip_info)
            i = i + 1
        cont['RelatedIPs'] = ip_ec_info
        IP_HEADERS = ['Count', 'IP', 'ASN']
    # add redirected URLs
    if 'requests' in scan_data:
        redirected_urls = []
        demisto.log(str(scan_data['requests']))
        for o in scan_data['requests']:
            if 'redirectResponse' in o['request']:
                if 'url' in o['request']['redirectResponse']:
                    url = o['request']['redirectResponse']['url']
                    redirected_urls.append(url)
        cont['RedirectedURLs'] = redirected_urls
    if 'countries' in scan_lists:
        countries = scan_lists['countries']
        human_readable['Associated Countries'] = countries
        cont['Country'] = countries
    if None not in scan_lists['hashes']:
        hashes = scan_lists['hashes']
        cont['RelatedHash'] = hashes
        human_readable['Related Hashes'] = hashes
    if 'domains' in scan_lists:
        subdomains = scan_lists['domains']
        cont['Subdomains'] = subdomains
        human_readable['Subdomains'] = subdomains
    if 'asn' in scan_page:
        cont['ASN'] = scan_page['asn']
    if 'malicious' in scan_stats:
        human_readable['Malicious URLs Found'] = scan_stats['malicious']
        if int(scan_stats['malicious']) >= THRESHOLD:
            human_readable['Malicious'] = 'Malicious'
            url_cont['Data'] = demisto.args().get('url')
            cont['Data'] = demisto.args().get('url')
            dbot_score['Indicator'] = demisto.args().get('url')
            url_cont['Malicious']['Vendor'] = 'urlscan.io'
            cont['Malicious']['Vendor'] = 'urlscan.io'
            dbot_score['Vendor'] = 'urlscan.io'
            url_cont['Malicious']['Description'] = 'Match found in Urlscan.io database'
            cont['Malicious']['Description'] = 'Match found in Urlscan.io database'
            dbot_score['Score'] = 3
            dbot_score['Type'] = 'url'
        else:
            dbot_score['Vendor'] = 'urlscan.io'
            dbot_score['Indicator'] = demisto.args().get('url')
            dbot_score['Score'] = 0
            dbot_score['Type'] = 'url'
            human_readable['Malicious'] = 'Benign'
    if 'url' in scan_meta['processors']['gsb']['data'] is None:
        mal_url_list = []
        matches = scan_meta['processors']['gsb']['data']['matches']
        for match in matches:
            mal_url = match['threat']['url']
            mal_url_list.append(mal_url)
        human_readable['Related Malicious URLs'] = mal_url_list
    if len(scan_meta['processors']['download']['data']) > 0:
        meta_data = scan_meta['processors']['download']['data'][0]
        sha256 = meta_data['sha256']
        filename = meta_data['filename']
        filesize = meta_data['filesize']
        filetype = meta_data['mimeType']
        human_readable['File']['Hash'] = sha256
        cont['File']['Hash'] = sha256
        file_context['SHA256'] = sha256
        human_readable['File']['Name'] = filename
        cont['File']['FileName'] = filename
        file_context['Name'] = filename
        human_readable['File']['Size'] = filesize
        cont['File']['FileSize'] = filesize
        file_context['Size'] = filesize
        human_readable['File']['Type'] = filetype
        cont['File']['FileType'] = filetype
        file_context['Type'] = filetype
        file_context['Hostname'] = demisto.args().get('url')

    ec = {
        'URLScan(val.URL && val.URL == obj.URL)': cont,
        'DBotScore': dbot_score,
        'URL': url_cont,
        outputPaths['file']: file_context
    }

    if 'screenshotURL' in scan_tasks:
        human_readable['Screenshot'] = scan_tasks['screenshotURL']
        screen_path = scan_tasks['screenshotURL']
        response_img = requests.request("GET", screen_path)
        stored_img = fileResult('screenshot.png', response_img.content)

    demisto.results({
        'Type': entryTypes['note'],
        'ContentsFormat': formats['markdown'],
        'Contents': response,
        'HumanReadable': tableToMarkdown('{} - Scan Results'.format(url_query), human_readable),
        'EntryContext': ec
    })

    if len(cert_md) > 0:
        demisto.results({
            'Type': entryTypes['note'],
            'ContentsFormat': formats['markdown'],
            'Contents': tableToMarkdown('Certificates', cert_md, CERT_HEADERS),
            'HumanReadable': tableToMarkdown('Certificates', cert_md, CERT_HEADERS)
        })
    if 'ips' in scan_lists:
        demisto.results({
            'Type': entryTypes['note'],
            'ContentsFormat': formats['markdown'],
            'Contents': tableToMarkdown('Related IPs and ASNs', ip_asn_MD, IP_HEADERS),
            'HumanReadable': tableToMarkdown('Related IPs and ASNs', ip_asn_MD, IP_HEADERS)
        })

    if 'screenshotURL' in scan_tasks:
        demisto.results({
            'Type': entryTypes['image'],
            'ContentsFormat': formats['text'],
            'File': stored_img['File'],
            'FileID': stored_img['FileID'],
            'Contents': ''
        })