def main(): parser = build_cli_parser("Query processes") parser.add_argument("-p", type=str, help="process guid", default=None) parser.add_argument("-f", type=str, help="output file name", default=None) parser.add_argument("-of", type=str, help="output file format: csv or json", default="json") args = parser.parse_args() cb = get_cb_threathunter_object(args) if not args.p: print("Error: Missing Process GUID to query the process tree with") sys.exit(1) tree = cb.select(Process).where(process_guid=args.p)[0].tree() for idx, child in enumerate(tree.children): print("Child #{}".format(idx)) print("\tName: {}".format(child.process_name)) print("\tNumber of children: {}".format(len(child.children))) if args.f is not None: if args.of == "json": with open(args.f, 'w') as outfile: for idx, child in enumerate(tree.children): json.dump(child.original_document, outfile) else: with open(args.f, 'w') as outfile: csvwriter = csv.writer(outfile) for idx,child in enumerate(tree.children): csvwriter.writerow(child.original_document)
def main(): parser = build_cli_parser( "Search for cmd.exe writing to exe and dll filepaths") args = parser.parse_args() cb = get_cb_response_object(args) for proc in cb.select(Process).where( "process_name:cmd.exe (filemod:*.exe or filemod:*.dll)"): for fm in proc.filemods: if not fm.path.lower().endswith((".exe", ".dll")): continue signed = "" product_name = "" if fm.type == "LastWrote" and fm.md5: try: b = cb.select(Binary, fm.md5) signed = b.signed product_name = b.product_name except ObjectNotFoundError: pass print("%s,%s,%s,%s,%s,%s,%s,%s,%s" % (str(fm.timestamp), proc.hostname, proc.username, proc.path, fm.path, fm.type, fm.md5, signed, product_name))
def main(): parser = build_cli_parser() parser.add_argument("--filename", "-f", action="store", default=None, dest="filename", help="Filename to save the installer package to", required=True) parser.add_argument("--sensor-group", "-g", action="store", default="1", dest="group", help="Sensor group name or ID of the group to download an installer for") parser.add_argument("--installer-type", "-t", action="store", default="windows/exe", dest="type", help="Installer type; must be one of windows/exe, windows/msi, linux, osx") args = parser.parse_args() cb = get_cb_response_object(args) try: sensor_group_id = int(args.group) sensor_group = cb.select(SensorGroup, sensor_group_id, force_init=True) except (ValueError, ObjectNotFoundError): sensor_group = cb.select(SensorGroup).where('name:{0:s}'.format(args.group)).one() except Exception: print("Could not find sensor group via id or name ({0:s})".format(args.group)) return 1 # download the installer package # print("-> Downloading {0:s} installer for group {1:s} to file {2:s}...".format(args.type, sensor_group.name, args.filename)) try: open(args.filename, 'wb').write(sensor_group.get_installer(args.type)) except ObjectNotFoundError: print("** Could not find an installer for {0:s}".format(args.type)) except IOError: print("** Error writing to file {0:s}".format(args.filename)) except Exception as e: print("** Unknown exception: {0:s}".format(str(e))) else: print("-> Download complete")
def main(): parser = build_cli_parser( description="Export CbR Sensors from your environment as CSV") parser.add_argument("--output", "-o", dest="exportfile", help="The file to export to", required=True) parser.add_argument( "--fields", "-f", dest="exportfields", help="The fields to export", default= "id,hostname,group_id,network_interfaces,os_environment_display_string," "build_version_string,network_isolation_enabled,last_checkin_time", required=False) parser.add_argument("--query", "-q", dest="query", help="optional query to filter exported sensors", required=False) args = parser.parse_args() cb = get_cb_response_object(args) export_fields = args.exportfields.split(",") return export_sensors(cb, export_file_name=args.exportfile, export_fields=export_fields, query=args.query)
def main(): parser = build_cli_parser("Export watchlists into shareable JSON format") parser.add_argument("-f", "--file", help="Select what file output is written to", required=True) parser.add_argument( "-w", "--watchlists", help="Specific watchlist(s) to export. Can be comma separated.") parser.add_argument("-m", "--selective", action="store_true", help="Interactively select which watchlists to export") parser.add_argument("-d", "--description", help="Description for the watchlist export file") parser.add_argument("-a", "--author", help="Author for the watchlist export file") args = parser.parse_args() cb = get_cb_response_object(args) return export_watchlists(cb, args)
def main(): parser = build_cli_parser("Restart Cb Response sensors when certain criteria are met") parser.add_argument("--config", "-c", help="Configuration file path", default="restart_sensors.conf") parser.add_argument("--dryrun", "-d", help="Dry run - don't actually restart sensors", action="store_true") options = parser.parse_args() criteria = [c.strip() for c in open(options.config, "r").readlines()] criteria = [c for c in criteria if c != ""] print("Will restart sensors that have any of the following sensor health messages:") for c in criteria: print(" - {0}".format(c)) cb = get_cb_response_object(options) num_sensors_restarted = 0 for sensor in cb.select(Sensor): if sensor.sensor_health_message in criteria: print("Restarting sensor id {0} (hostname {1}) because its health message is {2}" .format(sensor.id, sensor.hostname, sensor.sensor_health_message)) num_sensors_restarted += 1 if not options.dryrun: sensor.restart_sensor() print("{0} {1} sensors.".format("Would have restarted" if options.dryrun else "Restarted", num_sensors_restarted))
def main(): parser = build_cli_parser() parser.add_argument("--query", help="binary query", default='') args = parser.parse_args() cb = get_cb_response_object(args) binary_query = cb.select(Binary).where(args.query) # for each result for binary in binary_query: print(binary.md5sum) print("-" * 80) print("%-20s : %s" % ('Size (bytes)', binary.size)) print("%-20s : %s" % ('Signature Status', binary.signed)) print("%-20s : %s" % ('Publisher', binary.digsig_publisher) if binary.signed else "%-20s : %s" % ('Publisher', 'n/a')) print("%-20s : %s" % ('Product Version', binary.product_version)) print("%-20s : %s" % ('File Version', binary.file_version)) print("%-20s : %s" % ('64-bit (x64)', binary.is_64bit)) print("%-20s : %s" % ('EXE', binary.is_executable_image)) for fn in binary.observed_filenames: print("%-20s : %s" % ('On-Disk Filename', fn.split('\\')[-1])) print('\n')
def main(): parser = build_cli_parser("Check datasharing settings on server") args = parser.parse_args() cb = get_cb_response_object(args) virustotal_groups = [] for sg in cb.select(SensorGroup): settings = cb.get_object("/api/v1/group/{0}/datasharing".format( sg.id)) or [] for setting in settings: if setting.get("what") == "BIN" and setting.get( "who") == "VIRUSTOTAL": virustotal_groups.append(sg) if len(virustotal_groups) == 0: print( "No sensor groups are configured to send unknown binaries to VirusTotal" ) return 0 elif len(virustotal_groups) == len(cb.select(SensorGroup)): print( "**ALL** sensor groups are configured to send unknown binaries to VirusTotal" ) return 1 else: print( "The following sensor groups are configured to send unknown binaries to VirusTotal:" ) for sg in virustotal_groups: print(" id {0}: {1}".format(sg.id, sg.name)) return 1
def main(): parser = build_cli_parser("Delete duplicate computers") parser.add_argument( "--dry-run", "-d", help="perform a dry run, don't actually delete the computers", action="store_true", dest="dry_run") args = parser.parse_args() p = get_cb_protection_object(args) computer_list = defaultdict(list) for computer in p.select(Computer).where("deleted:false"): computer_list[computer.name].append({ "id": computer.id, "offline": computer.daysOffline }) for computer_name, computer_ids in iteritems(computer_list): if len(computer_ids) > 1: sorted_computers = sorted(computer_ids, key=lambda x: x["offline"], reverse=True) for computer_id in sorted_computers[:-1]: if computer_id["offline"] > 0: print( "deleting computer id %d (offline %d days, hostname %s)" % (computer_id["id"], computer_id["offline"], computer_name)) if not args.dry_run: print("deleting from server...") p.select(Computer, computer_id["id"]).delete()
def main(): parser = build_cli_parser("Bulk resolve alerts") parser.add_argument("--query", action="store", default="", help="The query string of alerts to resolve. All matching alerts will be resolved.") args = parser.parse_args() cb = get_cb_response_object(args) alert_query = cb.select(Alert).where("-status:Resolved " + args.query) resolved_alerts = 0 for alert in alert_query: try: alert.status = "Resolved" alert.save() except ApiError as e: print("Error resolving {0:s}: {1:s}".format(alert.unique_id, str(e))) else: resolved_alerts += 1 print("Resolved {0:s}".format(alert.unique_id)) if resolved_alerts: print("Waiting for alert changes to take effect...") time.sleep(25) print("Complete. Resolved {0:d} alerts.".format(resolved_alerts)) else: print("Congratulations! You have no unresolved alerts!")
def main(): parser = build_cli_parser() parser.add_argument("--query", help="binary query", default='') args = parser.parse_args() cb = get_cb_response_object(args) for wn in watched_names: bq = "observed_filename:%s" % (wn) binaries = cb.select(Binary).where(bq) for binary in binaries: print("-" * 80) print "Filename: %s Filehash: %s" % (wn, binary.md5sum) print("-" * 80) pq = "process_md5:%s" % (binary.md5) # to limit the search to the previous 24 hours # comment out the above query and uncomment out the below query #pq = "process_md5:%s start:-1440m" % (binary.md5) procs = cb.select(Process).where(pq) proc_names = {} for proc in procs: if proc.process_name in ignored_names : pass else: try: proc_names[proc.process_name] +=1 except KeyError: proc_names[proc.process_name] = 1 for k in sorted(proc_names.keys()): print k + " = " + str(proc_names[k]) print('\n')
def main(): parser = build_cli_parser() commands = parser.add_subparsers(help="Watchlist commands", dest="command_name") list_command = commands.add_parser("list", help="List all configured watchlists") add_command = commands.add_parser("add", help="Add new watchlist") add_command.add_argument("-N", "--name", help="Name of watchlist", required=True) add_command.add_argument("-q", "--query", help="Watchlist query string, e.g. process_name:notepad.exe", required=True) add_command.add_argument("-t", "--type", help="Watchlist type 'events' or 'modules'", required=True) del_command = commands.add_parser("delete", help="Delete watchlists") del_watchlist_specifier = del_command.add_mutually_exclusive_group(required=True) del_watchlist_specifier.add_argument("-i", "--id", type=int, help="ID of watchlist to delete") del_watchlist_specifier.add_argument("-N", "--name", help="Name of watchlist to delete. Specify --force to delete" " multiple watchlists that have the same name") del_command.add_argument("--force", help="If NAME matches multiple watchlists, delete all matching watchlists", action="store_true", default=False) args = parser.parse_args() cb = get_cb_response_object(args) if args.command_name == "list": return list_watchlists(cb, parser, args) elif args.command_name == "add": return add_watchlist(cb, parser, args) elif args.command_name == "delete": return delete_watchlist(cb, parser, args)
def main(): parser = build_cli_parser("List CB Analytics alerts") setup_parser_with_cbanalytics_criteria(parser) 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_psc_object(args) query = cb.select(CBAnalyticsAlert) load_cbanalytics_criteria(query, args) if args.sort_by: direction = "DESC" if args.reverse else "ASC" query = query.sort_by(args.sort_by, direction) alerts = list(query) print("{0:40} {1:40s} {2:40s} {3}".format("ID", "Hostname", "Threat ID", "Last Updated")) for alert in alerts: print("{0:40} {1:40s} {2:40s} {3}".format(alert.id, alert.device_name or "None", alert.threat_id or "Unknown", alert.last_update_time))
def main(): parser = build_cli_parser() parser.add_argument("--query", help="binary query", default='') args = parser.parse_args() cb = get_cb_response_object(args) binary_query = cb.select(Binary).where(args.query) for binary in binary_query: s = datetime.datetime.strptime(binary.server_added_timestamp, "%Y-%m-%dT%H:%M:%S.%fZ") now = datetime.datetime.utcnow() dwell_time = now-s print(binary.md5sum) print("%-20s : %s" % ('Endpoint(s)', binary.endpoint)) print("%-20s : %s" % ('Dwell Time', dwell_time)) print("%-20s : %s" % ('First Seen', binary.server_added_timestamp)) print("%-20s : %s" % ('Size (bytes)', binary.size)) print "*"*80 proc_query = cb.select(Process).where('filewrite_md5:%s' % (binary.md5sum)) pd = {} for proc in proc_query: pd[proc.unique_id] = {} pd[proc.unique_id]['hostname'] = proc.hostname pd[proc.unique_id]['username'] = proc.username for fm in proc.filemods: if fm.type == "LastWrote" and fm.md5 == binary.md5sum.lower(): idt = now - fm.timestamp pd[proc.unique_id]['dwell_time'] = idt pd[proc.unique_id]['path'] = fm.path for entry in pd.keys(): print pd[entry]['hostname'], pd[entry]['username'], pd[entry]['dwell_time'], pd[entry]['path']
def main(): parser = build_cli_parser("Walk the children of a given process") group = parser.add_mutually_exclusive_group() group.add_argument("--process", "-p", help="process GUID to walk", default='') group.add_argument("--query", "-q", help="walk the children of all processes matching this query") args = parser.parse_args() c = get_cb_response_object(args) if args.process: try: procs = [c.select(Process, args.process, force_init=True)] except ObjectNotFoundError as e: print("Could not find process {0:s}".format(args.procss)) return 1 except ApiError as e: print("Encountered error retrieving process: {0:s}".format(str(e))) return 1 except Exception as e: print("Encountered unknown error retrieving process: {0:s}".format(str(e))) return 1 elif args.query: procs = c.select(Process).where(args.query) else: print("Requires either a --process or --query argument") parser.print_usage() return 2 for root_proc in procs: print("Process {0:s} on {1:s} executed by {2:s} children:".format(root_proc.path, root_proc.hostname, root_proc.username)) root_proc.walk_children(visitor) print("")
def main(): parser = build_cli_parser("Move a device into a new security policy") device_options = parser.add_mutually_exclusive_group(required=True) device_options.add_argument("-i", "--id", type=int, help="Device ID of sensor to move") device_options.add_argument("-n", "--hostname", help="Hostname to move") policy_options = parser.add_mutually_exclusive_group(required=True) policy_options.add_argument("--policyid", type=int, help="Policy ID") policy_options.add_argument("--policyname", help="Policy name") args = parser.parse_args() cb = get_cb_defense_object(args) if args.id: devices = [cb.select(Device, args.id)] else: devices = list(cb.select(Device).where("hostNameExact:{0}".format(args.hostname))) for device in devices: if args.policyid: destpolicy = int(args.policyid) device.policyId = int(args.policyid) else: destpolicy = args.policyname device.policyName = args.policyname device.save() print("Moved device id {0} (hostname {1}) into policy {2}".format(device.deviceId, device.name, destpolicy))
def main(): parser = build_cli_parser() commands = parser.add_subparsers(help="Storage Partition commands", dest="command_name") list_command = commands.add_parser("list", help="List all storage partitions") create_command = commands.add_parser("create", help="Create new active writer partition") del_command = commands.add_parser("delete", help="Delete partition") del_command.add_argument("-N", "--name", help="Name of partition to delete.", required=True) mount_command = commands.add_parser("mount", help="Mount partition") mount_command.add_argument("-N", "--name", help="Name of partition to mount.", required=True) unmount_command = commands.add_parser("unmount", help="Unmount partition") unmount_command.add_argument("-N", "--name", help="Name of partition to unmount.", required=True) args = parser.parse_args() cb = get_cb_response_object(args) if cb.cb_server_version < LooseVersion("6.1.0"): parser.error("This script can only work with server versions >= 6.1.0; {0} is running {1}" .format(cb.url, cb.cb_server_version)) return 1 if args.command_name == "list": return list_partitions(cb, parser, args) elif args.command_name == "create": return create_partition(cb, parser, args) elif args.command_name == "delete": return delete_partition(cb, parser, args) elif args.command_name == "mount": return mount_partition(cb, parser, args) elif args.command_name == "unmount": return unmount_partition(cb, parser, args)
def main(): parser = build_cli_parser("High avg. netconn/second alert") parser.add_argument("--skip-unknown", "-s", action="store_true", default=False, dest="skip_unknown", help="Skip processes with unknown start or last update") parser.add_argument("--rate", "-r", type=float, default=100.0, dest="conn_rate", help="Alert on processes with more than [--rate] network connections per second") parser.add_argument("--gt-count", "-g", type=int, default=100, dest="gt_count", help="Filter processes with greater than [--gt-count] network events") args = parser.parse_args() cb = get_cb_response_object(args) for proc in cb.select(Process).where("netconn_count:[{0:d} TO *]".format(args.gt_count)).sort("last_update desc"): try: runtime = (proc.last_update - proc.start).total_seconds() except Exception: if not args.skip_unknown: runtime = 1.0 else: continue if not runtime and proc.netconn_count > 0: # simulate "infinity" so as to avoid a DivideByZero exception rate = 1000000 else: rate = proc.netconn_count / float(runtime) if rate > args.conn_rate: print("{0:s}|{1:s}|{2:s}|{3:.4f}".format(proc.hostname, proc.username, proc.process_name, rate))
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_psc_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(): parser = build_cli_parser("CB Runner") subparsers = parser.add_subparsers(help="Sensor commands", dest="command_name") parser.add_argument("-J", "--job", action="store", required=False, default="job", help="Name of the job to run.") parser.add_argument("-LR", "--lrprofile", action="store", required=False, help="Live Response profile name configured in your \ credentials.psc file.") parser.add_argument( "-A", "--actions", required=True, help="CSV file with a list of actions to run in the format \ of 'DeviceId, DeviceName, Command, Resource'") args = parser.parse_args() cb_psc = get_cb_psc_object(args) cb_def = CbDefenseAPI(profile=args.lrprofile) run_actions(args.actions, cb_def, cb_psc, args)
def main(): parser = build_cli_parser("Bulk resolve alerts") parser.add_argument( "--query", action="store", default="", required=True, help= "The query string of alerts to resolve. All matching alerts will be resolved." ) args = parser.parse_args() cb = get_cb_response_object(args) alert_query = cb.select(Alert).where("-status:Resolved") alert_query = alert_query.where(args.query) alert_count = len(alert_query) if alert_count > 0: print("Resolving {0:d} alerts...".format(len(alert_query))) alert_query.change_status("Resolved") print("Waiting for alert changes to take effect...") time.sleep(25) print("Complete. Resolved {0:d} alerts.".format(alert_count)) else: print("Congratulations! You have no unresolved alerts!")
def main(): parser = build_cli_parser("Move a device into a new security policy") device_options = parser.add_mutually_exclusive_group(required=True) device_options.add_argument("-i", "--id", type=int, help="Device ID of sensor to move") device_options.add_argument("-n", "--hostname", help="Hostname to move") policy_options = parser.add_mutually_exclusive_group(required=True) policy_options.add_argument("--policyid", type=int, help="Policy ID") policy_options.add_argument("--policyname", help="Policy name") args = parser.parse_args() cb = get_cb_defense_object(args) if args.id: devices = [cb.select(Device, args.id)] else: devices = list(cb.select(Device).where("hostNameExact:{0}".format(args.hostname))) for device in devices: if args.policyid: destpolicy = int(args.policyid) device.policyId = int(args.policyid) else: destpolicy = args.policyname device.policyName = args.policyname device.save() print("Moved device id {0} (hostname {1}) into policy {2}".format(device.deviceId, device.name, destpolicy))
def main(): parser = build_cli_parser("Create a CbTH feed and report from a stream of IOCs") # Feed metadata arguments. parser.add_argument("--name", type=str, help="Feed name", required=True) parser.add_argument("--owner", type=str, help="Feed owner", required=True) parser.add_argument("--url", type=str, help="Feed provider url", required=True) parser.add_argument("--summary", type=str, help="Feed summary", required=True) parser.add_argument("--category", type=str, help="Feed category", required=True) parser.add_argument("--access", type=str, help="Feed access scope", default="private") # Report metadata arguments. parser.add_argument("--rep_timestamp", type=int, help="Report timestamp", default=int(time.time())) parser.add_argument("--rep_title", type=str, help="Report title", required=True) parser.add_argument("--rep_desc", type=str, help="Report description", required=True) parser.add_argument("--rep_severity", type=int, help="Report severity", default=1) parser.add_argument("--rep_link", type=str, help="Report link") parser.add_argument("--rep_tags", type=str, help="Report tags, comma separated") parser.add_argument("--rep_visibility", type=str, help="Report visibility") args = parser.parse_args() cb = get_cb_threathunter_object(args) feed_info = { "name": args.name, "owner": args.owner, "provider_url": args.url, "summary": args.summary, "category": args.category, "access": args.access, } rep_tags = [] if args.rep_tags: rep_tags = args.rep_tags.split(",") report = { "timestamp": args.rep_timestamp, "title": args.rep_title, "description": args.rep_desc, "severity": args.rep_severity, "link": args.rep_link, "tags": rep_tags, "iocs_v2": [], # NOTE(ww): The feed server will convert IOCs to v2s for us. } report_id, iocs = read_iocs(cb) report["id"] = report_id report["iocs"] = iocs feed = { "feedinfo": feed_info, "reports": [report] } feed = cb.create(Feed, feed) feed.save() print(feed)
def main(): parser = build_cli_parser("Bulk resolve alerts") parser.add_argument( "--query", action="store", default="", help= "The query string of alerts to resolve. All matching alerts will be resolved." ) args = parser.parse_args() cb = get_cb_response_object(args) alert_query = cb.select(Alert).where("-status:Resolved " + args.query) resolved_alerts = 0 for alert in alert_query: try: alert.status = "Resolved" alert.save() except ApiError as e: print("Error resolving {0:s}: {1:s}".format( alert.unique_id, str(e))) else: resolved_alerts += 1 print("Resolved {0:s}".format(alert.unique_id)) if resolved_alerts: print("Waiting for alert changes to take effect...") time.sleep(25) print("Complete. Resolved {0:d} alerts.".format(resolved_alerts)) else: print("Congratulations! You have no unresolved alerts!")
def main(): parser = build_cli_parser("Enumerate USB Devices") parser.add_argument("--start", "-s", action="store", default=None, dest="start_time", help="Start time (example: -2h)") args = parser.parse_args() cb = get_cb_response_object(args) query_string = r'regmod:registry\machine\system\currentcontrolset\control\deviceclasses\{53f56307-b6bf-11d0-94f2-00a0c91efb8b}\*' # noqa: E501 if args.start_time: query_string += ' start:{0:s}'.format(args.start_time) for proc in cb.select(Process).where(query_string): for rm in proc.regmods: if "{53f56307-b6bf-11d0-94f2-00a0c91efb8b}" in rm.path: pieces = rm.path.split("usbstor#disk&") if len(pieces) < 2: print("WARN:::: {0}".format(str(pieces))) else: device_info = pieces[ 1] # .split('{53f56307-b6bf-11d0-94f2-00a0c91efb8b}')[0] print(device_info)
def main(): parser = build_cli_parser( description="Automatic detection and response based on watchlists") parser.add_argument("--watchlists", "-w", dest="watchlists", help="The watchlists in question", required=True) parser.add_argument("--operation", "-o", dest="operation", help="The operation to perform", required=True, default="Isolate") parser.add_argument("--dryrun", "-d", dest="dryrun", help="Dry run mode", default=False, required=False) args = parser.parse_args() cb = get_cb_response_object(args) return sensor_operations(cb, watchlists=args.watchlists, operation=args.operation, dryrun=args.dryrun)
def main(): parser = build_cli_parser("Grab all binaries from a Cb server") parser.add_argument('-d', '--destdir', action='store', help='Destination directory to place the events', default=os.curdir) # TODO: we don't have a control on the "start" value in the query yet parser.add_argument('--query', action='store', dest='query', help='Query string to filter results', default=None) parser.add_argument('-v', action='store_true', dest='verbose', help='Enable verbose debugging messages', default=False) args = parser.parse_args() query = args.query cb = get_cb_response_object(args) if args.verbose: logging.basicConfig(level=logging.DEBUG) else: logging.basicConfig(level=logging.INFO) return dump_all_binaries(cb, args.destdir, query)
def main(): parser = build_cli_parser() parser.add_argument("-thp", "--threatprofile", help="Threat Hunter profile", default="default") commands = parser.add_subparsers(help="Feed commands", dest="command_name") list_command = commands.add_parser("list", help="List all configured feeds") list_reports_command = commands.add_parser( "list-reports", help="List all configured reports for a feed") list_reports_command.add_argument("-i", "--id", type=str, help="Feed ID") convert_feed_command = commands.add_parser( "convert", help="Convert feed from CB Response to CB Threat Hunter") convert_feed_command.add_argument("-i", "--id", type=str, help="Feed ID") args = parser.parse_args() cb = get_cb_response_object(args) cb_th = CbThreatHunterAPI(profile=args.threatprofile) if args.command_name == "list": return list_feeds(cb, parser, args) if args.command_name == "list-reports": return list_reports(cb, parser, args) if args.command_name == "convert": return convert_feed(cb, cb_th, parser, args)
def main(): parser = build_cli_parser("List VMware alert facets") setup_parser_with_vmware_criteria(parser) parser.add_argument("-F", "--facet", action="append", choices=[ "ALERT_TYPE", "CATEGORY", "REPUTATION", "WORKFLOW", "TAG", "POLICY_ID", "POLICY_NAME", "DEVICE_ID", "DEVICE_NAME", "APPLICATION_HASH", "APPLICATION_NAME", "STATUS", "RUN_STATE", "POLICY_APPLIED_STATE", "POLICY_APPLIED", "SENSOR_ACTION" ], required=True, help="Retrieve these fields as facet information") args = parser.parse_args() cb = get_cb_psc_object(args) query = cb.select(VMwareAlert) load_vmware_criteria(query, args) facetinfos = query.facets(args.facet) for facetinfo in facetinfos: print("For field '{0}':".format(facetinfo["field"])) for facetval in facetinfo["values"]: print("\tValue {0}: {1} occurrences".format( facetval["id"], facetval["total"]))
def main(): parser = build_cli_parser("List devices") device_options = parser.add_mutually_exclusive_group(required=False) device_options.add_argument("-i", "--id", type=int, help="Device ID of sensor") device_options.add_argument("-n", "--hostname", help="Hostname") args = parser.parse_args() cb = get_cb_defense_object(args) if args.id: devices = [cb.select(Device, args.id)] elif args.hostname: devices = list( cb.select(Device).where("hostNameExact:{0}".format(args.hostname))) else: devices = list(cb.select(Device)) 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.deviceId, device.name or "None", device.lastInternalIpAddress or "Unknown", device.lastContact))
def main(): parser = build_cli_parser("Query processes") parser.add_argument("-p", type=str, help="process guid", default=None) parser.add_argument("-f", type=str, help="output file name", default=None) parser.add_argument("-of", type=str, help="output file format: csv or json", default="json") args = parser.parse_args() cb = get_cb_threathunter_object(args) if not args.p: print("Error: Missing Process GUID to query the process tree with") sys.exit(1) tree = cb.select(Process).where(process_guid=args.p)[0].tree() for idx, child in enumerate(tree.children): print("Child #{}".format(idx)) print("\tName: {}".format(child.process_name)) print("\tNumber of children: {}".format(len(child.children))) if args.f is not None: if args.of == "json": with open(args.f, 'w') as outfile: for idx, child in enumerate(tree.children): json.dump(child.original_document, outfile) else: with open(args.f, 'w') as outfile: csvwriter = csv.writer(outfile) for idx, child in enumerate(tree.children): csvwriter.writerow(child.original_document)
def main(): 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_ids", nargs="+", type=str, required=False, help="Policy IDs to filter on", ) 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") args = parser.parse_args() cb = get_cb_livequery_object(args) if args.command_name == "create": return create_run(cb, args) elif args.command_name == "status": return run_status(cb, args)
def main(): parser = cbhelper.build_cli_parser() parser.add_argument("--guid", dest="guid", help="GUID of target process",required=True) args = parser.parse_args() cbapi = cbhelper.get_cb_response_object(args) repgen = IncidentReportGenerator(cbapi=cbapi) print("[+] Generating report for process guid: {}\n".format(args.guid)) repgen.generate_report(guid=args.guid, verbose=True if args.verbose else False)
def main(): parser = build_cli_parser() parser.add_argument("--job", action="store", default="examplejob", required=True) args = parser.parse_args() cb = get_cb_defense_object(args) sensor_query = cb.select(Device) # Retrieve the list of sensors that are online # calculate based on sensors that have checked in during the last five minutes now = datetime.utcnow() delta = timedelta(minutes=5) online_sensors = [] offline_sensors = [] for sensor in sensor_query: if now - sensor.lastContact < delta: online_sensors.append(sensor) else: offline_sensors.append(sensor) print("The following sensors are offline and will not be queried:") for sensor in offline_sensors: print(" {0}: {1}".format(sensor.deviceId, sensor.name)) print("The following sensors are online and WILL be queried:") for sensor in online_sensors: print(" {0}: {1}".format(sensor.deviceId, sensor.name)) # import our job object from the jobfile job = __import__(args.job) jobobject = job.getjob() completed_sensors = [] futures = {} # collect 'future' objects for all jobs for sensor in online_sensors: f = cb.live_response.submit_job(jobobject.run, sensor) futures[f] = sensor.deviceId # iterate over all the futures for f in as_completed(futures.keys(), timeout=100): if f.exception() is None: print("Sensor {0} had result:".format(futures[f])) print(f.result()) completed_sensors.append(futures[f]) else: print("Sensor {0} had error:".format(futures[f])) print(f.exception()) still_to_do = set([s.deviceId for s in online_sensors]) - set(completed_sensors) print("The following sensors were attempted but not completed or errored out:") for sensor in still_to_do: print(" {0}".format(still_to_do))
def main(): parser = build_cli_parser("Download device list in CSV format") 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") parser.add_argument("-O", "--output", help="File to save output to (default stdout)") args = parser.parse_args() cb = get_cb_psc_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) data = query.download() if args.output: file = open(args.output, "w") file.write(data) file.close() else: print(data)
def main(): parser = build_cli_parser("Add an MD5 hash to the banned hash list in Cb Response") parser.add_argument("-H", "--hash", help="MD5 hash of the file to ban in Cb Response", required=True) parser.add_argument("-d", "--description", help="Description of why the hash is banned") args = parser.parse_args() cb = get_cb_response_object(args) return ban_hash(cb, args)
def main(): parser = build_cli_parser(description="Automatic detection and response based on watchlists") parser.add_argument("--watchlists", "-w", dest="watchlists", help="The watchlists in question", required=True) parser.add_argument("--operation", "-o", dest="operation", help="The operation to perform", required=True, default="Isolate") parser.add_argument("--dryrun", "-d", dest="dryrun", help="Dry run mode", default=False, required=False) args = parser.parse_args() cb = get_cb_response_object(args) return sensor_operations(cb, watchlists=args.watchlists, operation=args.operation, dryrun=args.dryrun)
def main(): parser = build_cli_parser("Cb Defense Live Response example") parser.add_argument("sensorid", nargs=1) args = parser.parse_args() c = get_cb_defense_object(args) sensor = c.select(Device, int(args.sensorid[0])) run_liveresponse(sensor.lr_session())
def main(): parser = build_cli_parser("Walk the children of a given process") group = parser.add_mutually_exclusive_group() group.add_argument("--process", "-p", help="process GUID to walk", default='') group.add_argument( "--query", "-q", help="walk the children of all processes matching this query") parser.add_argument("--children", "-c", default=15, help="number of children to fetch") args = parser.parse_args() c = get_cb_response_object(args) if args.process: try: procs = [ c.select(Process, args.process, max_children=args.children, force_init=True) ] except ObjectNotFoundError as e: print("Could not find process {0:s}".format(args.procss)) return 1 except ApiError as e: print("Encountered error retrieving process: {0:s}".format(str(e))) return 1 except Exception as e: print("Encountered unknown error retrieving process: {0:s}".format( str(e))) return 1 elif args.query: procs = c.select(Process).where( args.query).group_by("id").max_children(args.children) else: print("Requires either a --process or --query argument") parser.print_usage() return 2 for root_proc in procs: if not root_proc.get('terminated'): duration = "still running" else: duration = str(root_proc.end - root_proc.start) print("Process {0:s} on {1:s} executed by {2:s}:".format( root_proc.cmdline, root_proc.hostname, root_proc.username)) print("started at {0} ({1})".format(str(root_proc.start), duration)) print("Cb Response console link: {0}".format(root_proc.webui_link)) root_proc.walk_children(visitor) print("")
def main(): parser = build_cli_parser("Print processes") args = parser.parse_args() args.profile="default" cb = get_cb_response_object(args) for proc in cb.select(Process).where("process_name:notepad.exe hostname:w2k12"): print proc print "############"
def main(): parser = build_cli_parser("Listen to real-time notifications") parser.add_argument("-s", type=int, help="# of seconds to sleep between polls", default=30) args = parser.parse_args() cb = get_cb_defense_object(args) while True: for notification in cb.notification_listener(args.s): print(json.dumps(notification, indent=2))
def main(): parser = build_cli_parser("Import watchlists from shareable JSON format") parser.add_argument("-f", "--file", help="Select what file watchlists are read from", required=True) parser.add_argument("-w", "--watchlists", help="Specific watchlist(s) to import. Can be comma separated.") parser.add_argument("-m", "--selective", action="store_true", help="Interactively select which watchlists to import") args = parser.parse_args() cb = get_cb_response_object(args) return import_watchlists(cb, args)
def main(): parser = build_cli_parser("Push notifications to mobile phone") # Parse command line arguments and retrieve Cb Defense API credentials args = parser.parse_args() cb = get_cb_defense_object(args) # Note that the following is essentially an infinite loop - it will keep asking for notifications from # the Cb Defense server every 30 seconds forever... for notification in cb.notification_listener(interval=30): print(notification)
def main(): parser = build_cli_parser(description="Export CbR Sensors from your environment as CSV") parser.add_argument("--output", "-o", dest="exportfile", help="The file to export to", required=True) parser.add_argument("--fields", "-f", dest="exportfields", help="The fields to export", default="id,hostname,group_id,network_interfaces,os_environment_display_string,build_version_string,network_isolation_enabled,last_checkin_time", required=False) parser.add_argument("--query", "-q", dest="query", help="optional query to filter exported sensors", required=False) args = parser.parse_args() cb = get_cb_response_object(args) export_fields = args.exportfields.split(",") return export_sensors(cb, export_file_name=args.exportfile, export_fields=export_fields, query=args.query)
def main(): parser = build_cli_parser("List Events for a device") event_options = parser.add_mutually_exclusive_group(required=False) event_date_options = parser.add_argument_group("Date Range Arguments") event_date_options.add_argument("--start", help="start time") event_date_options.add_argument("--end", help="end time") event_options.add_argument("-n", "--hostname", help="Hostname") args = parser.parse_args() cb = get_cb_defense_object(args) if args.hostname: events = list( cb.select(Event).where("hostNameExact:{0}".format(args.hostname))) elif args.start and args.end: # flipped the start and end arguments around so script can be called with the start date # being the earliest date. it's just easier on the eyes for most folks. events = list( cb.select(Event).where("startTime:{0}".format( args.end))) and (cb.select(Event).where("endTime:{0}".format( args.start))) else: events = list(cb.select(Event)) # print the column headers print( "Event Time|Event ID|Create Time|Event Type|Description|Command Line") for event in events: # convert event and create times event_time = str(convert_time(event.createTime)) create_time = str(convert_time(event.eventTime)) # stripping HTML tags out of the long description long_description = unicodedata.normalize( 'NFD', strip_html(event.longDescription)) if event.processDetails: # stripping out the command line arguments from the processDetails field processDetails = str(event.processDetails) start_cmdline = processDetails.find("u'commandLine'") end_cmdline = processDetails.find(", u'parentName'") commandline = processDetails[start_cmdline + 18:end_cmdline - 1] print("{0}|{1}|{2}|{3}|{4}|{5}".format(event_time, event.eventId, create_time, event.eventType, long_description, commandline)) else: print("{0}|{1}|{2}|{3}|{4}".format(event_time, event.eventId, create_time, event.eventType, long_description))
def main(): parser = build_cli_parser("VirusTotal Connector") parser.add_argument("--config", "-c", help="Path to configuration file", default="virustotal.ini") args = parser.parse_args() inifile = RawConfigParser({ "vt_api_key": None, "retrieve_files": "true", "upload_binaries_to_vt": "false", "connector_name": "VirusTotal", "log_file": None, }) inifile.read(args.config) config = {} config["vt_api_key"] = inifile.get("bridge", "vt_api_key") config["retrieve_files"] = inifile.getboolean("bridge", "retrieve_files") config["connector_name"] = inifile.get("bridge", "connector_name") config["upload_binaries_to_vt"] = inifile.getboolean( "bridge", "upload_binaries_to_vt") log_file = inifile.get("bridge", "log_file") if log_file: file_handler = logging.FileHandler(log_file) formatter = logging.Formatter('%(asctime)s %(levelname)s:%(message)s') file_handler.setFormatter(formatter) file_handler.setLevel(logging.DEBUG) logging.getLogger().addHandler(file_handler) if not config["vt_api_key"]: log.fatal("Cannot start without a valid VirusTotal API key, exiting") return 1 log.info("Configuration:") for k, v in iteritems(config): log.info(" %-20s: %s" % (k, v)) api = get_cb_protection_object(args) vt = VirusTotalConnector( api, vt_token=config["vt_api_key"], allow_uploads=config[ "upload_binaries_to_vt"], # Allow VT connector to upload binary files to VirusTotal connector_name=config["connector_name"], ) log.info("Starting VirusTotal processing loop") vt.run()
def main(): parser = build_cli_parser("Export watchlists into shareable JSON format") parser.add_argument("-f", "--file", help="Select what file output is written to", required=True) parser.add_argument("-w", "--watchlists", help="Specific watchlist(s) to export. Can be comma separated.") parser.add_argument("-m", "--selective", action="store_true", help="Interactively select which watchlists to export") parser.add_argument("-d", "--description", help="Description for the watchlist export file") parser.add_argument("-a", "--author", help="Author for the watchlist export file") args = parser.parse_args() cb = get_cb_response_object(args) return export_watchlists(cb, args)
def main(): parser = build_cli_parser("Cb Response Live Response CLI") parser.add_argument("--log", help="Log activity to a file", default='') args = parser.parse_args() cb = get_cb_response_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(): parser = build_cli_parser() parser.add_argument("--md5", help="binary query", required=True) parser.add_argument("--filename", help="local filename to save the binary as", required=True) args = parser.parse_args() cb = get_cb_response_object(args) binary = cb.select(Binary, args.md5) shutil.copyfileobj(binary.file, open(args.filename, "wb")) print("-> Downloaded binary %s [%u bytes]" % (args.md5, binary.size)) return 0
def main(): parser = build_cli_parser() parser.add_argument("--query", help="binary query", default='') args = parser.parse_args() cb = get_cb_response_object(args) binary_query = cb.select(Binary).where(args.query) for binary in binary_query: #print binary for k in sorted(binary._info): print k break
def main(): parser = build_cli_parser() parser.add_argument("--md5", help="binary query", required=True) parser.add_argument("--filename", help="local filename to save the binary as", required=True) args = parser.parse_args() cb = get_cb_response_object(args) binary = cb.select(Binary, args.md5) binary_data = binary.file.read() open(args.filename, "wb").write(binary_data) print("-> Downloaded binary %s [%u bytes]" % (args.md5, len(binary_data))) return 0
def main(): parser = build_cli_parser() commands = parser.add_subparsers(help="User commands", dest="command_name") list_command = commands.add_parser("list", help="List all configured users") list_teams_command = commands.add_parser("list-teams", help="List all configured user teams") add_command = commands.add_parser("add", help="Add new user") add_command.add_argument("-u", "--username", help="New user's username", required=True) add_command.add_argument("-f", "--first-name", help="First name", required=True) add_command.add_argument("-l", "--last-name", help="Last name", required=True) add_command.add_argument("-p", "--password", help="Password - if not specified, prompt at runtime", required=False) add_command.add_argument("-e", "--email", help="Email address", required=True) add_command.add_argument("-A", "--global-admin", help="Make new user global admin", default=False, action="store_true") add_command.add_argument("-t", "--team", help="Add new user to this team (can specify multiple teams)", action="append", metavar="TEAM-NAME") add_team_command = commands.add_parser("add-team", help="Add new team") add_team_command.add_argument("-N", "--name", help="Name of the new team") add_team_command.add_argument("-A", "--administrator", help="Add administrator rights to the given sensor group", metavar="SENSOR-GROUP", action="append") add_team_command.add_argument("-V", "--viewer", help="Add viewer rights to the given sensor group", metavar="SENSOR-GROUP", action="append") get_api_key_command = commands.add_parser("get-api-key", help="Get API key for user") get_api_key_command.add_argument("-u", "--username", help="Username", required=True) get_api_key_command.add_argument("-p", "--password", help="Password - if not specified, prompt at runtime", required=False) del_command = commands.add_parser("delete", help="Delete user") del_user_specifier = del_command.add_mutually_exclusive_group(required=True) del_user_specifier.add_argument("-u", "--username", help="Name of user to delete.") args = parser.parse_args() cb = get_cb_response_object(args) if args.command_name == "list": return list_users(cb, parser, args) elif args.command_name == "list-teams": return list_teams(cb, parser, args) elif args.command_name == "get-api-key": return get_api_key(cb, parser, args) elif args.command_name == "add": return add_user(cb, parser, args) elif args.command_name == "add-team": return add_team(cb, parser, args) elif args.command_name == "delete": return delete_user(cb, parser, args)
def main(): parser = build_cli_parser("Download binary from endpoint through Live Response") parser.add_argument("-o", "--output", help="Output file name (default is the base file name)") parser.add_argument("-H", "--hostname", help="Hostname to download from", required=True) parser.add_argument("-p", "--path", help="Path to download", required=True) args = parser.parse_args() cb = get_cb_response_object(args) sensors = cb.select(Sensor).where("hostname:{0}".format(args.hostname)) for sensor in sensors: if sensor.status == "Online": return download_file(sensor, args.path, args.output) print("No sensors for hostname {0} are online, exiting".format(hostname))
def main(): parser = build_cli_parser() args = parser.parse_args() c = get_cb_response_object(args) hostname_user_pairs = defaultdict(ItemCount) username_activity = defaultdict(ItemCount) for proc in c.select(Process).where("process_name:explorer.exe"): hostname_user_pairs[proc.hostname].add(proc.username) username_activity[proc.username].add(proc.hostname) for hostname, user_activity in iteritems(hostname_user_pairs): print("For host {0:s}:".format(hostname)) for username, count in user_activity.report(): print(" %-20s: logged in %d times" % (username, count))
def main(): parser = build_cli_parser("VirusTotal Connector") parser.add_argument("--config", "-c", help="Path to configuration file", default="virustotal.ini") args = parser.parse_args() inifile = RawConfigParser({ "vt_api_key": None, "retrieve_files": "true", "upload_binaries_to_vt": "false", "connector_name": "VirusTotal", "log_file": None, }) inifile.read(args.config) config = {} config["vt_api_key"] = inifile.get("bridge", "vt_api_key") config["retrieve_files"] = inifile.getboolean("bridge", "retrieve_files") config["connector_name"] = inifile.get("bridge", "connector_name") config["upload_binaries_to_vt"] = inifile.getboolean("bridge", "upload_binaries_to_vt") log_file = inifile.get("bridge", "log_file") if log_file: file_handler = logging.FileHandler(log_file) formatter = logging.Formatter('%(asctime)s %(levelname)s:%(message)s') file_handler.setFormatter(formatter) file_handler.setLevel(logging.DEBUG) logging.getLogger().addHandler(file_handler) if not config["vt_api_key"]: log.fatal("Cannot start without a valid VirusTotal API key, exiting") return 1 log.info("Configuration:") for k, v in iteritems(config): log.info(" %-20s: %s" % (k,v)) api = get_cb_protection_object(args) vt = VirusTotalConnector( api, vt_token=config["vt_api_key"], allow_uploads=config["upload_binaries_to_vt"], # Allow VT connector to upload binary files to VirusTotal connector_name=config["connector_name"], ) log.info("Starting VirusTotal processing loop") vt.run()
def main(): parser = build_cli_parser("Revert computers in policy to previous policy") parser.add_argument("--policy", "-p", help="Policy name or ID", required=True) args = parser.parse_args() p = get_cb_protection_object(args) try: policyId = int(args.policy) except ValueError: policyId = p.select(Policy).where("name:{}".format(args.policy)).id for computer in p.select(Computer).where("policyId:{}".format(policyId)): print("%s was in %s" % (computer.name, computer.policyName)) computer.policyId = computer.previousPolicyId computer.save() print("%s is now in %s" % (computer.name, computer.policyName))
def main(): parser = build_cli_parser("Simple event listener. Calls a callback for every event received on the event bus") args = parser.parse_args() cb = get_cb_response_object(args) event_source = event.RabbitMQEventSource(cb) event_source.start() try: while True: time.sleep(10) except KeyboardInterrupt: event_source.stop() print("Exiting event loop") print("Encountered the following exceptions during processing:") for error in registry.errors: print(error["traceback"])
def main(): parser = build_cli_parser("Query processes") parser.add_argument("-q", type=str, help="process query", default="process_name:notepad.exe") parser.add_argument("-n", type=int, help="only output N processes", default=None) args = parser.parse_args() cb = get_cb_threathunter_object(args) processes = cb.select(Process).where(args.q) if args.n: processes = processes[0:args.n] for process in processes: print("Process: {}".format(process.process_name)) print("\tPIDs: {}".format(process.process_pids)) print("\tSHA256: {}".format(process.process_sha256)) print("\tGUID: {}".format(process.process_guid))
def main(): parser = build_cli_parser() parser.add_argument("--query", help="file property to query upon. e.x.\nmd5:D2F7A0ADC2EE0F65AB1F19D2E00C16B8", default='') parser.add_argument("--list", help="If provided this will list all the queryable fields", action="store_true") args = parser.parse_args() cb = get_cb_protection_object(args) if args.list: print "Here's a list of all the available fields in the File Catalog (and can be used in a query):" file = cb.select(FileCatalog).where('prevalence:1') print file[0] print "="*80 print "Here's a list of all the fields available from the File Instance table." fi_query = 'fileCatalogId:%s' % (file[0].id) file_instance = cb.select(FileInstance).where(fi_query) print file_instance[0] sys.exit(0) if not args.query: raise TypeError('Missing the query argument. Run %s --help for additional instructions'% (sys.argv[0])) try: file_catalog = cb.select(FileCatalog).where(args.query) except: raise for f in file_catalog: print "File Name : ", f.fileName print "Sha256 Hash: ", f.sha256 print "FileState: ", f.fileState fi_query='fileCatalogId:%s' % (f.id) file_instances = cb.select(FileInstance).where(fi_query) for file in file_instances: comp_query = 'id:%s' % (file.computerId) comp = cb.select(Computer).where(comp_query) for c in comp: cname = c.name print cname, file.pathName print "fileCatalogId: %s" % (file.fileCatalogId)