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("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() 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("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("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("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("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("Cb Defense Live Response CLI") parser.add_argument("--log", help="Log activity to a file", default='') args = parser.parse_args() cb = get_cb_defense_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("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("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)) 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 = strip_html(event.longDescription) # format and print out the event time, Event ID, Creation time, Event type and Description print("{0:^25}{1:^25}{2:^32}{3}".format("Event Time", "Event ID", "Create Time", "Event Type")) print("{0} | {1} | {2} | {3}".format(event_time, event.eventId, create_time, event.eventType)) print("{0:50}".format(" ")) print("{0} {1}".format("Description: ", long_description)) print("{0:50}".format("------------------------------------")) print("{0:50}".format(" "))
def main(): # First we create a command line parser to collect our configuration. # We use the built in ``build_cli_parser`` in ``cbapi.example_helpers`` to build # the basic command line parser, then augment with a few parameters specific to # this script. parser = build_cli_parser( "Example CB PSC & Response Live Response automation") parser.add_argument( "--synthetic", help="Generate synthetic notifications with given Device ID", metavar="DEVICE_ID") parser.add_argument("--poll", help="Poll interval for the Notifications API", type=int, default=30) parser.add_argument( "--siemprofile", help="CB Profile for SIEM API key (required to poll for notifications)", default="siem") args = parser.parse_args() log.info("Starting") datastore = DataStore() # Start the thread to listen to notifications if args.synthetic: notification_thread = SyntheticNotificationGenerator( args.synthetic, datastore, poll_interval=args.poll) else: siem_cb = CbDefenseAPI(profile=args.siemprofile) notification_thread = NotificationListener(siem_cb, datastore, poll_interval=args.poll) notification_thread.daemon = True notification_thread.start() cb = get_cb_defense_object(args) orchestrator = LiveResponseOrchestrator(cb, get_lr_session_psc, CollectContextWorker, datastore) orchestrator.start()
def main(): parser = build_cli_parser("Push notifications to mobile phone") parser.add_argument( "pushoverkey", help= "API key for pushover (will read from ~/.pushover if this isn't set)") parser.add_argument( "userkey", help= "User key for pushover (to control the destination of your notifications)", nargs=1) # Parse command line arguments and retrieve Cb Defense API credentials args = parser.parse_args() cb = get_cb_defense_object(args) # Get the API key for Pushover if args.pushoverkey: pushoverkey = args.pushoverkey else: # Read from ~/.pushover homedir = expanduser("~") pushoverkey = open(join(homedir, ".pushover"), "r").readline().strip() for notification in cb.notification_listener(interval=30): if notification.get("type") == "THREAT": summary = summarize_threat(notification) # Send summary to pushover to notify our on-call team requests.post("https://api.pushover.net/1/messages.json", json={ "token": pushoverkey, "user": args.userkey, "message": summary }) print("Sent notification {0} to phones!".format(summary))
def __init__(self, args): self.args = args self.cb = get_cb_defense_object(args) self.datastore = DataStore()
def main(): parser = build_cli_parser("Policy operations") commands = parser.add_subparsers(help="Policy commands", dest="command_name") list_command = 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_defense_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(): 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))