Exemplo n.º 1
0
def main():
    """Script entry point"""
    parser = build_cli_parser()
    parser.add_argument("--window", help="Define search window", default='3d')

    args = parser.parse_args()
    global ORG_KEY
    global HOSTNAME

    print_detail = False

    cb = get_cb_cloud_object(args)

    HEADERS['X-Auth-Token'] = cb.credentials.token
    ORG_KEY = cb.credentials.org_key
    HOSTNAME = cb.credentials.url

    start_date = (datetime.now() + timedelta(days=-2)).isoformat() + "Z"
    end_date = (datetime.now() + timedelta(days=-1)).isoformat() + "Z"
    if print_detail:
        print("Start date: {}\nEnd date: {}".format(start_date, end_date))

    run_process_invalid_search(cb, print_detail)
    run_process_event_invalid_search(cb, print_detail)
    get_list_of_available_process_results(cb)
    process_guid = get_process_guid(cb, print_detail, start_date, end_date)
    process_name = retrieve_process_name_from_process_details(cb, process_guid)
    get_process_facet(cb, print_detail, process_name, start_date, end_date)
    get_process_events_for_single_process(cb, process_guid, start_date,
                                          end_date, print_detail)
    get_events_facet_associated_with_a_process(cb, print_detail, start_date,
                                               end_date, process_guid)
    print('END OF TEST')
def main():
    """Main function for Device Processes script."""
    parser = build_cli_parser()

    args = parser.parse_args()
    cb = get_cb_cloud_object(args)

    query = cb.select(Device).where('1').set_status(['ACTIVE'])
    devices = list(query)
    if args.verbose:
        print(f"Querying {len(devices)} device(s)...")
    active_queries = set()
    for device in devices:
        query = cb.select(Process).where(
            f"device_id:{device.id}").set_time_range(window='-6h')
        if args.verbose:
            print(f"Sending query for device ID {device.id}...")
        active_queries.add(query.execute_async())

    if args.verbose:
        print("Done sending queries, waiting for responses...")
    concurrent.futures.wait(active_queries)
    print("{0:16} {1:5} {2:60}".format("Device Name", "PID", "Process Name"))
    print("{0:16} {1:5} {2:60}".format("-----------", "---", "------------"))
    for future in active_queries:
        result = future.result()
        for process in result:
            print("{0:16} {1:5} {2:60}".format(process['device_name'],
                                               process['process_pid'][0],
                                               process['process_name']))
Exemplo n.º 3
0
def main():
    """Main function for the user listing script"""
    parser = build_cli_parser('Find Users With Grants')
    parser.add_argument(
        '-n',
        '--number',
        type=int,
        default=0,
        help="Maximum number of users to find (default no limit)")

    args = parser.parse_args()
    cb = get_cb_cloud_object(args)

    users = cb.select(User)
    result_list = []
    count = 0
    for user in users:
        if has_grant(user):
            result_list.append(user)
            if 0 < args.number == len(result_list):
                break
        count = count + 1
        if count % 100 == 0:
            print(f"Processed {count} users")

    print(
        f"Found {len(result_list)} 'interesting' users (that have profiles) out of {count}"
    )
    for user in result_list:
        grant = user.grant()
        print(
            f"{user.login_id} - '{user.first_name} {user.last_name}' - {len(grant.profiles_)} profile(s)"
        )
    return 0
Exemplo n.º 4
0
def main():
    parser = build_cli_parser("List devices")
    parser.add_argument("-q", "--query", help="Query string for looking for devices")
    parser.add_argument("-A", "--ad_group_id", action="append", type=int, help="Active Directory Group ID")
    parser.add_argument("-p", "--policy_id", action="append", type=int, help="Policy ID")
    parser.add_argument("-s", "--status", action="append", help="Status of device")
    parser.add_argument("-P", "--priority", action="append", help="Target priority of device")
    parser.add_argument("-S", "--sort_by", help="Field to sort the output by")
    parser.add_argument("-R", "--reverse", action="store_true", help="Reverse order of sort")

    args = parser.parse_args()
    cb = get_cb_cloud_object(args)

    query = cb.select(Device)
    if args.query:
        query = query.where(args.query)
    if args.ad_group_id:
        query = query.set_ad_group_ids(args.ad_group_id)
    if args.policy_id:
        query = query.set_policy_ids(args.policy_id)
    if args.status:
        query = query.set_status(args.status)
    if args.priority:
        query = query.set_target_priorities(args.priority)
    if args.sort_by:
        direction = "DESC" if args.reverse else "ASC"
        query = query.sort_by(args.sort_by, direction)

    devices = list(query)
    print("{0:9} {1:40}{2:18}{3}".format("ID", "Hostname", "IP Address", "Last Checkin Time"))
    for device in devices:
        print("{0:9} {1:40s}{2:18s}{3}".format(device.id, device.name or "None",
                                               device.last_internal_ip_address or "Unknown",
                                               device.last_contact_time))
def main():
    """Script entry point"""
    parser = build_cli_parser()
    args = parser.parse_args()

    cb = get_cb_cloud_object(args)
    header_line()

    start_api_call('Get Sensor Configuration Template')
    templ_sdk = get_config_template_sdk(cb)
    templ_api = get_config_template_api(cb)
    base_compare(templ_sdk, templ_api, 'Get Sensor Configuration Template')

    start_api_call('Get Sensor Kit and Configuration Links')
    expires_date = (datetime.now() + timedelta(days=2)).isoformat() + "Z"
    kits_sdk = get_sensor_kits_sdk(cb, expires_date)
    kits_api = get_sensor_kits_api(cb, expires_date)
    sensorkit_compare(kits_sdk, kits_api)

    # We use an arbitrary resource to serve as the target for a sensor install.
    resource = lookup_compute_resource(cb)

    start_api_call('Request Workload Sensor Installation')
    result_sdk = request_install_sdk(resource)
    result_api = request_install_api(cb, resource)
    base_compare(result_sdk, result_api,
                 'Request Workload Sensor Installation')
Exemplo n.º 6
0
def main(cbc=None, menu=None, parser=None):
    """Script entry point"""
    # Initiate argparser
    parser = build_cli_parser()
    parser.add_argument('--appliance_uuid', nargs='+')
    parser.add_argument('--eligibility', nargs='+')
    parser.add_argument('--cluster_name', nargs='+')
    parser.add_argument('--name', nargs='+')
    parser.add_argument('--ip_address', nargs='+')
    parser.add_argument('--installation_status', nargs='+')
    parser.add_argument('--uuid', nargs='+')
    parser.add_argument('--os_type', nargs='+')
    parser.add_argument('--os_architecture', nargs='+')
    args = parser.parse_args()

    # Create cbc Instance
    cbc = get_cb_cloud_object(args)

    # Generate menu
    menu = generate_menu()

    # Get user menu choice
    user_choice = user_input(menu)

    # Call user specified sdk call
    menu[user_choice]['function_call'](cbc, menu, parser)
def main():
    """Script entry point"""
    parser = build_cli_parser()
    args = parser.parse_args()
    print_detail = args.verbose
    window = '-' + args.window

    do_process = True
    do_enriched_events = True

    if print_detail:
        print(f"profile being used is {args.__dict__}")

    process_guid = ""
    cb = get_cb_cloud_object(args)
    if do_process:
        process_guid = get_process_basic_window_enriched(cb, print_detail, window)
        get_process_events_for_single_process(cb, print_detail, process_guid)
        run_process_invalid_search(cb, print_detail)
        run_process_event_invalid_search(cb, print_detail)
        get_process_facet(cb, window)
        get_list_of_available_process_results(cb)
        get_events_facet_associated_with_a_process(cb, process_guid)
    if do_enriched_events:
        if not process_guid:
            process_guid = get_process_basic_window_enriched(cb, print_detail, window)
        event_id = get_enriched_events_for_single_process(cb, process_guid)
        get_enriched_event_facet(cb, print_detail, window)
        enriched_events_details(cb, event_id)
        enriched_events_aggregation(cb)
