Exemple #1
0
def on_finish(email, summary):
    setupkey = 'setup_data' + str(email['current_rule_run_id'])
    collectkey = 'collect_data' + str(email['current_rule_run_id'])
    email_to, email_from, smtp_asset = phantom.get_data(setupkey, clear_data=True)
    container_url = phantom.get_base_url() + 'container/' + str(email['id'])
    # calling get_summary to find out if we actually had anything we acted on
    getsummary = phantom.get_summary()
    #phantom.debug('Get summary: {}'.format(getsummary))
    #
    if len(getsummary['result']) > 0: # we have processed at least one item in on_start
        collected_results, collected_vault_items, container_owner = phantom.get_data(collectkey, clear_data=True)
        # finalize the vault item info and add to email
        for vaultid in collected_vault_items.keys():
            vaultinfo = phantom.get_vault_item_info(vaultid)
            for app_run_id, datavalues in collected_results.iteritems():
                #phantom.debug('iterate collected results: \napprunid: {}\n\ndatavals: {}'.format(app_run_id, datavalues))
                if datavalues['detonate_summary']['target'] == vaultid:
                    collected_results[app_run_id]['vault_info'] = vaultinfo
        if len(collected_results) < (len(getsummary['result'])-2): # subtracting actions that arent counted as detonations
            collected_results['message'] = "Unexpected: Collected Results: {} is less than actions run: {}".format(len(collected_results), (len(getsummary['result'])-2))
        # send summary email
        email_subject = "Results: Ingest file detonatation"
        email_body = '\nPhantom Container ID: {} - Owner: {}\nURL: {}\nReturned results by app_run_id:\n{}'.format(email['id'], container_owner, container_url, pprint.pformat(collected_results, indent=4))
        phantom.act('send email', parameters=[{ "from" : email_from,  "to" : email_to,  "subject" : email_subject,  "body" : email_body }], assets=[smtp_asset], callback=send_email_cb)
        phantom.debug("Summary: " + pprint.pformat(summary, indent=4))
    else: # no artifacts run on
        phantom.debug('No artifacts, sending abort email.')
        email_subject = "Results: No artifacts to run, aborting"
        email_body = '\nPhantom Container ID: {}\nURL: {} \nSummary:\n{}'.format(email['id'],container_url,summary)
        phantom.act('send email', parameters=[{ "from" : email_from,  "to" : email_to,  "subject" : email_subject,  "body" : email_body }], assets=[smtp_asset], callback=send_email_cb)
    return
Exemple #2
0
def on_finish(container, summary):
    phantom.debug('on_finish() called')
    # This function is called after all actions are completed.
    # summary of all the action and/or all detals of actions
    # can be collected here.

    # summary_json = phantom.get_summary()
    # if 'result' in summary_json:
    # for action_result in summary_json['result']:
    # if 'action_run_id' in action_result:
    # action_results = phantom.get_action_results(action_run_id=action_result['action_run_id'], result_data=False, flatten=False)
    # phantom.debug(action_results)

    qa_overall_result = phantom.get_data(key=keyfile, clear_data=False)
    qa_overall_result['message'] = qa_overall_result['message'] + '\n\n' + summary
    #

    #
    if qa_overall_result['qa_fail_count'] == 0:
        if expected_pass_count == qa_overall_result['qa_pass_count']:
            qa_overall_result['overall_result'] = 'Pass'  # set final pass/fail result in on_finish
    phantom.debug(
        'Overall Qa result: {} - Pass: {} - Fail: {} \nMessage: {}'.format(qa_overall_result['overall_result'],
                                                                           qa_overall_result['qa_pass_count'],
                                                                           qa_overall_result['qa_fail_count'],
                                                                           qa_overall_result['message'], ))
    phantom.save_data(qa_overall_result, key=keyfile)

    return
