Example #1
0
def run_playbook(uplink: UplinkConnection, playbook: str, target: str,
                 args: str):
    print(f'###  Manually executing playbook: {playbook} against {target}')
    manual_target = {
        'target_host': target,
        'details': {
            'run_method': 'manual'
        }
    }
    for i in range(0, len(args)):
        manual_target[f'arg{i}'] = args[i]
    try:
        playbook_module = importlib.import_module(
            f'radar.playbooks.{playbook}')
        results = playbook_module.run(manual_target)
        print(results)
    except ModuleNotFoundError as mnfe:
        print(f'!!!  Missing referenced Playbook: {mnfe}')
    except AttributeError as ae:
        print(f'!!!  Malformed Playbook, missing required attribute: {ae}')
    except TypeError as te:
        print(
            f'!!!  Malformed Playbook, the run method must take in the target as a dict: {te}'
        )
    except KeyboardInterrupt:
        print("!!!  Command cancelled by key interrupt")
    uplink.send_data(const.DEFAULT_TARGET_COLLECTION, manual_target)
Example #2
0
def modify_auth(uplink: UplinkConnection,
                api_key: str,
                superuser=False,
                authorizing=True):
    uplink.change_key_authorization(api_key,
                                    superuser=superuser,
                                    authorizing=authorizing)
Example #3
0
def dispatch(command: str, args=None):
    uplink_connection = UplinkConnection()
    if command == 'info':
        get_info(uplink_connection)
    elif command == 'distribute':
        distributed_command = args.command
        distribute_command(uplink_connection, distributed_command)
    elif command == 'playbook':
        run_playbook(uplink_connection, args.playbook, args.target,
                     args.playbook_args)
    elif command == 'collection-list':
        list_collections(uplink_connection)
    elif command == 'database-list':
        list_database_structure(uplink_connection)
    elif command == 'get-data':
        collection = args.collection
        database = args.database
        read_database_contents(uplink_connection,
                               collection,
                               database=database)
    elif command == 'mission-list':
        list_missions(uplink_connection)
    elif command == 'mission-join':
        join_mission(uplink_connection, args.mission)
    elif command == 'check-auth':
        check_auth(uplink_connection)
    elif command == 'grant-auth':
        modify_auth(uplink_connection, args.api_key, superuser=args.superuser)
    elif command == 'remove-auth':
        modify_auth(uplink_connection, args.api_key, authorizing=False)
    elif command == 'document-commands':
        output_filename = args.output_filename
        document_commands(uplink_connection, output_filename)
Example #4
0
def main(raw_command: str):
    print('============ EXECUTING COMMAND ============', file=sys.stderr)
    system_command = SystemCommand(raw_command)
    completed = system_command.run()
    if not completed:
        print("!!!  Command didn't finish executing", file=sys.stderr)
        exit(1)
    print(system_command.command_output, end='')

    print('========== PARSING COMMAND OUTPUT =========', file=sys.stderr)
    parser_manager = CommandParserManager()
    command_json = system_command.to_json()
    metadata, targets = parser_manager.parse(
        system_command)  # Conditionally parse command

    print('============ RUNNING PLAYBOOKS ============', file=sys.stderr)
    playbook_manager = PlaybookManager()
    playbook_manager.automate(targets)  # Conditionally run Playbooks

    print('========= ESTABLISHING RADAR UPLINK =======', file=sys.stderr)
    uplink = UplinkConnection()

    print('=============== SYNCING DATA ==============', file=sys.stderr)
    print("> command data... ", end='', file=sys.stderr)
    uplink.send_data(const.DEFAULT_COMMAND_COLLECTION, command_json)
    print("done", file=sys.stderr)
    print("> metadata... ", end='', file=sys.stderr)
    uplink.send_data(const.DEFAULT_METADATA_COLLECTION, metadata)
    print("done", file=sys.stderr)
    print("> target data... ", end='', file=sys.stderr)
    if len(targets) != 0:
        uplink.send_data(const.DEFAULT_TARGET_COLLECTION, targets)
        print("done", file=sys.stderr)
    else:
        print("n/a", file=sys.stderr)

    print('============<({[ COMPLETED ]})>============', file=sys.stderr)
Example #5
0
def document_commands(uplink: UplinkConnection, output_filename: str):
    out_file = open(output_filename, "w")
    command_list = uplink.get_data(const.DEFAULT_COMMAND_COLLECTION)
    for command_data in command_list:
        start_time_float = command_data.get("execution_time_start")
        start_time = time.strftime('%Y-%m-%d %H:%M:%S %z',
                                   time.localtime(start_time_float))
        end_time_float = command_data.get("execution_time_end")
        end_time = time.strftime('%Y-%m-%d %H:%M:%S %z',
                                 time.localtime(end_time_float))
        host = command_data.get("executed_on_host")
        command = command_data.get("command")
        output = command_data.get("command_output")

        out_file.write(f"RADAR COMMAND EXECUTION $> {command}\n")
        out_file.write(f"Executed on Host: {host}\n")
        out_file.write(f"Command Started at: {start_time}\n")
        out_file.write(f"Command Finished at: {end_time}\n")
        out_file.write("OUTPUT:\n")
        out_file.write("```\n")
        for line in output.split("\n")[:-1]:
            out_file.write(f'{line.strip()}\n')
        out_file.write("```\n")
        out_file.write("\n\n\n")