def main():
    """Main function for the user listing script"""
    parser = build_cli_parser('List Permitted Roles')
    args = parser.parse_args()
    cb = get_cb_cloud_object(args)

    roles = Grant.get_permitted_role_urns(cb)
    for index, role in enumerate(sorted(roles)):
        print(f"{index + 1}. {role}")
    return 0
def main():
    """Script entry point"""
    parser = build_cli_parser()
    args = parser.parse_args()

    do_devices = True

    cb = get_cb_cloud_object(args)
    if do_devices:
        search_devices(cb)
Exemplo n.º 10
0
def main():
    """Main function for Device Actions script."""
    parser = build_cli_parser("Send control messages to device")
    parser.add_argument("-d", "--device_id", type=int, required=True, help="The ID of the device to be controlled")
    subparsers = parser.add_subparsers(dest="command", help="Device command help")

    bgscan_p = subparsers.add_parser("background_scan", help="Set background scanning status")
    toggle = bgscan_p.add_mutually_exclusive_group(required=True)
    toggle.add_argument("--on", action="store_true", help="Turn background scanning on")
    toggle.add_argument("--off", action="store_true", help="Turn background scanning off")

    bypass_p = subparsers.add_parser("bypass", help="Set bypass mode")
    toggle = bypass_p.add_mutually_exclusive_group(required=True)
    toggle.add_argument("--on", action="store_true", help="Enable bypass mode")
    toggle.add_argument("--off", action="store_true", help="Disable bypass mode")

    subparsers.add_parser("delete", help="Delete sensor")
    subparsers.add_parser("uninstall", help="Uninstall sensor")

    quarantine_p = subparsers.add_parser("quarantine", help="Set quarantine mode")
    toggle = quarantine_p.add_mutually_exclusive_group(required=True)
    toggle.add_argument("--on", action="store_true", help="Enable quarantine mode")
    toggle.add_argument("--off", action="store_true", help="Disable quarantine mode")

    policy_p = subparsers.add_parser("policy", help="Update policy for node")
    policy_p.add_argument("-p", "--policy_id", type=int, required=True, help="New policy ID to set for node")

    sensorv_p = subparsers.add_parser("sensor_version", help="Update sensor version for node")
    sensorv_p.add_argument("-o", "--os", required=True, help="Operating system for sensor")
    sensorv_p.add_argument("-V", "--version", required=True, help="Version number of sensor")

    args = parser.parse_args()
    cb = get_cb_cloud_object(args)
    dev = cb.select(Device, args.device_id)

    if args.command:
        if args.command == "background_scan":
            dev.background_scan(toggle_value(args))
        elif args.command == "bypass":
            dev.bypass(toggle_value(args))
        elif args.command == "delete":
            dev.delete_sensor()
        elif args.command == "uninstall":
            dev.uninstall_sensor()
        elif args.command == "quarantine":
            dev.quarantine(toggle_value(args))
        elif args.command == "policy":
            dev.update_policy(args.policy_id)
        elif args.command == "sensor_version":
            dev.update_sensor_version({args.os: args.version})
        else:
            raise NotImplementedError("Unknown command")
        print("OK")
    else:
        print(dev)
Exemplo n.º 11
0
def main():
    """Script entry point"""
    global ORG_KEY
    global HOSTNAME
    parser = build_cli_parser()
    parser.add_argument("--window", help="Define search window", default='3d')

    args = parser.parse_args()
    print_detail = args.verbose
    window = '-' + args.window

    if print_detail:
        print("args provided {}".format(args))

    cb = get_cb_cloud_object(args)
    HEADERS["X-Auth-Token"] = cb.credentials.token
    ORG_KEY = cb.credentials.org_key
    HOSTNAME = cb.credentials.url

    print()
    print(17 * " ", "Enriched Events For Alerts")
    print(SYMBOLS * DELIMITER)
    # get alert created in the last four weeks, because enriched events are kept for some time
    query = cb.select(CBAnalyticsAlert).set_create_time(range="-4w")
    if len(query) == 0:
        return

    item = query[0]
    alert_id = item._info["legacy_alert_id"]
    eevents = [event._info for event in item.get_events()]

    job_id = start_search_job(alert_id)
    wait_till_job_ready(job_id)
    records = get_results_search_job(job_id)
    assert records == eevents, "Actual: {}, Expected: {}".format(
        records, eevents)
    print("Get events for CBAnalyticsAlert...........................OK")
    async_eevents = [
        event._info for event in item.get_events(async_mode=True).result()
    ]
    assert records == async_eevents, "Actual: {}, Expected: {}".format(
        records, async_eevents)
    print("Get async events for CBAnalyticsAlert.....................OK")

    # TODO rewrite the functionality below
    process_guid = ""
    if not process_guid:
        process_guid = get_process_basic_window_enriched(
            cb, print_detail, window)
    event_id = get_enriched_events_for_single_process(cb, process_guid)
    get_enriched_event_facet(cb, print_detail, window)
    enriched_events_details(cb, event_id)
    enriched_events_aggregation(cb)
def test_apicloudapi_object_with_command_line_arguments():
    """Tests the CBCloudAPI object with command line arguments."""
    parser = build_cli_parser("Test helpers.py")
    args = parser.parse_known_args()[0]

    args.cburl = 'https://example.com'
    args.apitoken = 'ABCDEFGH'
    args.orgkey = 'A1B2C3D4'
    args.no_ssl_verify = 'false'

    api = get_cb_cloud_object(args)

    assert api.credential_profile_name is None
def main():
    parser = build_cli_parser("Carbon Black Cloud Live Response CLI")
    parser.add_argument("--log", help="Log activity to a file", default='')
    args = parser.parse_args()
    cb = get_cb_cloud_object(args)

    if args.log:
        file_handler = logging.FileHandler(args.log)
        file_handler.setLevel(logging.DEBUG)
        log.addHandler(file_handler)

    cli = CblrCli(cb, connect_callback)
    cli.cmdloop()
def main():
    """Script entry point"""
    parser = build_cli_parser()
    args = parser.parse_args()
    global ORG_KEY
    global HOSTNAME

    cb = get_cb_cloud_object(args)

    HEADERS['X-Auth-Token'] = cb.credentials.token
    ORG_KEY = cb.credentials.org_key
    HOSTNAME = cb.credentials.url

    search_devices(cb)
def main():
    """Script entry point"""
    parser = build_cli_parser()
    args = parser.parse_args()

    cb = get_cb_cloud_object(args)

    sdk_resp, event_id = search_and_facet_compute_resources_sdk(cb)
    api_resp = search_and_facet_compute_resources_api(cb)
    compare_data_facet(sdk_resp, api_resp,
                       'Search and Facet Compute Resources')

    sdk_resp = fetch_compute_resource_by_id_sdk(cb, event_id)
    api_resp = fetch_compute_resource_by_id_api(cb, event_id)
    compare_data_id(sdk_resp, api_resp, 'Fetch Compute Resource by ID')
Exemplo n.º 16
0
def main():
    """Main function for the role changing script"""
    parser = build_cli_parser("Change User's Role")
    parser.add_argument('email',
                        help='E-mail address of the user to change role of')
    parser.add_argument('role', help='New role URN for the user')

    args = parser.parse_args()
    cb = get_cb_cloud_object(args)

    user = cb.select(User).email_addresses([args.email]).one()
    grant = user.grant()
    need_reset = True
    for profile in grant.profiles_:
        if profile.allowed_orgs == [cb.org_urn]:
            profile.roles = [args.role]
            profile.save()
            need_reset = False
    if need_reset:
        grant.roles = [args.role]
        grant.save()
    print("Role changed.")
    return 0
