Example #1
0
async def get_all_tasks(request):
    callbacks = Callback.select()
    operators = Operator.select()
    tasks = Task.select()
    # callbacks_with_operators = await db_objects.prefetch(callbacks, operators)
    full_task_data = await db_objects.prefetch(tasks, callbacks, operators)
    return json([c.to_json() for c in full_task_data])
Example #2
0
async def ws_operators(request, ws):
    try:
        async with aiopg.create_pool(apfell.config['DB_POOL_CONNECT_STRING']) as pool:
            async with pool.acquire() as conn:
                async with conn.cursor() as cur:
                    await cur.execute('LISTEN "newoperator";')
                    # BEFORE WE START GETTING NEW THINGS, UPDATE WITH ALL OF THE OLD DATA
                    operators = await db_objects.execute(Operator.select())
                    for o in operators:
                        await ws.send(js.dumps(o.to_json()))
                    await ws.send("")
                    # now pull off any new payloads we got queued up while processing old data
                    while True:
                        try:
                            msg = conn.notifies.get_nowait()
                            id = (msg.payload)
                            p = await db_objects.get(Operator, id=id)
                            await ws.send(js.dumps(p.to_json()))
                        except asyncio.QueueEmpty as e:
                            await asyncio.sleep(2)
                            await ws.send("")  # this is our test to see if the client is still there
                            continue
                        except Exception as e:
                            print(e)
                            return
    finally:
        pool.close()
Example #3
0
async def ws_tasks(request, ws):
    try:
        async with aiopg.create_pool(apfell.config['DB_POOL_CONNECT_STRING']) as pool:
            async with pool.acquire() as conn:
                async with conn.cursor() as cur:
                    await cur.execute('LISTEN "newtask";')
                    # before we start getting new things, update with all of the old data
                    callbacks = Callback.select()
                    operators = Operator.select()
                    tasks = Task.select()
                    tasks_with_all_info = await db_objects.prefetch(tasks, callbacks, operators)
                    # callbacks_with_operators = await db_objects.prefetch(callbacks, operators)
                    for task in tasks_with_all_info:
                        await ws.send(js.dumps(task.to_json()))
                    await ws.send("")
                    # now pull off any new tasks we got queued up while processing the old data
                    while True:
                        try:
                            msg = conn.notifies.get_nowait()
                            id = (msg.payload)
                            tsk = await db_objects.get(Task, id=id)
                            await ws.send(js.dumps(tsk.to_json()))
                        except asyncio.QueueEmpty as e:
                            await asyncio.sleep(2)
                            await ws.send("")  # this is our test to see if the client is still there
                            continue
                        except Exception as e:
                            print(e)
                            return
    finally:
        # print("closed /ws/tasks")
        pool.close()
Example #4
0
async def ws_callbacks_current_operation(request, ws, user):
    try:
        async with aiopg.create_pool(apfell.config['DB_POOL_CONNECT_STRING']) as pool:
            async with pool.acquire() as conn:
                async with conn.cursor() as cur:
                    await cur.execute('LISTEN "newcallback";')
                    if user['current_operation'] != "":
                        # before we start getting new things, update with all of the old data
                        operation = await db_objects.get(Operation, name=user['current_operation'])
                        callbacks = Callback.select().where(Callback.operation == operation).order_by(Callback.id)
                        operators = Operator.select()
                        callbacks_with_operators = await db_objects.prefetch(callbacks, operators)
                        for cb in callbacks_with_operators:
                            await ws.send(js.dumps(cb.to_json()))
                        await ws.send("")
                        # now pull off any new callbacks we got queued up while processing the old data
                        while True:
                            # msg = await conn.notifies.get()
                            try:
                                msg = conn.notifies.get_nowait()
                                id = (msg.payload)
                                cb = await db_objects.get(Callback, id=id, operation=operation)
                                await ws.send(js.dumps(cb.to_json()))
                            except asyncio.QueueEmpty as e:
                                await asyncio.sleep(0.5)
                                await ws.send("") # this is our test to see if the client is still there
                                continue
                            except Exception as e:
                                print(e)
                                return
    finally:
        pool.close()
