Esempio n. 1
0
async def ws_payloadtypes(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 "newpayloadtype";')
                    # BEFORE WE START GETTING NEW THINGS, UPDATE WITH ALL OF THE OLD DATA
                    payloadtypes = await db_objects.execute(PayloadType.select().order_by(PayloadType.id))
                    for p in payloadtypes:
                        await ws.send(js.dumps(p.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(PayloadType, 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()
Esempio n. 2
0
async def update_c2profile(request, info, user):
    name = unquote_plus(info)
    data = request.json
    payload_types = []
    try:
        # TODO make sure the user has appropriate access to the c2_profile by checking operations scopes
        profile = await db_objects.get(C2Profile, name=name)
    except Exception as e:
        print(e)
        return json({'status': 'error', 'error': 'failed to find C2 Profile'})
    try:
        if 'description' in data:
            profile.description = data['description']
        if 'payload_types' in data:
            # We need to update the mapping in PayloadTypeC2Profile accordingly
            # We need to see which ones were there before, and either add or delete accordingly
            mapping = await db_objects.execute(
                PayloadTypeC2Profile.select().where(
                    PayloadTypeC2Profile.c2_profile == profile))
            # For each payload type, make sure it's real, and that it's in the mapping
            for m in mapping:
                map = await db_objects.get(PayloadType, id=m.payload_type)
                if map.ptype in data['payload_types']:
                    # something we say this c2 profile supports is already listed, so remove it from our list to process
                    del data['payload_types'][data['payload_types'].index(
                        map.ptype)]  # remove it from the array
                    payload_types.append(map.ptype)
                else:
                    # it was in our mapping, now it's not, so remove it from the database mapping
                    await db_objects.delete(m)
            # if there's anyting left in data['payload_types'], it means we need to add it to the database
            for m in data['payload_types']:
                if await db_objects.count(PayloadType.select().where(
                        PayloadType.ptype == m.strip())) != 1:
                    return json({
                        'status':
                        'error',
                        'error':
                        m +
                        ' is not a valid PayloadType. Perhaps you need to register it first?'
                    })
                payload = await db_objects.get(PayloadType, ptype=m.strip())
                await db_objects.create(PayloadTypeC2Profile,
                                        c2_profile=profile,
                                        payload_type=payload)
                payload_types.append(m.strip())
        success = {'status': 'success'}
        updated_json = profile.to_json()
        return json({
            **success,
            **updated_json, 'payload_types': payload_types
        })
    except Exception as e:
        print(e)
        return json({
            'status': 'error',
            'error': 'failed to update C2 Profile'
        })
Esempio n. 3
0
async def register_new_c2profile(request, user):
    data = request.json
    #print(data)
    data['operator'] = user['username']
    if 'name' not in data or data['name'] is "":
        return json({'status': 'error', 'error': 'name is required'})
    if 'description' not in data:
        data['description'] = ""
    if 'payload_types' not in data:
        return json({
            'status': 'error',
            'error': 'payload_types is required information'
        })
    # we need to 1. make sure these are all valid payload types, and 2. create payloadtypec2profile entries as well
    for t in data['payload_types']:
        # this should be an array we can iterate over
        if await db_objects.count(PayloadType.select().where(
                PayloadType.ptype == t.strip())) != 1:
            return json({
                'status': 'error',
                'error': t + ' is not a valid PayloadType.'
            })
    try:
        op = await db_objects.get(Operator, username=data['operator'])
    except Exception as e:
        print(e)
        return json({
            'status': 'error',
            'error': 'operator could not be found'
        })
    try:
        if user['current_operation'] != "":
            operation = await db_objects.get(Operation,
                                             name=user['current_operation'])
            profile = await db_objects.create(C2Profile,
                                              name=data['name'],
                                              description=data['description'],
                                              operator=op,
                                              operation=operation)
            # now create the payloadtypec2profile entries
            for t in data['payload_types']:
                payload_type = await db_objects.get(PayloadType,
                                                    ptype=t.strip())
                await db_objects.create(PayloadTypeC2Profile,
                                        payload_type=payload_type,
                                        c2_profile=profile)
            profile_json = profile.to_json()
            status = {'status': 'success'}
            return json({**status, **profile_json})
        else:
            return json({
                'status': 'error',
                'error': 'must be part of an active operation'
            })
    except Exception as e:
        print(e)
        return json({'status': 'error', 'error': 'Profile name already taken'})
Esempio n. 4
0
async def get_all_payloadtypes(request, user):
    payloads = await db_objects.execute(PayloadType.select())
    return json([p.to_json() for p in payloads])
Esempio n. 5
0
async def register_new_c2profile(request, user):
    if request.form:
        data = js.loads(request.form.get('json'))
    else:
        data = request.json
    #print(data)
    # also takes in an array of 'name', 'key' values to aid in payload creation, not a requirement though
    data['operator'] = user['username']
    if 'name' not in data or data['name'] is "" or data['name'] is None:
        return json({'status': 'error', 'error': 'name is required'})
    if 'description' not in data:
        data['description'] = ""
    if 'payload_types' not in data or data['payload_types'] is None:
        return json({
            'status': 'error',
            'error': 'payload_types is required information'
        })
    # we need to 1. make sure these are all valid payload types, and 2. create payloadtypec2profile entries as well
    for t in data['payload_types']:
        # this should be an array we can iterate over
        if await db_objects.count(PayloadType.select().where(
                PayloadType.ptype == t.strip())) != 1:
            return json({
                'status': 'error',
                'error': t + ' is not a valid PayloadType.'
            })
    try:
        op = await db_objects.get(Operator, username=data['operator'])
    except Exception as e:
        print(e)
        return json({
            'status': 'error',
            'error': 'operator could not be found'
        })
    try:
        if user['current_operation'] != "":
            operation = await db_objects.get(Operation,
                                             name=user['current_operation'])
            profile = await db_objects.create(C2Profile,
                                              name=data['name'],
                                              description=data['description'],
                                              operator=op,
                                              operation=operation)
            # make the right directory structure
            os.makedirs("./app/c2_profiles/{}/{}".format(
                operation.name, data['name']),
                        exist_ok=True)
            # now create the payloadtypec2profile entries
            for t in data['payload_types']:
                try:
                    payload_type = await db_objects.get(PayloadType,
                                                        ptype=t.strip())
                except Exception as e:
                    print(e)
                    return json({
                        'status': 'error',
                        'error': 'failed to find payload type: ' + t
                    })
                await db_objects.create(PayloadTypeC2Profile,
                                        payload_type=payload_type,
                                        c2_profile=profile)
                os.makedirs("./app/c2_profiles/{}/{}/{}".format(
                    operation.name, data['name'], payload_type.ptype),
                            exist_ok=True)
            # now create the c2profileparameters entries so we can generate the right form to fill out
            if 'c2profileparameters' in data:
                for params in data['c2profileparameters']:
                    if not 'hint' in params:
                        params['hint'] = ""
                    await db_objects.create(C2ProfileParameters,
                                            c2_profile=profile,
                                            key=params['key'],
                                            name=params['name'],
                                            hint=params['hint'])
            profile_json = profile.to_json()
            # Now that the profile is created and registered, write the server code files to the appropriate directory
            if request.files:
                code = request.files['upload_file'][0].body
                code_file = open(
                    "./app/c2_profiles/{}/{}/{}".format(
                        operation.name, profile.name,
                        request.files['upload_file'][0].name), "wb")
                code_file.write(code)
                code_file.close()
                for i in range(1, int(request.form.get('file_length'))):
                    code = request.files['upload_file_' + str(i)][0].body
                    code_file = open(
                        "./app/c2_profiles/{}/{}/{}".format(
                            operation.name, profile.name,
                            request.files['upload_file_' + str(i)][0].name),
                        "wb")
                    code_file.write(code)
                    code_file.close()
            elif 'code' in data and 'file_name' in data:
                # if the user is doing this through the API instead of UI, they can specify a file this way
                code = base64.b64decode(data['code'])
                code_file = open(
                    "./app/c2_profiles/{}/{}/{}".format(
                        operation.name, profile.name, data['file_name']), 'wb')
                code_file.write(code)
                code_file.close()
            status = {'status': 'success'}
            return json({**status, **profile_json})
        else:
            return json({
                'status': 'error',
                'error': 'must be part of an active operation'
            })
    except Exception as e:
        print(e)
        return json({'status': 'error', 'error': 'Profile name already taken'})