Exemple #3
0
def Format_End_Marker(action=None,
                      success=None,
                      container=None,
                      results=None,
                      handle=None,
                      filtered_artifacts=None,
                      filtered_results=None):
    phantom.debug('Format_End_Marker() called')

    playbook_info = phantom.get_playbook_info()
    guid = phantom.get_data(playbook_info[0]['id'], clear_data=False)
    phantom.debug(guid)

    template = "eventcreate /id 999 /D \"ended test for {0} guid=%s\" /T INFORMATION /L application" % guid

    # parameter list for template variable replacement
    parameters = [
        "Run_Start_Marker:action_result.parameter.ip_hostname",
    ]

    phantom.format(container=container,
                   template=template,
                   parameters=parameters,
                   name="Format_End_Marker")

    Run_End_Marker(container=container)

    return
Exemple #4
0
def Format_Start_Marker(action=None,
                        success=None,
                        container=None,
                        results=None,
                        handle=None,
                        filtered_artifacts=None,
                        filtered_results=None):
    phantom.debug('format_1() called')

    playbook_info = phantom.get_playbook_info()
    guid = phantom.get_data(playbook_info[0]['id'], clear_data=False)

    template = "eventcreate /id 999 /D \"started test on {0} guid=%s\" /T INFORMATION /L application" % guid

    # parameter list for template variable replacement
    parameters = ["artifact:*.cef.destinationAddress"]

    phantom.format(container=container,
                   template=template,
                   parameters=parameters,
                   name="Format_Start_Marker")

    Run_Start_Marker(container=container)

    return
def pin_1(action=None,
          success=None,
          container=None,
          results=None,
          handle=None,
          filtered_artifacts=None,
          filtered_results=None):
    import random
    phantom.debug('pin_1() called')

    # collect data for 'pin_to_hud_6' call
    dest_ip_artifacts = filter(
        lambda x: x[0],
        phantom.collect2(container=container,
                         datapath=['artifact:*.cef.destinationAddress']))
    sorc_ip_artifacts = filter(
        lambda x: x[0],
        phantom.collect2(container=container,
                         datapath=['artifact:*.cef.sourceAddress']))

    styles = set(["white", "red", "purple"])

    pin_name = pin_name_mangle("pin_1", container)
    pin_id = phantom.get_data(pin_name)

    if not pin_id:
        ret_val, message, pin_id = phantom.pin(
            container=container,
            message="Affected IPs",
            data=str(len(dest_ip_artifacts) + len(sorc_ip_artifacts)),
            pin_type="card_medium",
            pin_style="white")
        phantom.debug("new pin_1")
    else:
        style = random.sample(styles, 1)[0]
        phantom.debug(style)
        ret_val, message = phantom.update_pin(
            pin_id,
            message="Affected IPs",
            data=str(len(dest_ip_artifacts) + len(sorc_ip_artifacts)),
            pin_style=style)

    if ret_val:
        phantom.save_data(pin_id, pin_name)

    # set container properties for:
    update_data = {}

    phantom.update(container, update_data)

    return
def pin_2(action=None,
          success=None,
          container=None,
          results=None,
          handle=None,
          filtered_artifacts=None,
          filtered_results=None):
    import random
    phantom.debug('pin_2() called')

    # collect data for 'pin_to_hud_6' call
    dest_username = filter(
        lambda x: x[0],
        phantom.collect2(container=container,
                         datapath=['artifact:*.cef.destinationUserName']))
    sorc_username = filter(
        lambda x: x[0],
        phantom.collect2(container=container,
                         datapath=['artifact:*.cef.sourceUserName']))

    styles = set(["white", "red", "purple"])
    pin_name = pin_name_mangle("pin_2", container)
    pin_id = phantom.get_data(pin_name)

    if not pin_id:
        ret_val, message, pin_id = phantom.pin(
            container=container,
            message="Affected Users",
            data=str(len(dest_username) + len(sorc_username)),
            pin_type="card_medium",
            pin_style="purple")
        phantom.debug("new pin_2")
    else:
        # Delete and remake this one, for the sake of demonstration
        ret_val, message = phantom.delete_pin(pin_id)
        ret_val, message, pin_id = phantom.pin(
            container=container,
            message="Affected Users",
            data=str(len(dest_username) + len(sorc_username)),
            pin_type="card_medium",
            pin_style=random.sample(styles, 1)[0])

    if ret_val:
        phantom.save_data(pin_id, pin_name)
    # set container properties for:
    update_data = {}

    phantom.update(container, update_data)

    return