Example #6
0
def distribute_command(uplink: UplinkConnection, distrib_command: str):
    syntax_pattern = '^(?P<targets>.+) ([iI][nN][tT][oO]) (?P<command>.*{}.*)$'
    parsed_command = re.search(syntax_pattern, distrib_command)

    if not parsed_command.group('targets'):
        print("!!!  Missing targets that go into distributed command")
        exit(1)
    if not parsed_command.group('command'):
        print("!!!  Missing distributed command with placeholder")
        exit(1)

    unprocessed_target_list = parsed_command.group('targets').split(',')
    target_list = []
    for target in unprocessed_target_list:
        target = target.strip()
        if len(target) > 0:
            target_list.append(target)

    command = parsed_command.group('command').strip()
    if len(target_list) == 0 or command == '':
        print('!!!  Either targets or command is missing content and is blank')
        exit(1)

    # IP Input patterns
    ipaddr_rex = '^([0-9]{1,3}\.){3}[0-9]{1,3}$'
    iprange_rex = '^([0-9]{1,3}\.){3}[0-9]{1,3} *\- *([0-9]{1,3}\.){3}[0-9]{1,3}$'
    ipcidr_rex = '^([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]{1,2}$'

    # tokenize each target in target_list
    print("###  Verifying targets")
    for target in target_list:
        if re.match(ipaddr_rex, target):
            print(f"  {target} is an IP address")
        elif re.match(iprange_rex, target):
            print(f"  {target} is an IP range")
        elif re.match(ipcidr_rex, target):
            print(f"  {target} is an CIDR network")
        else:
            print(
                f"  {target} is a hostname, URL, or other non-IP address target"
            )
    valid = input("Does this look correct? [Y/n]: ").strip().lower()
    if len(valid) > 0 and valid[0] != 'y':
        print('!!!  You said targets are invalid... stopping now')
        exit(2)

    # Generate every single valid target
    all_targets = []
    for target in target_list:
        try:
            if re.match(ipaddr_rex, target):
                host_ip = netaddr.IPAddress(target)
                all_targets.append(str(host_ip))
            elif re.match(iprange_rex, target):
                range_start_end = [ip.strip() for ip in target.split('-')]
                iprange = netaddr.IPRange(range_start_end[0],
                                          range_start_end[1])
                for host_ip in iprange:
                    all_targets.append(str(host_ip))
            elif re.match(ipcidr_rex, target):
                cidr = netaddr.IPNetwork(target)
                for host_ip in cidr.iter_hosts():
                    all_targets.append(str(host_ip))
            else:
                all_targets.append(target)
        except Exception as err:
            print(f"!!!  Invalid target '{target}': {err}")
    if len(all_targets) == 0:
        print("!!!  No valid targets... aborting")
        exit(1)

    print(f"$$$  A total of {len(all_targets)} targets are valid")

    command_list = [command.replace('{}', target) for target in all_targets]
    print(f"~~~  Example distirbuted command: '{command_list[0]}'")
    valid = input("Does this look correct? [Y/n]: ").strip().lower()
    if len(valid) > 0 and valid[0] != 'y':
        print('!!!  You said the command is wrong... stopping now')
        exit(2)

    print(f"$$$ Sending {len(command_list)} commands to be distributed")
    result = uplink.send_distributed_commands(command_list)
    if not result:
        print('!!!  Failed to send the commands to the Uplink')
Example #7
0
def get_info(uplink: UplinkConnection):
    info = uplink.get_info()
    print(info)
Example #8
0
def check_auth(uplink: UplinkConnection):
    uplink.get_key_authorization()
Example #9
0
def join_mission(uplink: UplinkConnection, mission: str):
    uplink.set_mission(mission)
Example #10
0
def list_missions(uplink: UplinkConnection):
    mission_list = uplink.get_mission_list()
    print("Available Missions w/ data")
    for mission in mission_list:
        print(f'> {mission}')
Example #11
0
def read_database_contents(uplink: UplinkConnection,
                           collection: str,
                           database=None):
    contents = uplink.get_data(collection, database=database)
    print(json.dumps(contents, indent=4, sort_keys=True))
Example #12
0
def list_collections(uplink: UplinkConnection):
    collection_list = uplink.list_collections()
    for collection in collection_list:
        print(collection)
Example #13
0
def list_database_structure(uplink: UplinkConnection):
    structure = uplink.get_database_structure()
    for database_name, collection_list in structure.items():
        print(database_name)
        for collection in collection_list:
            print(f'> {collection}')