def add_device_counts(policy_list):
    devices = di.get_devices(include_deactivated=False)
    device_counts = di.count_data_by_field(devices, 'policy_id')
    for policy in policy_list:
        if policy['ID'] not in device_counts.keys():
            policy['Device Count'] = 0
        else:
            policy['Device Count'] = device_counts[policy['ID']]
    return policy_list
#get tenant data from server
print('INFO: Getting Tenant data from server')
tenants = di.get_tenants()

#confirm that we got valid data back; if not, abort script
if len(tenants) == 0:
    print('ERROR: No Tenants returned. Check that server is multi-tenancy enabled and that your API key has the appropriate permissions.')
    sys.exit(0)

#get msp data from server
print('INFO: Getting MSP data from server')
msps = di.get_msps()

# get device data from server
print('INFO: Getting Device data from server')
devices = di.get_devices(include_deactivated=False)

# add msp_name to tenant data
print('INFO: Adding MSP names to Tenant data')
for tenant in tenants:
    for msp in msps:
        if tenant['msp_id'] == msp['id']:
            tenant['msp_name'] = msp['name']

# If option to include policy mode counts is enabled, get policy details,
# then parse policies to calculate mode, then add that data to devices
if include_policy_mode_counts:
    print('INFO: Getting policy data from server')
    policies = di.get_policies(include_policy_data=True)

    print('INFO: Parsing policy data to determine policy mode')
コード例 #3
0
def run_deployment_phase_progression_readiness(fqdn, key, config):

    print('Beginning data collection')

    di.fqdn = fqdn
    di.key = key
    di.quiet_mode = True
    config = config
    mt = di.is_server_multitenancy_enabled()

    #collect policy data
    print('\nGetting policy data from server')
    policies = di.get_policies(include_policy_data=True)

    #collect event data
    search_parameters = get_event_search_parameters(config['deployment_phase'])
    suspicious_search_parameters = get_suspicious_event_search_parameters(
        config['deployment_phase'])
    print('\nGetting event data from server')
    events = di.get_events(search=search_parameters)
    print(len(events), 'events were returned.')

    if not config['ignore_suspicious_events']:
        if suspicious_search_parameters != {}:
            print('\nGetting suspicious event data from server')
            suspicious_events = di.get_suspicious_events(
                search=suspicious_search_parameters)
            print(len(suspicious_events), 'suspicious events were returned.')
            events = events + suspicious_events

    event_counts = di.count_data_by_field(events, 'device_id')

    #collect device data
    print('\nGetting device data from server')
    devices = di.get_devices(include_deactivated=False)
    print(len(devices), 'devices were found.')

    #determine if we have data from a single MSP or multiple
    policy_msp_ids = []
    for policy in policies:
        if policy['msp_id'] not in policy_msp_ids:
            policy_msp_ids.append(policy['msp_id'])
    if len(policy_msp_ids) > 1:
        multiple_msps = True
    else:
        multiple_msps = False

    print('\nAnalyzing policy data')
    policy_evaluation_results = []
    for policy in policies:
        policy['deployment_phase'] = classify_policy(policy, config)
        if policy['os'] == 'WINDOWS':
            if policy['deployment_phase'] > 0:
                result = f"Policy '{policy['name']}' (ID {policy['id']}) is a Phase {policy['deployment_phase']} policy."
            else:
                result = f"Policy '{policy['name']}' (ID {policy['id']}) is not aligned with any defined Deployment Phase."
            if mt and multiple_msps:
                result = f"MSP '{policy['msp_name']}' (ID {policy['msp_id']}) {result}"
            print(result)
            policy_evaluation_results.append(result)

    filtered_devices = []
    for device in devices:
        for policy in policies:
            if policy['id'] == device['policy_id']:
                device['deployment_phase'] = policy['deployment_phase']
                if device['deployment_phase'] == config['deployment_phase']:
                    filtered_devices.append(device)
    excluded_device_count = len(devices) - len(filtered_devices)
    devices = filtered_devices

    print('')
    print(len(devices), 'devices are in a phase', config['deployment_phase'],
          'policy.')

    if len(devices) == 0:
        print('ERROR: Aborting analysis due to zero devices to analyze.')
        sys.exit(0)

    devices_ready = []
    devices_not_ready = []

    for device in devices:
        if device['id'] not in event_counts.keys():
            device['event_count'] = 0
        else:
            device['event_count'] = event_counts[device['id']]
        device['last_contact_days_ago'] = (
            datetime.datetime.now(datetime.timezone.utc) -
            parser.parse(device['last_contact'])).days
        device['days_since_install'] = (
            datetime.datetime.now(datetime.timezone.utc) -
            parser.parse(device['last_registration'])).days

        device['progression_criteria_violations'] = []

        if device['event_count'] > int(config['max_open_event_quantity']):
            device['progression_criteria_violations'].append(
                'More than ' + str(config['max_open_event_quantity']) +
                ' open events')

        if device['last_contact_days_ago'] > int(
                config['max_days_since_last_contact']):
            device['progression_criteria_violations'].append(
                'Offline for more than ' +
                str(config['max_days_since_last_contact']) + ' days')

        if device['days_since_install'] < int(
                config['min_days_since_install']):
            device['progression_criteria_violations'].append(
                'Installed less than ' +
                str(config['min_days_since_install']) + ' days ago')

        if len(device['progression_criteria_violations']) > 0:
            device['ready_to_move_to_next_phase'] = False
            devices_not_ready.append(device)
        else:
            device['ready_to_move_to_next_phase'] = True
            devices_ready.append(device)

    print(len(devices_ready), 'devices are ready to move to the next phase.')
    print(
        len(devices_not_ready),
        'devices are not ready based on violating one or more of the provided criteria.'
    )
    print(
        excluded_device_count,
        'devices in the system were not assessed due to not being in a phase',
        config['deployment_phase'], 'policy.')

    #convert data to be exported to dataframes
    devices_ready_df = pandas.DataFrame(devices_ready)
    devices_not_ready_df = pandas.DataFrame(devices_not_ready)
    config_df = pandas.DataFrame(config.items())
    search_parameters_df = pandas.DataFrame(search_parameters.items())
    suspicious_search_parameters_df = pandas.DataFrame(
        suspicious_search_parameters.items())
    policy_evaluation_results_df = pandas.DataFrame(policy_evaluation_results)

    #prep for export
    folder_name = di.create_export_folder()
    from_deployment_phase = "{:g}".format(float(config['deployment_phase']))
    if di.is_server_multitenancy_enabled() and not multiple_msps:
        server_shortname = re.sub(r'[^a-z0-9]', '',
                                  policies[0]['msp_name'].lower())
    else:
        server_shortname = di.fqdn.split(".", 1)[0]
    file_name = f'deployment_phase_{from_deployment_phase}_progression_readiness_assessment_{datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%d_%H.%M")}_UTC_{server_shortname}.xlsx'

    #export dataframes to Excel format
    with pandas.ExcelWriter(f'{folder_name}/{file_name}') as writer:
        devices_ready_df.to_excel(writer,
                                  sheet_name='ready_for_next_phase',
                                  index=False)
        devices_not_ready_df.to_excel(writer,
                                      sheet_name='not_ready_for_next_phase',
                                      index=False)
        config_df.to_excel(writer, sheet_name='config', index=False)
        search_parameters_df.to_excel(writer,
                                      sheet_name='event_search',
                                      index=False)
        suspicious_search_parameters_df.to_excel(
            writer, sheet_name='suspicious_event_search', index=False)
        policy_evaluation_results_df.to_excel(writer,
                                              sheet_name='policy_evaluation',
                                              index=False)

    print('')
    print(f'Results were exported to disk as\n{folder_name}\\{file_name}\n')