Exemplo n.º 17
0
def main():
    """Main function for the user creation script"""
    parser = build_cli_parser('Create a User')
    parser.add_argument('first_name', help='First name for the new user')
    parser.add_argument('last_name', help='Last name for the new user')
    parser.add_argument('email', help='E-mail address for the new user')
    parser.add_argument('phone', help='Phone number for the new user')
    parser.add_argument('role', help='Role URN to assign the new user')
    parser.add_argument('-P', '--accessprofiles', action='store_true',
                        help='Use access profiles when creating the user')

    args = parser.parse_args()
    cb = get_cb_cloud_object(args)

    builder = User.create(cb).set_first_name(args.first_name).set_last_name(args.last_name).set_email(args.email)
    builder.set_phone(args.phone)
    if args.accessprofiles:
        builder.add_grant_profile([cb.org_urn], [args.role])
    else:
        builder.set_role(args.role)
    builder.build()
    print("New user created.")
    return 0
def main():
    """Script entry point"""
    parser = build_cli_parser()
    parser.add_argument("-m",
                        "--machinename",
                        help="machinename to run host forensics recon on")
    parser.add_argument("-g",
                        "--get",
                        help="Get the Dell BIOS Verification images",
                        action="store_true")
    args = parser.parse_args()

    # Create the CBCloud
    cb = get_cb_cloud_object(args)

    if args.machinename:
        if args.get:
            live_response(cb, host=args.machinename, response="get")
        else:
            print("Nothing to do...")
    else:
        print(
            "[ ! ] You must specify a machinename with a --machinename parameter."
            " IE ./BiosVerification.py --machinename cheese")
def main():
    """Main function of the Feed Operations script."""
    parser = build_cli_parser()
    commands = parser.add_subparsers(help="Feed commands", dest="command_name")

    list_command = commands.add_parser("list", help="List all configured feeds")
    list_command.add_argument(
        "-P",
        "--public",
        help="Include public feeds",
        action="store_true",
        default=False,
    )
    list_command.add_argument(
        "-r",
        "--reports",
        help="Include reports for each feed",
        action="store_true",
        default=False,
    )
    list_command.add_argument(
        "-i",
        "--iocs",
        help="Include IOCs for each feed's reports",
        action="store_true",
        default=False,
    )

    list_iocs_command = commands.add_parser(
        "list-iocs", help="List all IOCs for a feed"
    )
    specifier = list_iocs_command.add_mutually_exclusive_group(required=True)
    specifier.add_argument("-i", "--id", type=str, help="Feed ID")
    specifier.add_argument("-f", "--feedname", type=str, help="Feed Name")

    export_command = commands.add_parser(
        "export", help="Export a feed into an importable format"
    )
    specifier = export_command.add_mutually_exclusive_group(required=True)
    specifier.add_argument("-i", "--id", type=str, help="Feed ID")
    specifier.add_argument("-f", "--feedname", type=str, help="Feed Name")

    import_command = commands.add_parser(
        "import", help="Import a previously exported feed"
    )
    import_command.add_argument(
        "-f", "--feedname", type=str, help="Renames the imported feed"
    )
    import_command.add_argument(
        "-P", "--public", help="Make the feed public", action="store_true"
    )

    del_command = commands.add_parser("delete", help="Delete feed")
    specifier = del_command.add_mutually_exclusive_group(required=True)
    specifier.add_argument("-i", "--id", type=str, help="Feed ID")
    specifier.add_argument("-f", "--feedname", type=str, help="Feed Name")

    export_report_command = commands.add_parser(
        "export-report", help="Export a feed's report into an importable format"
    )
    specifier = export_report_command.add_mutually_exclusive_group(required=True)
    specifier.add_argument("-i", "--id", type=str, help="Feed ID")
    specifier.add_argument("-f", "--feedname", type=str, help="Feed Name")
    specifier = export_report_command.add_mutually_exclusive_group(required=True)
    specifier.add_argument("-I", "--reportid", type=str, help="Report ID")
    specifier.add_argument("-r", "--reportname", type=str, help="Report Name")

    import_report_command = commands.add_parser(
        "import-report", help="Import a previously exported report"
    )
    specifier = import_report_command.add_mutually_exclusive_group(required=True)
    specifier.add_argument("-i", "--id", type=str, help="Feed ID")
    specifier.add_argument("-f", "--feedname", type=str, help="Feed Name")

    delete_report_command = commands.add_parser(
        "delete-report", help="Delete a report from a feed"
    )
    specifier = delete_report_command.add_mutually_exclusive_group(required=True)
    specifier.add_argument("-i", "--id", type=str, help="Feed ID")
    specifier.add_argument("-f", "--feedname", type=str, help="Feed Name")
    specifier = delete_report_command.add_mutually_exclusive_group(required=True)
    specifier.add_argument("-I", "--reportid", type=str, help="Report ID")
    specifier.add_argument("-r", "--reportname", type=str, help="Report Name")

    replace_report_command = commands.add_parser(
        "replace-report", help="Replace a feed's report"
    )
    specifier = replace_report_command.add_mutually_exclusive_group(required=True)
    specifier.add_argument("-i", "--id", type=str, help="Feed ID")
    specifier.add_argument("-f", "--feedname", type=str, help="Feed Name")

    args = parser.parse_args()
    cb = get_cb_cloud_object(args)

    if args.command_name == "list":
        return list_feeds(cb, parser, args)
    elif args.command_name == "list-iocs":
        return list_iocs(cb, parser, args)
    elif args.command_name == "export":
        return export_feed(cb, parser, args)
    elif args.command_name == "import":
        return import_feed(cb, parser, args)
    elif args.command_name == "delete":
        return delete_feed(cb, parser, args)
    elif args.command_name == "export-report":
        return export_report(cb, parser, args)
    elif args.command_name == "import-report":
        return import_report(cb, parser, args)
    elif args.command_name == "delete-report":
        return delete_report(cb, parser, args)
    elif args.command_name == "replace-report":
        return replace_report(cb, parser, args)
Exemplo n.º 20
0
def main():
    """Export an ordered csv file by kill_chain_status to current directory"""
    args = get_args()
    cb = get_cb_cloud_object(args)

    now = datetime.now().strftime('%Y%m%d%H%M%S')
    sep = "|"

    attack_stages_query = cb.select(CBAnalyticsAlert)

    if args.severity:
        attack_stages_query = attack_stages_query.set_minimum_severity(
            args.severity)

    if args.range:
        attack_stages_query = attack_stages_query.set_time_range(
            'last_update_time', range=f'-{args.range}')

    stages = [
        "RECONNAISSANCE", "WEAPONIZE", "DELIVER_EXPLOIT", "INSTALL_RUN",
        "COMMAND_AND_CONTROL", "EXECUTE_GOAL", "BREACH"
    ]

    processed_alerts = set()
    try:
        print(f'Writing Attack Stages to: attack_stages_{now}.csv')
        with open(f'attack_stages_{now}.csv', 'w') as export_file:
            export_file.write(
                'Alert ID,Alert,ThreatScore,TargetPriority,Vector,Stage,First Seen,'
                'DeviceHostName,Username,Policy,On/Off Premise,TTPs,ThreatCategory,'
                'RunState,PolicyAppliedState,Dismissed,Reputation\n')
            for stage in stages:
                attack_stages_query = attack_stages_query.set_kill_chain_statuses(
                    [stage])

                alerts = list(attack_stages_query)
                if len(alerts) > 0:
                    for alert in alerts:
                        # Check if Alert was already exported as an Alert can have one or more kill_chain_statuses
                        if alert.id in processed_alerts:
                            continue
                        processed_alerts.add(alert.id)

                        export_file.write(f'{alert.id},')  # Alert ID
                        export_file.write(f'{alert.reason},')  # Alert
                        export_file.write(f'{alert.severity},')  # ThreatScore
                        export_file.write(
                            f'{alert.target_value},')  # TargetPriority
                        export_file.write(
                            f'{alert.threat_cause_vector},')  # Vector
                        export_file.write(
                            f'{sep.join(alert.kill_chain_status)},')  # Stage
                        export_file.write(
                            f'{alert.first_event_time},')  # First Seen
                        export_file.write(
                            f'{alert.device_name},')  # DeviceHostName
                        export_file.write(
                            f'{alert.device_username},')  # Username
                        export_file.write(f'{alert.policy_name},')  # Policy
                        export_file.write(
                            f'{alert.device_location},')  # On/Off Premise
                        ttps = set()
                        if alert.threat_indicators:
                            for indicator in alert.threat_indicators:
                                if indicator["ttps"]:
                                    for ttp in indicator["ttps"]:
                                        ttps.add(ttp)
                        export_file.write(f'{sep.join(list(ttps))},')  # TTPs
                        export_file.write(
                            f'{alert.threat_cause_threat_category},'
                        )  # ThreatCategory
                        export_file.write(f'{alert.run_state},')  # RunState
                        export_file.write(
                            f'{alert.policy_applied},')  # PolicyAppliedState
                        export_file.write(
                            f'{False if alert.workflow["state"] else True},'
                        )  # Dismissed
                        export_file.write(
                            f'{alert.threat_cause_reputation},')  # Reputation
                        export_file.write('\n')
    except Exception as e:
        print(f'Verify your args are valid. Exception {e}')