Exemple #7
0
def _save_data(qa_pass_count=0, qa_fail_count=0, qa_overall_result="Fail", message="", init=False, offset=0):
    if init:
        if message == "":
            message = 'At on_start'
        qa_overall_result = {'qa_pass_count': 0, 'qa_fail_count': 0, 'overall_result': 'Fail', 'message': message}
        phantom.save_data(qa_overall_result, key=keyfile)

    else:
        with padlock:
            qa_overall_result = phantom.get_data(key=keyfile, clear_data=False)
            if len(message) > 0:
                message = "{}():{}> {}".format(inspect.stack()[1 + offset][3], inspect.stack()[1 + offset][2], message)
                phantom.debug(message)
                qa_overall_result['message'] += "\n" + message
            qa_overall_result['qa_pass_count'] += qa_pass_count
            qa_overall_result['qa_fail_count'] += qa_fail_count
            phantom.save_data(qa_overall_result, key=keyfile)
def pin_3(action=None,
          success=None,
          container=None,
          results=None,
          handle=None,
          filtered_artifacts=None,
          filtered_results=None):
    import random
    phantom.debug('pin_3() called')

    # collect data for 'pin_to_hud_6' call
    dest_domain = filter(
        lambda x: x[0],
        phantom.collect2(container=container,
                         datapath=['artifact:*.cef.destinationDnsDomain']))

    pin_name = pin_name_mangle("pin_3", container)

    try:
        most_rcnt_domain = dest_domain[0][0]
    except:
        pass
    else:
        pin_id = phantom.get_data(pin_name)
        if not pin_id:
            ret_val, message, pin_id = phantom.pin(
                container=container,
                message="Most Recent Domain",
                data=most_rcnt_domain,
                pin_type="card_medium",
                pin_style="red")
            phantom.debug("new pin_3")
        else:
            ret_val, message = phantom.update_pin(pin_id,
                                                  message="Most Recent Domain",
                                                  data=most_rcnt_domain,
                                                  pin_type="card_medium",
                                                  pin_style="red")
        if ret_val:
            phantom.save_data(pin_id, pin_name)

    # set container properties for:
    update_data = {}

    phantom.update(container, update_data)
    return
Exemple #9
0
def detonate_file_cb(action, success, email, results, handle):
    collectkey = 'collect_data' + str(email['current_rule_run_id'])
    if not success:
        phantom.debug("Error running detonate action.\n{}".format(json.dumps(results)))
        return

    # grab just the results url from the threatgrid return data, perhaps send the entire results dict
    # later as an email attachment?
    #result_url = results[0]['action_results'][0]['summary']['results_url']
    # get the app run ID, and use it as a key to the dictionary we build with results
    app_run_id = results[0]['app_run_id']
    collected_results, collected_vault_items, container_owner = phantom.get_data(collectkey, clear_data=False)
    collected_results[app_run_id] = dict()
    collected_results[app_run_id]['asset'] = results[0]['asset']
    collected_results[app_run_id]['message'] = results[0]['message']
    collected_results[app_run_id]['summary'] = results[0]['summary']
    collected_results[app_run_id]['detonate_summary'] =  results[0]['action_results'][0]['summary']
    phantom.save_data([collected_results, collected_vault_items, container_owner], key=collectkey)

    return