コード例 #4
0
def do_warranty_compliance_check(fqdn, key, exclude_empty_policies):
    di.fqdn = fqdn
    di.key = key

    #Get data from server
    print('INFO: Getting policy data from server')
    policies = di.get_policies(include_policy_data=True)
    print('INFO: Getting device data from server')
    devices = di.get_devices(include_deactivated=False)

    # Calculate device_count for each policy (how many active devices in policy)
    # Add device_countfield with initial value zero
    print('INFO: Calculating device count for each policy')
    for policy in policies:
        policy['device_count'] = 0
    # Iterate through devices and policies, incrementing device_count appropriately
    for device in devices:
        for policy in policies:
            if policy['id'] == device['policy_id']:
                policy['device_count'] += 1

    if exclude_empty_policies:
        print(
            'INFO: Narrowing policy list to include only those which contain 1 or more activated devices'
        )
        non_empty_policies = []
        for policy in policies:
            if policy['device_count'] > 0:
                non_empty_policies.append(policy)
        empty_policy_count = len(policies) - len(non_empty_policies)
        policies = non_empty_policies
    else:
        print(
            'INFO: exclude_empty_policies is disabled, therefore proceeding with analysis on all policies'
        )

    #Extract Windows policies
    print('INFO: Extracting Windows policies to new list windows_policies')
    windows_policies = []
    for policy in policies:
        if policy['os'] == 'WINDOWS':
            windows_policies.append(policy)

    #Iterate through Windows policies, determine compliance or lack thereof, and assign to appropriate list

    print('INFO: Analyzing policies for compliance')

    compliant_windows_policies = []
    noncompliant_windows_policies = []

    for policy in windows_policies:

        policy[
            'compliant'] = True  #initially assume compliant; will change to false if violation(s) identified
        policy['compliance_violations'] = {
        }  #define dictionary to store details of violation(s) if any

        if policy['prevention_level'] not in ['HIGH', 'MEDIUM', 'LOW']:
            policy['compliant'] = False
            policy['compliance_violations']['prevention_level'] = policy[
                'prevention_level']

        if policy['remote_code_injection'] != 'PREVENT':
            policy['compliant'] = False
            policy['compliance_violations']['remote_code_injection'] = policy[
                'remote_code_injection']

        if policy['arbitrary_shellcode_execution'] != 'PREVENT':
            policy['compliant'] = False
            policy['compliance_violations'][
                'arbitrary_shellcode_execution'] = policy[
                    'arbitrary_shellcode_execution']

        if policy['ransomware_behavior'] != 'PREVENT':
            policy['compliant'] = False
            policy['compliance_violations']['ransomware_behavior'] = policy[
                'ransomware_behavior']

        #TODO: Add logic to check the following atttributes of the Windows policy:
        #   1. D-Cloud Services (compliance requires that this be enabled)
        #   2. Malicious PowerShell Prevention (compliance requires that this be in Prevention)
        #Both of above require that product make these fields visible via the REST API. Submitted
        #as FR-166 and FR-167 on 2021-07-06

        if policy['compliant'] == True:
            compliant_windows_policies.append(policy)
        else:
            noncompliant_windows_policies.append(policy)

    #Calculate how many devices are in compliant versus non-compliance policies

    print('INFO: Counting sum of devices in policies in each category')

    device_count_compliant_windows_policies = 0
    for policy in compliant_windows_policies:
        device_count_compliant_windows_policies += policy['device_count']

    device_count_noncompliant_windows_policies = 0
    for policy in noncompliant_windows_policies:
        device_count_noncompliant_windows_policies += policy['device_count']

    #Write results to disk

    print('INFO: Calculating file and folder names for export')
    folder_name = di.create_export_folder()
    file_name = f'warranty_compliance_audit_{datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%d_%H.%M")}_UTC.txt'

    print('INFO: Opening file for writing data to to disk')
    output = open(f'{folder_name}\{file_name}', 'a')

    print('INFO: Writing data to disk')

    output.writelines([
        '--------\nDeep Instinct Ransomware Warranty Compliance Check\n',
        di.fqdn, '\n',
        datetime.datetime.now(
            datetime.timezone.utc).strftime("%Y-%m-%d_%H.%M"),
        ' UTC\n--------\n\n'
    ])

    if exclude_empty_policies:
        if empty_policy_count > 0:
            output.writelines([
                'NOTE: Data below excludes ',
                str(empty_policy_count),
                ' policies containing 0 activated devices.\n\n'
            ])

    output.writelines([
        str(device_count_compliant_windows_policies),
        ' devices are in a compliant Windows policy.\n'
    ])
    output.writelines([
        str(device_count_noncompliant_windows_policies),
        ' devices are in a non-compliant Windows policy.\n'
    ])
    output.writelines([
        '\n',
        str(len(compliant_windows_policies)),
        ' Windows policies are compliant:\n\n'
    ])
    output.writelines([
        'msp_id\tmsp_name\tpolicy_id\tpolicy_name\tdevice_count\tcompliance_violations\n'
    ])
    for policy in compliant_windows_policies:
        output.writelines([
            str(policy['msp_id']), '\t', policy['msp_name'], '\t',
            str(policy['id']), '\t', policy['name'], '\t',
            str(policy['device_count']), '\t',
            str(policy['compliance_violations']), '\n'
        ])
    output.writelines([
        '\n',
        str(len(noncompliant_windows_policies)),
        ' Windows policies are non-compliant:\n\n'
    ])
    output.writelines([
        'msp_id\tmsp_name\tpolicy_id\tpolicy_name\tdevice_count\tcompliance_violations\n'
    ])
    for policy in noncompliant_windows_policies:
        output.writelines([
            str(policy['msp_id']), '\t', policy['msp_name'], '\t',
            str(policy['id']), '\t', policy['name'], '\t',
            str(policy['device_count']), '\t',
            str(policy['compliance_violations']), '\n'
        ])

    print('INFO: Closing file for writing data to to disk')
    output.close()

    print('INFO: Done. Results written to', f'{folder_name}\{file_name}')