def main():
    """Script entry point"""
    parser = build_cli_parser()
    parser.add_argument("--job",
                        action="store",
                        default="examplejob",
                        required=True)

    args = parser.parse_args()

    cb = get_cb_cloud_object(args)

    device_query = cb.select(Device)

    # Retrieve the list of devices that are online
    # calculate based on devices that have checked in during the last five minutes
    now = datetime.utcnow()
    delta = timedelta(minutes=5)

    online_devices = []
    offline_devices = []
    for device in device_query:
        if now - datetime.strptime(device.last_contact_time, FORMAT) < delta:
            online_devices.append(device)
        else:
            offline_devices.append(device)

    print("The following devices are offline and will not be queried:")
    for device in offline_devices:
        print("  {0}: {1}".format(device.id, device.name))

    print("The following devices are online and WILL be queried:")
    for device in offline_devices:
        print("  {0}: {1}".format(device.id, device.name))

    # import our job object from the jobfile
    job = __import__(args.job)
    jobobject = job.getjob()

    completed_devices = []
    futures = {}

    # collect 'future' objects for all jobs
    for device in online_devices:
        f = cb.live_response.submit_job(jobobject.run, device)
        futures[f] = device.id

    # iterate over all the futures
    for f in as_completed(futures.keys(), timeout=100):
        if f.exception() is None:
            print("Device {0} had result:".format(futures[f]))
            print(f.result())
            completed_devices.append(futures[f])
        else:
            print("Device {0} had error:".format(futures[f]))
            print(f.exception())

    still_to_do = set([s.id for s in online_devices]) - set(completed_devices)
    print(
        "The following devices were attempted but not completed or errored out:"
    )
    for device in still_to_do:
        print("  {0}".format(device))
def main():
    """Main function for the LiveQuery runs manager."""
    parser = build_cli_parser("Create and manage LiveQuery runs")
    commands = parser.add_subparsers(help="Commands", dest="command_name")

    create_command = commands.add_parser("create",
                                         help="Create a new LiveQuery run")
    create_command.add_argument("-s",
                                "--sql",
                                type=str,
                                required=True,
                                help="The query to run")
    create_command.add_argument(
        "-n",
        "--notify",
        action="store_true",
        help="Notify by email when the run finishes",
    )
    create_command.add_argument("-N",
                                "--name",
                                type=str,
                                required=False,
                                help="The name of the run")
    create_command.add_argument(
        "--device_ids",
        nargs="+",
        type=int,
        required=False,
        help="Device IDs to filter on",
    )
    create_command.add_argument(
        "--device_types",
        nargs="+",
        type=str,
        required=False,
        help="Device types to filter on",
    )
    create_command.add_argument(
        "--policy_id",
        type=int,
        required=False,
        help="Policy ID to filter on. Only one policy_id can be specified.",
    )

    status_command = commands.add_parser(
        "status", help="Retrieve information about a run")
    status_command.add_argument("-i",
                                "--id",
                                type=str,
                                required=True,
                                help="The run ID")

    stop_command = commands.add_parser("stop",
                                       help="Stops/cancels a current run")
    stop_command.add_argument("-i",
                              "--id",
                              type=str,
                              required=True,
                              help="The run ID")

    delete_command = commands.add_parser("delete",
                                         help="Permanently delete a run")
    delete_command.add_argument("-i",
                                "--id",
                                type=str,
                                required=True,
                                help="The run ID")

    history_command = commands.add_parser("history",
                                          help="List history of all runs")
    history_command.add_argument("-q",
                                 "--query",
                                 type=str,
                                 required=False,
                                 help="Query string to use")
    history_command.add_argument("-S",
                                 "--sort_by",
                                 type=str,
                                 help="sort by this field",
                                 required=False)
    history_command.add_argument("-D",
                                 "--descending_results",
                                 help="return results in descending order",
                                 action="store_true",
                                 required=False)

    args = parser.parse_args()
    cb = get_cb_cloud_object(args)

    if args.command_name == "create":
        return create_run(cb, args)
    elif args.command_name == "status":
        return run_status(cb, args)
    elif args.command_name == "stop":
        return run_stop(cb, args)
    elif args.command_name == "delete":
        return run_delete(cb, args)
    elif args.command_name == "history":
        return run_history(cb, args)
def main():
    """Script entry point"""
    global ORG_KEY
    global HOSTNAME
    parser = build_cli_parser()
    args = parser.parse_args()
    print_detail = args.verbose

    if print_detail:
        print(f"profile being used is {args.__dict__}")

    cb = get_cb_cloud_object(args)

    ReputationOverride.create(cb, {
        "description": "An override for a sha256 hash",
        "override_list": "BLACK_LIST",
        "override_type": "SHA256",
        "sha256_hash": "af62e6b3d475879c4234fe7bd8ba67ff6544ce6510131a069aaac75aa92aee7a",
        "filename": "foo.exe"
    })

    sha256_override = cb.select(ReputationOverride) \
                        .where("foo*") \
                        .set_override_list("BLACK_LIST") \
                        .set_override_type("SHA256") \
                        .sort_by("create_time", "desc") \
                        .first()

    assert sha256_override.sha256_hash == "af62e6b3d475879c4234fe7bd8ba67ff6544ce6510131a069aaac75aa92aee7a"
    assert sha256_override.filename == "foo.exe"
    print('Configure Reputation Override - SHA256 .......OK')
    print('Search Reputation Overrides - SHA256 .........OK')

    override_by_id = cb.select(ReputationOverride, sha256_override.id)

    assert override_by_id.id == sha256_override.id
    assert override_by_id.sha256_hash == sha256_override.sha256_hash
    print('Get Reputation Override ......................OK')

    sha256_override.delete()

    delete_query = cb.select(ReputationOverride) \
                     .where("foo") \
                     .set_override_list("BLACK_LIST") \
                     .set_override_type("SHA256") \
                     .sort_by("create_time", "desc")

    assert len(delete_query) == 0
    print('Delete Reputation Override ...................OK')

    caught = False
    try:
        sha256_override.delete()
    except ObjectNotFoundError:
        caught = True
    assert caught
    print('Delete Reputation Override - 404 .............OK')

    ReputationOverride.create(cb, {
        "description": "Approved IT Tools",
        "override_list": "WHITE_LIST",
        "override_type": "IT_TOOL",
        "path": "C://tools//*.exe",
        "include_child_processes": True
    })

    it_tool_override = cb.select(ReputationOverride) \
                         .set_override_list("WHITE_LIST") \
                         .set_override_type("IT_TOOL") \
                         .sort_by("create_time", "desc") \
                         .first()

    assert it_tool_override.path == "C://tools//*.exe"
    assert it_tool_override.include_child_processes
    print('Configure Reputation Override - IT_TOOL ......OK')
    print('Search Reputation Overrides - IT_TOOL ........OK')

    ReputationOverride.create(cb, {
        "description": "Approved Certificate",
        "override_list": "WHITE_LIST",
        "override_type": "CERT",
        "signed_by": "VMware Inc.",
        "certificate_authority": "VMware"
    })

    cert_override = cb.select(ReputationOverride) \
                      .set_override_list("WHITE_LIST") \
                      .set_override_type("CERT") \
                      .sort_by("create_time", "desc") \
                      .first()

    assert cert_override.signed_by == "VMware Inc."
    assert cert_override.certificate_authority == "VMware"
    print('Configure Reputation Override - CERT .........OK')
    print('Search Reputation Overrides - CERT ...........OK')

    ReputationOverride.bulk_delete(cb, [it_tool_override.id, cert_override.id])

    with pytest.raises(ObjectNotFoundError):
        cb.select(ReputationOverride, it_tool_override.id)
    with pytest.raises(ObjectNotFoundError):
        cb.select(ReputationOverride, cert_override.id)
    print('Bulk Delete Reputation Overrides .............OK')