def quarantine_device_1(action=None,
                        success=None,
                        container=None,
                        results=None,
                        handle=None,
                        filtered_artifacts=None,
                        filtered_results=None):

    # collect data for 'quarantine_device_1' call
    container_data = phantom.get_data("rkitdata", clear_data=True)

    parameters = []

    # build parameters list for 'quarantine_device_1' call
    for container_item in container_data:
        if container_item[0]:
            parameters.append({
                'ip_hostname': container_item[0],
                # context (artifact id) is added to associate results with the artifact
                'context': {
                    'artifact_id': container_item[1]
                },
            })

    if parameters:
        phantom.act("quarantine device",
                    parameters=parameters,
                    assets=['carbonblack'],
                    callback=get_system_info_1,
                    name="quarantine_device_1")
    else:
        phantom.error(
            "'quarantine_device_1' will not be executed due to lack of parameters"
        )

    return
Exemple #11
0
def generic_cb(action_name, status, incident, results, handle):
    phantom.debug('Action '+action_name+ (' SUCCEEDED' if status else ' FAILED'))
    my_data = phantom.get_data(handle)
    return
def pin_4(action=None,
          success=None,
          container=None,
          results=None,
          handle=None,
          filtered_artifacts=None,
          filtered_results=None):
    phantom.debug('pin_4() called')
    artifacts = phantom.collect(container=container,
                                datapath='artifacts:*',
                                scope='all')
    artifacts = sorted(artifacts, key=lambda x: x['update_time'], reverse=True)

    ioc_count = 0
    most_recent_ioc = None
    ioc_types = set()

    for artifact in artifacts:
        for key, value in artifact['cef'].iteritems():
            value = str(value)
            ret, ioc_type = is_ioc(value)
            if ret:
                if most_recent_ioc is None:
                    most_recent_ioc = value
                ioc_count += 1
                ioc_types.add(ioc_type)

    pin4_name = pin_name_mangle("pin_4", container)
    pin5_name = pin_name_mangle("pin_5", container)
    pin6_name = pin_name_mangle("pin_6", container)

    pin_id_ioc_cnt = phantom.get_data(pin4_name)
    pin_id_ioc_rct = phantom.get_data(pin5_name)
    pin_id_ioc_type = phantom.get_data(pin6_name)

    if not pin_id_ioc_cnt:
        ret_val, message, pin_id_ioc_cnt = phantom.pin(container=container,
                                                       message="IOC Count",
                                                       data=str(ioc_count),
                                                       pin_type="card_medium",
                                                       pin_style="white")
    else:
        ret_val, message = phantom.update_pin(pin_id_ioc_cnt,
                                              message="IOC Count",
                                              data=str(ioc_count),
                                              pin_type="card_medium",
                                              pin_style="red")
    if ret_val:
        phantom.save_data(pin_id_ioc_cnt, pin4_name)

    if ioc_count:
        if not pin_id_ioc_rct:
            ret_val, message, pin_id_ioc_rct = phantom.pin(
                container=container,
                message="Most Recent IOC",
                data=most_recent_ioc,
                pin_type="card_medium",
                pin_style="purple")
        else:
            ret_val, message = phantom.update_pin(pin_id_ioc_rct,
                                                  message="Most Recent IOC",
                                                  data=most_recent_ioc,
                                                  pin_type="card_medium",
                                                  pin_style="purple")
        if ret_val:
            phantom.save_data(pin_id_ioc_rct, pin5_name)

        if not pin_id_ioc_type:
            ret_val, message, pin_id_ioc_type = phantom.pin(
                container=container,
                message="IOC Types",
                data=", ".join(ioc_types))
        else:
            ret_val, message = phantom.update_pin(pin_id_ioc_type,
                                                  message="IOC Types",
                                                  data=", ".join(ioc_types))
        if ret_val:
            phantom.save_data(pin_id_ioc_type, pin6_name)
    return
Exemple #13
0
def generic_cb(action_name, status, incident, results, handle):
    phantom.debug('Action ' + action_name +
                  (' SUCCEEDED' if status else ' FAILED'))
    my_data = phantom.get_data(handle)
    return