Example #5
0
async def get_all_callbacks(request):
    #callbacks = await db_objects.execute(Callback.select(Callback, Operator).join(Operator))
    #return json([c.to_json() for c in callbacks])
    callbacks = Callback.select()
    operators = Operator.select()
    callbacks_with_operators = await db_objects.prefetch(callbacks, operators)
    return json([c.to_json() for c in callbacks_with_operators])
Example #6
0
async def initial_setup():
    # create apfell_admin
    operators = await db_objects.execute(Operator.select())
    # mark all the profiles as stopped first since we just started the server
    await mark_profiles_as_not_running()
    if len(operators) != 0:
        print("Users already exist, exiting initial setup early")
        return
    admin, created = await db_objects.get_or_create(
        Operator,
        username="******",
        password=
        "******",
        admin=True,
        active=True)
    print("Created Admin")
    # create default operation
    operation, created = await db_objects.get_or_create(Operation,
                                                        name='default',
                                                        admin=admin,
                                                        complete=False)
    print("Created Operation")
    await db_objects.get_or_create(OperatorOperation,
                                   operator=admin,
                                   operation=operation)
    print("Registered Admin with the default operation")
    print("Started parsing ATT&CK data...")
    file = open('./app/templates/attack.json', 'r')
    attack = js.load(
        file)  # this is a lot of data and might take a hot second to load
    for obj in attack['techniques']:
        await db_objects.create(ATTACK, **obj)
    file.close()
    print("Created all ATT&CK entries")
    file = open("./app/templates/artifacts.json", "r")
    artifacts_file = js.load(file)
    for artifact in artifacts_file['artifacts']:
        await db_objects.get_or_create(Artifact,
                                       name=artifact['name'],
                                       description=artifact['description'])
    file.close()
    print("Created all base artifacts")
    file = open('./app/templates/apfell-jxa.json', 'r')
    apfell_jxa = js.load(
        file)  # this is a lot of data and might take a hot second to load
    print("parsed apfell-jxa payload file")
    for ptype in apfell_jxa['payload_types']:
        await import_payload_type_func(ptype, admin, operation)
    file.close()
    print("created Apfell-jxa payload")
    file = open('./app/templates/linfell_c.json', 'r')
    linfell_c = js.load(
        file)  # this is a lot of data and might take a hot second to load
    for ptype in linfell_c['payload_types']:
        await import_payload_type_func(ptype, admin, operation)
    file.close()
    print("created Linfell-c payload")
    await register_default_profile_operation(admin, operation)
    print("Successfully finished initial setup")
Example #7
0
async def initial_setup():
    # create mythic_admin
    operators = await db_objects.execute(Operator.select())
    if len(operators) != 0:
        print("Users already exist, aborting initial install")
        await start_all_socks_after_restart()
        return
    password = await crypto.hash_SHA512(mythic_admin_password)
    admin, created = await db_objects.get_or_create(Operator,
                                                    username=mythic_admin_user,
                                                    password=password,
                                                    admin=True,
                                                    active=True)
    print("Created Admin")
    # create default operation
    AES_PSK = await create_key_AES256()
    operation, created = await db_objects.get_or_create(
        Operation,
        name=default_operation_name,
        admin=admin,
        complete=False,
        AESPSK=AES_PSK,
    )
    print("Created Operation")
    await db_objects.get_or_create(OperatorOperation,
                                   operator=admin,
                                   operation=operation)
    admin.current_operation = operation
    await db_objects.update(admin)
    print("Registered Admin with the default operation")
    print("Started parsing ATT&CK data...")
    file = open("./app/default_files/other_info/attack.json", "r")
    attack = js.load(
        file)  # this is a lot of data and might take a hot second to load
    for obj in attack["techniques"]:
        await db_objects.create(ATTACK, **obj)
    file.close()
    print("Created all ATT&CK entries")
    file = open("./app/default_files/other_info/artifacts.json", "r")
    artifacts_file = js.load(file)
    for artifact in artifacts_file["artifacts"]:
        await db_objects.get_or_create(Artifact,
                                       name=artifact["name"],
                                       description=artifact["description"])
    file.close()
    print("Created all base artifacts")
    for base_file in glob.iglob("./app/default_files/c2_profiles/*"):
        file = open(base_file, "r")
        c2 = js.load(file)
        print("parsed {}".format(base_file))
        # await import_c2_profile_func(c2, admin)
    print("Created all C2 Profiles")
    print("Successfully finished initial setup")