Exemplo n.º 24
0
def main():
    """Main function for the Policy Operations script."""
    parser = build_cli_parser("Policy operations")
    commands = parser.add_subparsers(help="Policy commands",
                                     dest="command_name")

    commands.add_parser("list", help="List all configured policies")

    import_policy_command = commands.add_parser(
        "import", help="Import policy from JSON file")
    import_policy_command.add_argument("-N",
                                       "--name",
                                       help="Name of new policy",
                                       required=True)
    import_policy_command.add_argument("-d",
                                       "--description",
                                       help="Description of new policy",
                                       required=True)
    import_policy_command.add_argument(
        "-p",
        "--prioritylevel",
        help="Priority level (HIGH, MEDIUM, LOW)",
        default="LOW")
    import_policy_command.add_argument(
        "-f",
        "--policyfile",
        help="Filename containing the JSON policy description",
        required=True)

    export_policy_command = commands.add_parser(
        "export", help="Export policy to JSON file")
    export_policy_specifier = export_policy_command.add_mutually_exclusive_group(
        required=False)
    export_policy_specifier.add_argument("-i",
                                         "--id",
                                         type=int,
                                         help="ID of policy")
    export_policy_specifier.add_argument("-N", "--name", help="Name of policy")

    del_command = commands.add_parser("delete", help="Delete policies")
    del_policy_specifier = del_command.add_mutually_exclusive_group(
        required=True)
    del_policy_specifier.add_argument("-i",
                                      "--id",
                                      type=int,
                                      help="ID of policy to delete")
    del_policy_specifier.add_argument(
        "-N",
        "--name",
        help="Name of policy to delete. Specify --force to delete"
        " multiple policies that have the same name")
    del_command.add_argument(
        "--force",
        help="If NAME matches multiple policies, delete all matching policies",
        action="store_true",
        default=False)

    add_rule_command = commands.add_parser(
        "add-rule", help="Add rule to existing policy from JSON rule file")
    add_rule_specifier = add_rule_command.add_mutually_exclusive_group(
        required=True)
    add_rule_specifier.add_argument("-i",
                                    "--id",
                                    type=int,
                                    help="ID of policy (can specify multiple)",
                                    action="append",
                                    metavar="POLICYID")
    add_rule_specifier.add_argument(
        "-N",
        "--name",
        help="Name of policy (can specify multiple)",
        action="append",
        metavar="POLICYNAME")
    add_rule_command.add_argument("-f",
                                  "--rulefile",
                                  help="Filename containing the JSON rule",
                                  required=True)

    del_rule_command = commands.add_parser(
        "del-rule", help="Delete rule from existing policy")
    del_rule_specifier = del_rule_command.add_mutually_exclusive_group(
        required=True)
    del_rule_specifier.add_argument("-i",
                                    "--id",
                                    type=int,
                                    help="ID of policy")
    del_rule_specifier.add_argument("-N", "--name", help="Name of policy")
    del_rule_command.add_argument("-r",
                                  "--ruleid",
                                  type=int,
                                  help="ID of rule",
                                  required=True)

    replace_rule_command = commands.add_parser(
        "replace-rule", help="Replace existing rule with a new one")
    replace_rule_specifier = replace_rule_command.add_mutually_exclusive_group(
        required=True)
    replace_rule_specifier.add_argument("-i",
                                        "--id",
                                        type=int,
                                        help="ID of policy")
    replace_rule_specifier.add_argument("-N", "--name", help="Name of policy")
    replace_rule_command.add_argument("-r",
                                      "--ruleid",
                                      type=int,
                                      help="ID of rule",
                                      required=True)
    replace_rule_command.add_argument("-f",
                                      "--rulefile",
                                      help="Filename containing the JSON rule",
                                      required=True)

    args = parser.parse_args()
    cb = get_cb_cloud_object(args)

    if args.command_name == "list":
        return list_policies(cb, parser, args)
    elif args.command_name == "import":
        return import_policy(cb, parser, args)
    elif args.command_name == "export":
        return export_policy(cb, parser, args)
    elif args.command_name == "delete":
        return delete_policy(cb, parser, args)
    elif args.command_name == "add-rule":
        return add_rule(cb, parser, args)
    elif args.command_name == "del-rule":
        return del_rule(cb, parser, args)
    elif args.command_name == "replace-rule":
        return replace_rule(cb, parser, args)
def main():
    """Script entry point"""
    global ORG_KEY
    global HOSTNAME
    parser = build_cli_parser()
    args = parser.parse_args()
    print_detail = args.verbose

    if print_detail:
        print(f"profile being used is {args.__dict__}")

    cb = get_cb_cloud_object(args)
    HEADERS['X-Auth-Token'] = cb.credentials.token
    ORG_KEY = cb.credentials.org_key
    HOSTNAME = cb.credentials.url

    print()
    print(18 * ' ', 'Vulnerability Organization Level')
    print(SYMBOLS * DELIMITER)

    api_results = get_vulnerability_summary()
    sdk_results = cb.select(Vulnerability.OrgSummary).submit()
    assert api_results == sdk_results._info, 'Test Failed Expected: {} Actual: {}'.\
        format(api_results, sdk_results)
    print('Get Vulnerability Summary...........................................OK')
    api_results = get_vulnerability_summary(severity='LOW')
    sdk_results = cb.select(Vulnerability.OrgSummary).set_severity('LOW').submit()
    assert api_results == sdk_results._info, 'Test Failed Expected: {} Actual: {}'.\
        format(api_results, sdk_results)
    print('Get Vulnerability Summary with severity.............................OK')
    data = {
        "criteria": {
            "severity": {
                "value": "LOW",
                "operator": "EQUALS"
            },
            "os_type": {
                "value": "WINDOWS",
                "operator": "EQUALS"
            }
        }
    }
    api_results = search_vulnerability_summary(data)['results']
    query = cb.select(Vulnerability.AssetView).set_severity('LOW', 'EQUALS') \
                                              .set_os_type('WINDOWS', 'EQUALS')
    sdk_results = [asset for asset in query]
    assert api_results == sdk_results, 'Test Failed Expected: {} Actual: {}'.\
        format(api_results, sdk_results)
    print('Get Asset View with Vulnerability Summary...........................OK')

    data = {
        'criteria': {'severity': {'value': 'LOW', 'operator': 'EQUALS'}},
        'sort': [{'field': 'highest_risk_score', 'order': 'DESC'}],
        'rows': 5
    }
    api_results = search_vulnerabilities(data=data)
    query = cb.select(Vulnerability).set_severity('LOW', 'EQUALS').sort_by('highest_risk_score', 'DESC')
    sdk_results = [x._info for x in query[:5]]
    assert api_results == sdk_results, 'Test Failed Expected: {} Actual: {}'.\
        format(api_results, sdk_results)
    print('Get Vulnerability List for Specific OS and Application..............OK')

    print()
    print(22 * ' ', 'Device Vulnerability Level')
    print(SYMBOLS * DELIMITER)

    device = cb.select(Device).set_status(['ACTIVE']).first()
    DEVICE_ID = device.id

    api_results = get_specific_device_summary(device_id=DEVICE_ID)
    sdk_results = device.get_vulnerability_summary()
    assert api_results == sdk_results, 'Test Failed Expected: {} Actual: {}'.\
        format(api_results, sdk_results)
    print('Get Vulnerability Summary for a specific device.....................OK')

    query = device.get_vulnerabilties()
    api_results = get_specific_device_list(device_id=DEVICE_ID)
    sdk_results = [x._info for x in query]

    CVE_ID = sdk_results[0]["cve_id"]

    assert api_results == sdk_results, 'Test Failed Expected: {} Actual: {}'.\
        format(api_results, sdk_results)
    print('Get Vulnerabilities for a specific device...........................OK')

    device = cb.select(Device, DEVICE_ID)
    sdk_results = device.vulnerability_refresh()
    sdk_results.pop('updated_at')
    api_results = refresh_device(device_id=DEVICE_ID)
    api_results.pop('updated_at')
    assert api_results == sdk_results, 'Test Failed Expected: {} Actual: {}'.\
        format(api_results, sdk_results)
    print('Perform an action on a specific device..............................OK')

    print()
    print(25 * ' ', 'Vulnerability Level')
    print(SYMBOLS * DELIMITER)

    CVE_ID = 'CVE-2008-5915'

    api_results = get_vulnerability(cve_id=CVE_ID)
    vulnerability = None
    try:
        vulnerability = Vulnerability(cb, CVE_ID)
    except MoreThanOneResultError as ex:
        vulnerability = ex.results

    if type(vulnerability) == list:
        sdk_results = [vuln._info for vuln in vulnerability]

        # Select a singular vulnerabilty for follow up tests
        vulnerability = vulnerability[0]
    else:
        sdk_results = vulnerability._info

    assert api_results == sdk_results, 'Test Failed Expected: {} Actual: {}'.format(api_results, sdk_results)
    print('Get vulnerability details for a specific CVE ID.....................OK')

    api_response = get_affected_devices(cve_id=CVE_ID, data={'os_product_id': vulnerability.os_product_id})['results']
    query = vulnerability.get_affected_assets()
    sdk_results = []
    api_results = []
    for x in query:
        sdk_results.append({'device_id': x.id, 'type': x.deployment_type, 'name': x.vm_name, 'host_name': x.name})
    for x in api_response:
        api_results.append({'device_id': x['device_id'],
                            'type': x['type'],
                            'name': x['name'],
                            'host_name': x['host_name']})
    assert api_results == sdk_results, 'Test Failed Expected: {} Actual: {}'.\
        format(api_results, sdk_results)
    print('Get Affected Assets for Specific Vulnerability......................OK')
def main():
    """Script entry point"""
    global ORG_KEY
    global HOSTNAME
    parser = build_cli_parser()
    args = parser.parse_args()
    print_detail = args.verbose

    if print_detail:
        print(f"args provided {args}")

    cb = get_cb_cloud_object(args)
    HEADERS['X-Auth-Token'] = cb.credentials.token
    ORG_KEY = cb.credentials.org_key
    HOSTNAME = cb.credentials.url

    print(13 * ' ' + 'Live Response Commands')
    print(SYMBOLS * DELIMITER)

    try:
        device = cb.select(Device, DEVICE_ID)
    except Exception:
        # if this is not run on dev01, pick a random active device
        devices = cb.select(Device).set_status(['ACTIVE'])
        device = devices[0]

    lr_session = device.lr_session()
    print(f'Created Session {lr_session.session_id}...............OK')
    print()

    # create the file that will be uploaded on the server,
    # will be deleted once we are done with the test
    fp = open("test.txt", "w")
    fp.write(FILE_CONTENT)
    fp.close()

    print()
    print(10 * ' ' + 'Live Response Files Commands')
    print(SYMBOLS * DELIMITER)

    # create directory
    try:
        lr_session.create_directory(DIR)
    except LiveResponseError as ex:
        if 'ERROR_ALREADY_EXISTS' in str(ex):
            print('Directory already exists, continue with the test.')
        else:
            raise
    print('Create Dir....................................OK')

    # show that test.txt is not present in that directory
    response = lr_session.list_directory(DIR)
    directories = flatten_response(response)
    assert 'test.txt' not in directories, f'Dirs: {directories}'

    # upload the file on the server
    lr_session.put_file(open("test.txt", "r"), FILE)
    print('PUT File......................................OK')

    # show that test.txt is present in that directory
    response = lr_session.list_directory(DIR)
    directories = flatten_response(response)
    assert 'test.txt' in directories, f'Dirs: {directories}'

    # walk through the directories
    for entry in lr_session.walk(DIR):
        print(entry)
    print('WALK dir......................................OK')

    content = lr_session.get_file(FILE)
    assert content == FILE_CONTENT_BINARY, f'{content} {FILE_CONTENT}'
    print('GET File......................................OK')
    lr_session.delete_file(FILE)

    exc_raise = False
    try:
        content = lr_session.get_file(FILE)
    except LiveResponseError as ex:
        assert 'ERROR_FILE_NOT_FOUND' in str(
            ex) or 'ERROR_PATH_NOT_FOUND' in str(ex), f'Other error {ex}'
        exc_raise = True
    finally:
        assert exc_raise
    print('DELETE File...................................OK')
    # delete the directory too
    lr_session.delete_file(DIR)
    print('DELETE Dir....................................OK')

    # This command takes a lot of time!
    # uncomment only if this needs to be tested!
    """
    lr_session.memdump(LOCAL_FILE, MEMDUMP_FILE)
    assert path.exists(LOCAL_FILE)
    exc_raise = False
    try:
        content = lr_session.get_file(MEMDUMP_FILE)
    except LiveResponseError as ex:
        assert 'ERROR_FILE_NOT_FOUND' in str(ex), f'Other error {ex}'
        exc_raise = True
    finally:
        assert exc_raise
    print('Memdump.......................................OK')
    """

    print()
    print(9 * ' ' + 'Live Response Process Commands')
    print(SYMBOLS * DELIMITER)

    # list processes
    processes = lr_session.list_processes()
    pprint(flatten_processes_response(processes))
    print('List Processes................................OK')

    # create infinite ping, that could be killed afterwards
    lr_session.create_process(r'cmd.exe /c "ping.exe -t 127.0.0.1"',
                              wait_for_completion=False,
                              wait_for_output=False)
    processes = lr_session.list_processes()
    found = False
    for process in processes:
        if 'ping.exe' in process['process_path']:
            found = True

    # assert that indeed there is such a process
    assert found
    print('Create Process................................OK')

    # kill all of the processes that are for ping.exe
    for pid in flatten_processes_response_filter(processes, 'ping.exe'):
        print(f'Killing process with pid {pid}')
        lr_session.kill_process(pid)
    print('Kill Process..................................OK')

    print()
    print(6 * ' ' + 'Live Response Registry Keys Commands')
    print(SYMBOLS * DELIMITER)

    result = lr_session.list_registry_keys_and_values(KEY_PATH_PARENT)
    pprint(result)
    print('List Registry Keys and Values.................OK')

    found = False
    for item in result['values']:
        if item['registry_name'] == 'Test':
            found = True
            break
    # make sure the value for the key doesn't exist
    assert found is False

    exists = True
    try:
        result = lr_session.list_registry_keys_and_values(KEY_PATH)
        print(result)
    except LiveResponseError as ex:
        # make sure such registry key does not exist
        exists = not ('ERROR_FILE_NOT_FOUND' in str(ex))
    assert exists is False
    print(f'Registry key with path {KEY_PATH} does not exist. Creating...')

    lr_session.create_registry_key(KEY_PATH)
    exists = True
    try:
        result = lr_session.list_registry_keys_and_values(KEY_PATH)
    except LiveResponseError as ex:
        exists = False
        assert 'ERROR_FILE_NOT_FOUND' in str(ex)
    # make sure that now the key exists
    assert exists
    print('Create Registry Key...........................OK')

    # create value for the key
    lr_session.set_registry_value(KEY_PATH, 1)
    result = lr_session.get_registry_value(KEY_PATH)
    assert result['registry_data'] == '1'
    assert result['registry_name'] == 'Test'
    print('Create Registry Value.........................OK')

    pprint(result)
    print('Get Registry Value............................OK')

    result = lr_session.list_registry_keys_and_values(KEY_PATH_PARENT)
    pprint(result)
    print('List Registry Keys and Values.................OK')

    found = False
    for item in result['values']:
        if item['registry_name'] == 'Test':
            found = True
            break
    # make sure the value for the key exists
    assert found is True

    result = lr_session.delete_registry_value(KEY_PATH)
    deleted = False
    try:
        result = lr_session.get_registry_value(KEY_PATH)
    except LiveResponseError as ex:
        deleted = 'ERROR_FILE_NOT_FOUND' in str(ex)
    # make sure the value is deleted
    assert deleted
    print('Delete Registry Value.........................OK')

    result = lr_session.list_registry_keys_and_values(KEY_PATH_PARENT)
    found = False
    for item in result['values']:
        if item['registry_name'] == 'Test':
            found = True
            break
    # make sure the value for the key was deleted successfully
    assert found is False

    result = lr_session.delete_registry_key(KEY_PATH)
    exists = True
    try:
        result = lr_session.list_registry_keys_and_values(KEY_PATH)
    except LiveResponseError as ex:
        # make sure such registry key does not exist
        exists = False
        assert 'ERROR_FILE_NOT_FOUND' in str(ex)
    assert exists is False, 'Registry key was not properly deleted.'
    print('Delete Registry Key...........................OK')

    # clean-up actions after the tests
    if path.exists(LOCAL_FILE):
        os.remove(LOCAL_FILE)
    if path.exists("test.txt"):
        os.remove("test.txt")

    lr_session.close()
    print(f'Deleted the session {lr_session.session_id}...........OK')