Example #8
0
async def search(request, user):
    template = env.get_template('search.html')
    try:
        operator = Operator.get(Operator.username == user['username'])
        if use_ssl:
            content = template.render(links=links, name=user['username'], http="https", ws="wss")
        else:
            content = template.render(links=links, name=user['username'], http="http", ws="ws")
        return response.html(content)
    except Exception as e:
        print(e)
        return json({'status': 'error', 'error': 'Failed to find operator'})
Example #9
0
async def get_all_tasks(request, user):
    callbacks = Callback.select()
    operators = Operator.select()
    tasks = Task.select()
    full_task_data = await db_objects.prefetch(tasks, callbacks, operators)
    if user['admin']:
        # callbacks_with_operators = await db_objects.prefetch(callbacks, operators)
        return json([c.to_json() for c in full_task_data])
    elif user['current_operation'] != "":
        operation = await db_objects.get(Operation, name=user['current_operation'])
        return json([c.to_json() for c in full_task_data if c.callback.operation == operation])
    else:
        return json({'status': 'error', 'error': 'must be admin to see all tasks or part of a current operation'})
Example #10
0
async def get_all_tasks(request, user):
    if user['admin']:
        callbacks = Callback.select()
        operators = Operator.select()
        tasks = Task.select()
        # callbacks_with_operators = await db_objects.prefetch(callbacks, operators)
        full_task_data = await db_objects.prefetch(tasks, callbacks, operators)
        return json([c.to_json() for c in full_task_data])
    else:
        return json({
            'status': 'error',
            'error': 'must be admin to see all tasks'
        })
Example #11
0
async def settings(request, user):
    template = env.get_template('settings.html')
    try:
        operator = Operator.get(Operator.username == user['username'])
        op_json = operator.to_json()
        del op_json['ui_config']
        if use_ssl:
            content = template.render(links=links,
                                      name=user['username'],
                                      http="https",
                                      ws="wss",
                                      op=op_json,
                                      config=user['ui_config'])
        else:
            content = template.render(links=links,
                                      name=user['username'],
                                      http="http",
                                      ws="ws",
                                      op=op_json,
                                      config=user['ui_config'])
        return response.html(content)
    except Exception as e:
        print(e)
        return json({'status': 'error', 'error': 'Failed to find operator'})
Example #12
0
async def get_all_operators(request):
    ops = await db_objects.execute(Operator.select())
    return json([p.to_json() for p in ops])
Example #13
0
async def initial_setup():
    # create apfell_admin
    operators = await db_objects.execute(Operator.select())
    if len(operators) != 0:
        print("Users already exist, only handling transform updates")
        rsp = await write_transforms_to_file()
        if rsp['status'] == 'success':
            print("Successfully wrote transforms to file")
            rsp2 = await update_all_pt_transform_code()
            if rsp2['status'] == 'success':
                print("Successfully sent transforms to containers")
            else:
                print("Failed to send code to containers: " + rsp2['error'])
        else:
            print("Failed to write transforms to file: " + rsp['error'])
        return
    admin, created = await db_objects.get_or_create(
        Operator,
        username="******",
        password=
        "******",
        admin=True,
        active=True)
    print("Created Admin")
    # create default operation
    AES_PSK = await create_key_AES256()
    operation, created = await db_objects.get_or_create(Operation,
                                                        name='default',
                                                        admin=admin,
                                                        complete=False,
                                                        AESPSK=AES_PSK)
    print("Created Operation")
    await db_objects.get_or_create(OperatorOperation,
                                   operator=admin,
                                   operation=operation)
    print("Registered Admin with the default operation")
    print("Started parsing ATT&CK data...")
    file = open('./app/default_files/other_info/attack.json', 'r')
    attack = js.load(
        file)  # this is a lot of data and might take a hot second to load
    for obj in attack['techniques']:
        await db_objects.create(ATTACK, **obj)
    file.close()
    print("Created all ATT&CK entries")
    file = open("./app/default_files/other_info/artifacts.json", "r")
    artifacts_file = js.load(file)
    for artifact in artifacts_file['artifacts']:
        await db_objects.get_or_create(Artifact,
                                       name=artifact['name'],
                                       description=artifact['description'])
    file.close()
    await register_default_profile_operation(admin)
    print("Created all base artifacts")
    for base_file in glob.iglob("./app/default_files/payload_types/*"):
        file = open(base_file, 'r')
        ptype = js.load(file)
        print("parsed {}".format(base_file))
        for payload_type in ptype['payload_types']:
            await import_payload_type_func(payload_type, admin, operation)
    print("Created all payload types")

    print("registering initial browser scripts")
    code = open("./app/scripts/browser_scripts.json", 'r').read()
    code = js.loads(code)
    result = await import_browserscript_func(code,
                                             {"username": admin.username})
    print("Generating initial transforms.py file")
    rsp = await write_transforms_to_file()
    if rsp['status'] == 'success':
        rsp2 = await update_all_pt_transform_code()
        if rsp2['status'] == 'success':
            print("Successfully sent transforms to containers")
        else:
            print("Failed to send code to containers: " + rsp2['error'])
    else:
        print("Failed to write transforms to file: " + rsp['error'])
    print("Successfully finished initial setup")