def main():
    """Main function of the process events script."""
    parser = build_cli_parser()
    parser.add_argument("--query",
                        "-q",
                        type=str,
                        help="Query string for the search",
                        default=None)
    parser.add_argument(
        "--include",
        "-i",
        action='append',
        type=str,
        help="Specifies included event field values, as key=value")
    parser.add_argument(
        "--exclude",
        "-x",
        action='append',
        type=str,
        help="Specifies excluded event field values, as key=value")
    parser.add_argument("--fields",
                        "-f",
                        action='append',
                        type=str,
                        help="Specifies names of fields to include")
    parser.add_argument("--numrows",
                        "-n",
                        type=int,
                        help="Maximum number of rows to be returned",
                        default=None)
    parser.add_argument(
        "--group",
        "-g",
        type=str,
        help="Field to group by, either device_id or process_sha256",
        default=None)
    parser.add_argument("--timeout",
                        "-T",
                        type=int,
                        help="Timeout for the search in milliseconds",
                        default=None)

    args = parser.parse_args()
    cb = get_cb_cloud_object(args)

    query = cb.select(EnrichedEvent)
    if args.query:
        query.where(args.query)
    inclusions = parse_key_value_pairs(args.include)
    for (key, value) in inclusions:
        query.update_criteria(key, value)
    exclusions = parse_key_value_pairs(args.exclude)
    for (key, value) in exclusions:
        query.add_exclusion(key, value)
    if args.fields:
        query.set_fields(args.fields)
    if args.numrows:
        query.set_rows(args.numrows)
    if args.group:
        query.aggregation(args.group)
    if args.timeout:
        query.timeout(args.timeout)

    separator = False
    for event in query:
        if separator:
            print(
                "------------------------------------------------------------------------\n"
            )
        separator = True
        print(f"{event}\n")