Example #14
0
async def initial_setup():
    # create apfell_admin
    operators = await db_objects.execute(Operator.select())
    # mark all the profiles as stopped first since we just started the server
    await mark_profiles_as_not_running()
    if len(operators) != 0:
        print("Users already exist, exiting initial setup early")
        return
    admin, created = await db_objects.get_or_create(Operator, username="******", password="******",
                                   admin=True, active=True)
    print("Created Admin")
    # create default operation
    operation, created = await db_objects.get_or_create(Operation, name='default', admin=admin, complete=False)
    print("Created Operation")
    # create default payload types
    apfell_jxa_command_template = """exports.command_name = function(task, command, params){
        //task is a dictionary of Task information
        //command is the single word command that caused this function to be called
        //params is a string of everything passed in except for the command
        //   if you pass in a json blob on the command line, then to get json back here call JSON.parse(params);
        //do stuff here, with access to the following commands:
        does_file_exist(strPath);
        convert_to_nsdata(strData);
        write_data_to_file(data, filePath);
        base64_decode(data);
        base64_encode(data);
    };
    """
    payload_type_apfell_jxa, created = await db_objects.get_or_create(PayloadType, ptype='apfell-jxa', operator=admin,
                                                                      file_extension=".js", wrapper=False,
                                                                      command_template=apfell_jxa_command_template)
    #c2_profile, pt_c2_profile = await create_default_c2_for_operation(operation, admin, [payload_type_apfell_jxa])
    await register_default_profile_operation({"username": "******"}, "default")
    # create the default transforms for apfell-jxa payloads
    jxa_load_transform = await db_objects.get_or_create(Transform, name="readCommands", t_type="load",
                                                        order=1, payload_type=payload_type_apfell_jxa,
                                                        operator=admin)
    jxa_load_transform = await db_objects.get_or_create(Transform, name="combineAppend", t_type="load",
                                                        order=2, payload_type=payload_type_apfell_jxa,
                                                        operator=admin)
    jxa_load_transform = await db_objects.get_or_create(Transform, name="convertBytesToString", t_type="load",
                                                        order=3, payload_type=payload_type_apfell_jxa,
                                                        operator=admin)
    jxa_load_transform = await db_objects.get_or_create(Transform, name="removeSlashes", t_type="load",
                                                        order=4, payload_type=payload_type_apfell_jxa,
                                                        operator=admin)
    jxa_load_transform = await db_objects.get_or_create(Transform, name="strToByteArray", t_type="load",
                                                        order=5, payload_type=payload_type_apfell_jxa,
                                                        operator=admin)
    jxa_load_transform = await db_objects.get_or_create(Transform, name="writeFile", t_type="load",
                                                        order=6, payload_type=payload_type_apfell_jxa,
                                                        operator=admin)
    print("Created Apfell-jxa payload type")
    # add the apfell_admin to the default operation
    await db_objects.get_or_create(OperatorOperation, operator=admin, operation=operation)
    print("Registered Admin with the default operation")
    # Register commands for created payload types
    file = open("./app/templates/default_commands.json", "r")
    command_file = js.load(file)
    for cmd_group in command_file['payload_types']:
        for cmd in cmd_group['commands']:
            if cmd['needs_admin'] == "false":
                cmd['needs_admin'] = False
            else:
                cmd['needs_admin'] = True
            command, created = await db_objects.get_or_create(Command, cmd=cmd['cmd'], needs_admin=cmd['needs_admin'],
                                                     description=cmd['description'], help_cmd=cmd['help_cmd'],
                                                     payload_type=payload_type_apfell_jxa,
                                                     operator=admin)
            for param in cmd['parameters']:
                try:
                    if param['required'] == "false":
                        param['required'] = False
                    else:
                        param['required'] = True
                    await db_objects.get_or_create(CommandParameters, command=command, **param, operator=admin)
                except Exception as e:
                    print(e)
    print("Created all commands and command parameters")
    file.close()