def main():
    """Script entry point"""
    global ORG_KEY
    global HOSTNAME
    parser = build_cli_parser()
    args = parser.parse_args()
    print_detail = args.verbose

    if print_detail:
        print(f"profile being used is {args.__dict__}")

    cb = get_cb_cloud_object(args)
    HEADERS['X-Auth-Token'] = cb.credentials.token
    ORG_KEY = cb.credentials.org_key
    HOSTNAME = cb.credentials.url

    # USB Device Approvals
    """USB Device Control Approval"""
    print('USB Device Control Approvals')
    print(SYMBOLS * DELIMITER)

    # create the usb device approval
    data = [{
        "vendor_id": "0x0781",
        "product_id": "0x5581",
        "serial_number": "4C531001331122115172",
        "notes": "A few notes",
        "approval_name": "Example Approval"
    }]
    sdk_result = USBDeviceApproval.bulk_create(cb, data)
    sdk_created_obj = sdk_result[0]

    sdk_obj = USBDeviceApproval(cb, sdk_created_obj.id)
    api_result = get_usb_device_approval_by_id_api(sdk_created_obj.id).json()
    dict_sdk_obj = sdk_obj._info
    assert api_result == dict_sdk_obj, 'Get Approval by ID Failed - ' \
           'Expected: {}, Actual: {}'.format(api_result, dict_sdk_obj)
    print('Get Approval by ID............................OK')

    # get the USB Device Approval
    query = cb.select(USBDeviceApproval)
    sdk_results = []
    for approval in query:
        if approval.id == sdk_created_obj.id:
            print('Bulk Create Test..............................OK')
        sdk_results.append(approval._info)
    api_search = search_usb_device_approval().json()['results']
    assert sdk_results == api_search, 'Search Test Failed Expected: {}, ' \
        'Actual: {}'.format(api_search, sdk_results)
    print('Search Test...................................OK')

    # update the object
    sdk_created_obj.approval_name = 'Changed Approval'
    sdk_created_obj._update_object()
    sdk_created_new = None
    query = cb.select(USBDeviceApproval)
    sdk_created_new = query[0]
    assert sdk_created_new.approval_name == 'Changed Approval', 'Update Test '\
        'Failed - Excepted: {}, Actual: {}'.format(
            sdk_created_obj._info,
            sdk_created_new._info)
    print('Update Test...................................OK')

    # delete the usb approval
    if sdk_created_obj is not None:
        sdk_created_obj.delete()
    query = cb.select(USBDeviceApproval)
    assert query._total_results == 0, 'Delete Approval Test Failed - Record '\
        'was not deleted... {}'.format(query._total_results)
    print('Delete Approval...............................OK')
    print(NEWLINES * '\n')
    """USB Device Control Blocks"""
    print('USB Device Control Blocks')
    print(SYMBOLS * DELIMITER)

    # create the usb device block
    data = ["6997287"]
    sdk_result = USBDeviceBlock.bulk_create(cb, data)
    sdk_created_obj = sdk_result[0]

    api_result = get_usb_device_block_by_id_api(sdk_created_obj.id).json()
    block_obj = USBDeviceBlock(cb, sdk_created_obj.id)
    dict_block_obj = block_obj._info
    assert dict_block_obj == api_result, 'Get Block by ID Failed - Expected: '\
        '{}, Actual: {}'.format(api_result, dict_block_obj)
    print('Get Block by ID...............................OK')
    # get the USB Device Block
    query = cb.select(USBDeviceBlock)
    sdk_results = []
    for block in query:
        if block.id == sdk_created_obj.id:
            print('Bulk Create Test..............................OK')
        sdk_results.append(block._info)
    api_search = search_usb_device_blocks().json()['results']
    assert sdk_results == api_search, 'Search Test Failed Expected: {}, ' \
        'Actual: {}'.format(api_search.json()['results'], sdk_results)
    print('Search Test...................................OK')

    # delete the usb approval
    if sdk_created_obj is not None:
        sdk_created_obj.delete()
    query = cb.select(USBDeviceBlock)
    assert query._total_results == 0, 'Delete Block Failed - Record was not '\
        'deleted... {}'.format(query._total_results)
    print('Delete Block..................................OK')
    print(NEWLINES * '\n')
    """USB Devices"""
    print('USB Devices')
    print(SYMBOLS * DELIMITER)

    query = cb.select(USBDevice)
    sdk_results = []
    for device in query:
        sdk_results.append(device._info)
    api_search = search_usb_devices().json()
    assert api_search['num_found'] == query._total_results, 'Device Search ' \
           'Failed - Expected: {}, Actual: {}'.format(api_search['num_found'],
                                                      query._total_results)
    assert sdk_results == api_search['results'], 'Device Search Test Failed -'\
        'Expected: {}, Actual: {}'.format(api_search['results'], sdk_results)
    print('Device Search.................................OK')

    # Facet USB Devices
    query = cb.select(USBDevice).facets(["status"])
    api_search = search_usb_devices_facets().json()
    assert query == api_search['terms'], 'Facet USB Devices Failed - Expected'\
        ': {}, Actual: {}'.format(api_search['terms'], query)
    print('Facet USB Devices.............................OK')
    print(NEWLINES * '\n')

    # vendors and products
    print('Testing Get USB Device Vendors and Products Seen')
    print(SYMBOLS * DELIMITER)
    api_result = get_products_n_vendors_api()
    sdk_result = USBDevice.get_vendors_and_products_seen(cb)
    api_results = api_result.json()['results']
    assert api_results == sdk_result, 'Get USB Device Vendors and Products '\
        'Failed - Expected: {}, Actual: {}'.format(api_results, sdk_result)
    print('Get USB Device Vendors and Products Seen......OK')
def main():
    """Export two csv files based on policy APPLIED and NOT_APPLIED to current directory"""
    args = get_args()
    cb = get_cb_cloud_object(args)

    now = datetime.now().strftime('%Y%m%d%H%M%S')
    sep = "|"

    alerts_stopped = cb.select(CBAnalyticsAlert).set_policy_applied(['APPLIED'])
    alerts_detected = cb.select(CBAnalyticsAlert).set_policy_applied(['NOT_APPLIED'])

    if args.severity:
        alerts_stopped = alerts_stopped.set_minimum_severity(args.severity)
        alerts_detected = alerts_detected.set_minimum_severity(args.severity)

    if args.range:
        alerts_stopped = alerts_stopped.set_time_range('last_update_time', range=f'-{args.range}')
        alerts_detected = alerts_detected.set_time_range('last_update_time', range=f'-{args.range}')

    try:
        if len(alerts_stopped) > 0:
            print(f'Writing Attacks Stopped to: attacks_stopped_{now}.csv')
            with open(f'attacks_stopped_{now}.csv', 'w') as stopped:
                stopped.write('Alert ID,Alert,ThreatScore,TargetPriority,Vector,Stage,First Seen,DeviceHostName,'
                              'Username,Policy,On/Off Premise,TTPs,ThreatCategory,RunState,PolicyAppliedState,'
                              'Dismissed,Reputation\n')
                for alert in alerts_stopped:
                    stopped.write(f'{alert.id},')  # Alert ID
                    stopped.write(f'{alert.reason},')  # Alert
                    stopped.write(f'{alert.severity},')  # ThreatScore
                    stopped.write(f'{alert.target_value},')  # TargetPriority
                    stopped.write(f'{alert.threat_cause_vector},')  # Vector
                    stopped.write(f'{sep.join(alert.kill_chain_status)},')  # Stage
                    stopped.write(f'{alert.first_event_time},')  # First Seen
                    stopped.write(f'{alert.device_name},')  # DeviceHostName
                    stopped.write(f'{alert.device_username},')  # Username
                    stopped.write(f'{alert.policy_name},')  # Policy
                    stopped.write(f'{alert.device_location},')  # On/Off Premise
                    ttps = set()
                    if alert.threat_indicators:
                        for indicator in alert.threat_indicators:
                            if indicator["ttps"]:
                                for ttp in indicator["ttps"]:
                                    ttps.add(ttp)
                    stopped.write(f'{sep.join(list(ttps))},')  # TTPs
                    stopped.write(f'{alert.threat_cause_threat_category},')  # ThreatCategory
                    stopped.write(f'{alert.run_state},')  # RunState
                    stopped.write(f'{alert.policy_applied},')  # PolicyAppliedState
                    stopped.write(f'{False if alert.workflow["state"] else True},')  # Dismissed
                    stopped.write(f'{alert.threat_cause_reputation},')  # Reputation
                    stopped.write('\n')

        if len(alerts_detected) > 0:
            print(f'Writing Attacks Detected to: attacks_detected_{now}.csv')
            with open(f'attacks_detected_{now}.csv', 'w') as detected:
                detected.write('Alert ID,Alert,ThreatScore,TargetPriority,Vector,Stage,First Seen,DeviceHostName,'
                               'Username,Policy,On/Off Premise,TTPs,ThreatCategory,RunState,PolicyAppliedState,'
                               'Dismissed,Reputation\n')
                for alert in alerts_detected:
                    detected.write(f'{alert.id},')  # Alert ID
                    detected.write(f'{alert.reason},')  # Alert
                    detected.write(f'{alert.severity},')  # ThreatScore
                    detected.write(f'{alert.target_value},')  # TargetPriority
                    detected.write(f'{alert.threat_cause_vector},')  # Vector
                    detected.write(f'{sep.join(alert.kill_chain_status)},')  # Stage
                    detected.write(f'{alert.first_event_time},')  # First Seen
                    detected.write(f'{alert.device_name},')  # DeviceHostName
                    detected.write(f'{alert.device_username},')  # Username
                    detected.write(f'{alert.policy_name},')  # Policy
                    detected.write(f'{alert.device_location},')  # On/Off Premise
                    ttps = set()
                    if alert.threat_indicators:
                        for indicator in alert.threat_indicators:
                            if indicator["ttps"]:
                                for ttp in indicator["ttps"]:
                                    ttps.add(ttp)
                    detected.write(f'{sep.join(list(ttps))},')  # TTPs
                    detected.write(f'{alert.threat_cause_threat_category},')  # ThreatCategory
                    detected.write(f'{alert.run_state},')  # RunState
                    detected.write(f'{alert.policy_applied},')  # PolicyAppliedState
                    detected.write(f'{False if alert.workflow["state"] else True},')  # Dismissed
                    detected.write(f'{alert.threat_cause_reputation},')  # Reputation
                    detected.write('\n')
    except Exception as e:
        print(f'Verify your args are valid. Exception {e}')