Example #15
0
async def initial_setup():
    # create apfell_admin
    operators = await db_objects.execute(Operator.select())
    # mark all the profiles as stopped first since we just started the server
    await mark_profiles_as_not_running()
    if len(operators) != 0:
        print("Users already exist, exiting initial setup early")
        return
    admin, created = await db_objects.get_or_create(Operator, username="******", password="******",
                                   admin=True, active=True)
    print("Created Admin")
    # create default operation
    operation, created = await db_objects.get_or_create(Operation, name='default', admin=admin, complete=False)
    print("Created Operation")
    # create default payload types
    payload_type_apfell_jxa, created = await db_objects.get_or_create(PayloadType, ptype='apfell-jxa', operator=admin,
                                                                      file_extension=".js", wrapper=False)
    #c2_profile, pt_c2_profile = await create_default_c2_for_operation(operation, admin, [payload_type_apfell_jxa])
    await register_default_profile_operation({"username": "******"}, "default")
    # create the default transforms for apfell-jxa payloads
    jxa_load_transform = await db_objects.get_or_create(Transform, name="readCommands", t_type="load",
                                                        order=1, payload_type=payload_type_apfell_jxa,
                                                        operator=admin)
    jxa_load_transform = await db_objects.get_or_create(Transform, name="combineAppend", t_type="load",
                                                        order=2, payload_type=payload_type_apfell_jxa,
                                                        operator=admin)
    jxa_load_transform = await db_objects.get_or_create(Transform, name="convertBytesToString", t_type="load",
                                                        order=3, payload_type=payload_type_apfell_jxa,
                                                        operator=admin)
    jxa_load_transform = await db_objects.get_or_create(Transform, name="removeSlashes", t_type="load",
                                                        order=4, payload_type=payload_type_apfell_jxa,
                                                        operator=admin)
    jxa_load_transform = await db_objects.get_or_create(Transform, name="strToByteArray", t_type="load",
                                                        order=5, payload_type=payload_type_apfell_jxa,
                                                        operator=admin)
    jxa_load_transform = await db_objects.get_or_create(Transform, name="writeFile", t_type="load",
                                                        order=6, payload_type=payload_type_apfell_jxa,
                                                        operator=admin)
    print("Created Apfell-jxa payload type")
    # add the apfell_admin to the default operation
    await db_objects.get_or_create(OperatorOperation, operator=admin, operation=operation)
    print("Registered Admin with the default operation")
    # Register commands for created payload types
    file = open("./app/templates/default_commands.json", "r")
    command_file = js.load(file)
    for cmd_group in command_file['payload_types']:
        for cmd in cmd_group['commands']:
            if cmd['needs_admin'] == "false":
                cmd['needs_admin'] = False
            else:
                cmd['needs_admin'] = True
            command, created = await db_objects.get_or_create(Command, cmd=cmd['cmd'], needs_admin=cmd['needs_admin'],
                                                     description=cmd['description'], help_cmd=cmd['help_cmd'],
                                                     payload_type=payload_type_apfell_jxa,
                                                     operator=admin)
            for param in cmd['parameters']:
                try:
                    if param['required'] == "false":
                        param['required'] = False
                    else:
                        param['required'] = True
                    await db_objects.get_or_create(CommandParameters, command=command, **param, operator=admin)
                except Exception as e:
                    print(e)
    print("Created all commands and command parameters")
    file.close()