async def user(request, urltype, steamid): path = urlparse(request.url).path currentuser = await getcurrentuser(request) if currentuser and currentuser['url'] == path: user = currentuser else: user = await getuser(steamid, urltype) if user: if user['url'] != path: return redirect(user['url']) items = await getitems(item['index'] for item in user['wishlist']) for i, item in enumerate(items): item.update({'i': i}) item.update(user['wishlist'][i]) else: abort(404) return await render('user.html', user=user, items=items)
async def item(request, **kwargs): slug = kwargs.get('slug') index = kwargs.get('index') is_json = kwargs.get('is_json') item = await (getitembyslug(slug) if slug else getitem(index)) if item and index is not None and not is_json: slug = slugify(item['name']) return redirect(f'/{slug}', status=301) if not item: if is_json: return tojson({'error': 'Item does not exist.'}) abort(404) if is_json: return tojson(item) else: name = item['name'] tags_text = '/'.join(item['tags']) if item['tags'] else 'item' classes_text = getlistastext(item['classes'], 'all classes') description = f'{name} is a TF2 {tags_text} for {classes_text}.' if item['description']: desc_parts = item['description'].partition('---') desc = desc_parts[0].replace('\n', ' ') bundle_items = getlistastext(desc_parts[2].split('\n')) description = ( f"{description} {desc} {bundle_items}" if bundle_items else f"{description} {desc}" ).rstrip(':') if description[-1] not in ('.', '?', '!'): description += '.' return await render('item.html', item=item, description=description)
async def update_one_payloadtype(request, user, ptype): if user["auth"] not in ["access_token", "apitoken"]: abort( status_code=403, message= "Cannot access via Cookies. Use CLI or access via JS in browser", ) try: query = await db_model.payloadtype_query() payloadtype = await db_objects.get(query, id=ptype) data = request.json if "container_running" in data: payloadtype.container_running = data["container_running"] await db_objects.update(payloadtype) except Exception as e: return json({ "status": "error", "error": "failed to find payload type" }) return json({"status": "success", **payloadtype.to_json()})
async def register_user(request: Request, ws: WebSocketCommonProtocol): logger.info(f"Registering new user, paramsL {request.args}") if 'name' not in request.args or 'room' not in request.args: logger.warning("No args") abort(400) name_arg = request.args['name'][0] room_arg = request.args['room'][0] if room_arg not in app.config.rooms: logger.info("Room not found. Creating new room.") app.config.rooms[room_arg] = Room(room_arg) room = app.config.rooms[room_arg] try: room.add_user(name_arg, ws) except UserAlreadyExists: logger.warning("User already exists, closing the socket") await ws.close(code=1003, reason='UserAlreadyExists') await chat_loop(name_arg, room, ws)
async def exchange_token(request, payload): code = payload["code"] try: token = await request.app.exchange_token(code) except aiohttp.ClientResponseError as e: raise abort(e.status, f"Discord Exchange Error: '{e.message}'") if type(token) == bytes: token = token.decode() return response.json({"token": token})
async def show(request, token): Secret.update(reads=Secret.reads - 1).where( Secret.token == token, Secret.expiration >= datetime.now(), ).execute() or abort(404, 'Secret not found') secret = Secret.get(Secret.token == token) secret.reads > 0 or secret.delete_instance() context = secret.serialize() if request.headers.get('Accept') == 'application/json': return response.json(context) return jinja.render('show.html', request, **context)
async def get_all_responses(request, user): if user['auth'] not in ['access_token', 'apitoken']: abort(status_code=403, message="Cannot access via Cookies. Use CLI or access via JS in browser") try: responses = [] query = await db_model.operation_query() operation = await db_objects.get(query, name=user['current_operation']) query = await db_model.callback_query() callbacks = await db_objects.execute(query.where(Callback.operation == operation)) for c in callbacks: query = await db_model.task_query() tasks = await db_objects.prefetch(query.where(Task.callback == c), Command.select()) for t in tasks: query = await db_model.response_query() task_responses = await db_objects.execute(query.where(Response.task == t)) responses += [r.to_json() for r in task_responses] except Exception as e: return json({'status': 'error', 'error': 'Cannot get responses: ' + str(e)}) return json(responses)
async def create_disabled_commands_profile(request, user): if user['auth'] not in ['access_token', 'apitoken']: abort(status_code=403, message= "Cannot access via Cookies. Use CLI or access via JS in browser") # only the admin of an operation or an overall admin can delete an operation try: if not user['admin']: return json({ "status": 'error', 'error': 'Must be an Apfell admin to create disabled command profiles' }) data = request.json added_acl = [] # {"profile_name": {"payload type": [command name, command name 2], "Payload type 2": [] } for name in data: for ptype in data[name]: query = await db_model.payloadtype_query() payload_type = await db_objects.get(query, ptype=ptype) for cmd in data[name][ptype]: query = await db_model.command_query() command = await db_objects.get(query, cmd=cmd, payload_type=payload_type) profile = await db_objects.create(DisabledCommandsProfile, name=name, command=command) added_acl.append(profile.to_json()) return json({ 'status': 'success', 'disabled_command_profile': added_acl }) except Exception as e: print(e) return json({ 'status': 'error', 'error': 'failed to create disabled command profile' })
async def export_browserscript(request, user): if user['auth'] not in ['access_token', 'apitoken']: abort(status_code=403, message= "Cannot access via Cookies. Use CLI or access via JS in browser") scripts = [] query = await db_model.operator_query() operator = await db_objects.get(query, username=user['username']) query = await db_model.operation_query() operation = await db_objects.get(query, name=user['current_operation']) query = await db_model.browserscript_query() operator_scripts = await db_objects.execute( query.where((db_model.BrowserScript.operator == operator) & (db_model.BrowserScript.command != None))) operation_scripts = await db_objects.execute( query.where((db_model.BrowserScript.operation == operation) & (db_model.BrowserScript.command != None) & (db_model.BrowserScript.operator != operator))) support_scripts = await db_objects.execute( query.where(db_model.BrowserScript.command == None)) for s in operator_scripts: scripts.append({ "operator": s.operator.username, "script": s.script, "command": s.command.cmd, "payload_type": s.command.payload_type.ptype }) for s in operation_scripts: scripts.append({ "operator": s.operator.username, "script": s.script, "command": s.command.cmd, "payload_type": s.command.payload_type.ptype }) for s in support_scripts: scripts.append({ "operator": s.operator.username, "script": s.script, "name": s.name }) return json(scripts)
async def update_operator(request, oid, user): if user['auth'] not in ['access_token', 'apitoken']: abort(status_code=403, message="Cannot access via Cookies. Use CLI or access via JS in browser") try: query = await db_model.operator_query() op = await db_objects.get(query, id=oid) if op.username != user['username'] and not user['admin']: # you can't change the name of somebody else unless you're admin return json({'status': 'error', 'error': 'not authorized to change that user\'s information'}) data = request.json if 'password' in data: op.password = await crypto.hash_SHA512(data['password']) if 'admin' in data and user['admin']: # only a current admin can make somebody an admin op.admin = data['admin'] if 'active' in data: # this way you can deactivate accounts without deleting them op.active = data['active'] if 'current_operation' in data: if data['current_operation'] in user['operations']: query = await db_model.operation_query() current_op = await db_objects.get(query, name=data['current_operation']) op.current_operation = current_op if 'ui_config' in data: if data['ui_config'] == "default": op.ui_config = op.default_config elif data['ui_config'] == "dark": op.ui_config = op.default_specter_config else: op.ui_config = data['ui_config'] if 'username' in data and data['username'] != "": op.username = data['username'] if 'view_utc_time' in data: op.view_utc_time = data['view_utc_time'] try: await db_objects.update(op) success = {'status': 'success'} except Exception as e: return json({'status': 'error', 'error': "failed to update operator: " + str(e)}) updated_operator = op.to_json() return json({**success, **updated_operator}) except Exception as e: return json({'status': 'error', 'error': 'failed to update operator: ' + str(e)})
async def get_pageinate_artifact_tasks(request, user, page, size): if user['auth'] not in ['access_token', 'apitoken']: abort(status_code=403, message= "Cannot access via Cookies. Use CLI or access via JS in browser") # get all of the artifact tasks for the current operation if page <= 0 or size <= 0: return json({ 'status': 'error', 'error': 'page or size must be greater than 0' }) try: query = await db_model.operation_query() operation = await db_objects.get(query, name=user['current_operation']) except Exception as e: return json({ 'status': 'error', 'error': "failed to get current operation" }) query = await db_model.callback_query() callbacks = query.where(Callback.operation == operation).select( Callback.id) task_query = await db_model.taskartifact_query() count = await db_objects.count( task_query.where((Task.callback.in_(callbacks)) | (TaskArtifact.operation == operation))) if page * size > count: page = ceil(count / size) if page == 0: page = 1 tasks = await db_objects.execute( task_query.where((Task.callback.in_(callbacks)) | (TaskArtifact.operation == operation)).order_by( -TaskArtifact.timestamp).paginate(page, size)) return json({ 'status': 'success', 'tasks': [a.to_json() for a in tasks], 'total_count': count, 'page': page, 'size': size })
async def get_c2profile_parameters(request, info, user): if user["auth"] not in ["access_token", "apitoken"]: abort( status_code=403, message= "Cannot access via Cookies. Use CLI or access via JS in browser", ) try: query = await db_model.operation_query() operation = await db_objects.get(query, name=user["current_operation"]) query = await db_model.c2profile_query() profile = await db_objects.get(query, id=info) except Exception as e: print(e) return json({ "status": "error", "error": "failed to find the c2 profile" }) try: query = await db_model.c2profileparameters_query() parameters = await db_objects.execute( query.where(C2ProfileParameters.c2_profile == profile)) param_list = [] for p in parameters: p_json = p.to_json() if p_json["name"] == "AESPSK": p_json["default_value"] = await create_key_AES256() if p_json["randomize"]: # generate a random value based on the associated format_string variable p_json["default_value"] = await generate_random_format_string( p_json["format_string"]) param_list.append(p_json) return json({"status": "success", "c2profileparameters": param_list}) except Exception as e: print(e) return json({ "status": "error", "error": "failed to get c2 profile parameters, you might need to select a c2 profile first", })
async def spotify_callback(request): if request.args.get("error"): return json(dict(error=request.args.get("error_description"))) elif request.args.get("code"): grant = request.args.get("code") callback_state = request.args.get("state") if callback_state != state: abort(401) try: user_creds = await spt.build_user_creds(grant=grant) async with aiofiles.open(os.getcwd() + "SPOTIFY_CREDS.json", "w") as file: await file.write(stdlib_json.dumps(user_creds.__dict__)) except AuthError as e: return json(dict(error_description=e.msg, error_code=e.code), e.code) else: await spt.populate_user_creds() print(os.getcwd()) return await response.file(os.getcwd() + "SPOTIFY_CREDS.json") # return response.json(dict(user_creds=user_creds.__dict__, check_if_active=app.url_for('is_active', _scheme='http', _external=True, _server=local_full_address)), 200) else: return response.text("Something is wrong with your callback")
async def get_all_attack_mappings_for_command(request, user, id): if user['auth'] not in ['access_token', 'apitoken']: abort(status_code=403, message= "Cannot access via Cookies. Use CLI or access via JS in browser") try: query = await db_model.command_query() command = await db_objects.get(query, id=id) except Exception as e: print(e) return json({ 'status': 'error', 'error': 'failed to find that command' }) query = await db_model.attackcommand_query() attacks = await db_objects.execute( query.where(ATTACKCommand.command == command)) return json({ 'status': 'success', 'attack': [a.to_json() for a in attacks] })
async def get_commands_for_payloadtype(request, user, ptype): if user['auth'] not in ['access_token', 'apitoken']: abort(status_code=403, message="Cannot access via Cookies. Use CLI or access via JS in browser") payload_type = unquote_plus(ptype) try: query = await db_model.payloadtype_query() payloadtype = await db_objects.get(query, ptype=payload_type) except Exception as e: print(e) return json({'status': 'error', 'error': 'failed to get payload type'}) query = await db_model.command_query() commands = await db_objects.execute(query.where(Command.payload_type == payloadtype).order_by(Command.cmd)) all_commands = [] for cmd in commands: query = await db_model.commandparameters_query() params = await db_objects.execute(query.where(CommandParameters.command == cmd)) query = await db_model.commandtransform_query() transforms = await db_objects.execute(query.where(CommandTransform.command == cmd)) all_commands.append({**cmd.to_json(), "params": [p.to_json() for p in params], "transforms": [t.to_json() for t in transforms]}) status = {'status': 'success'} return json({**status, 'commands': all_commands})
async def spotify_callback(request): if request.args.get("error"): return json(dict(error=request.args.get("error_description"))) elif request.args.get("code"): grant = request.args.get("code") callback_state = request.args.get("state") if callback_state != state: abort(401) try: user_creds = await spt.build_user_creds(grant=grant) except AuthError as e: return json(dict(error_description=e.msg, error_code=e.code), e.code) else: await spt.populate_user_creds() user_creds.save_as_json() return response.text( "Your user credentials where successfully saved, you can now easily access them in any script by simply calling: user_creds.load_from_json()" ) else: return response.text("Something is wrong with your callback")
async def get_screencapture(request, user, id): if user['auth'] not in ['access_token', 'apitoken']: abort(status_code=403, message= "Cannot access via Cookies. Use CLI or access via JS in browser") try: query = await db_model.filemeta_query() file_meta = await db_objects.get(query, id=id) except Exception as e: print(e) return json({'status': 'error', 'error': 'failed to find callback'}) if file_meta.operation.name in user['operations']: return await file(file_meta.path, filename=file_meta.path.split("/")[-1]) else: return json({ "status": 'error', 'error': 'must be part of that callback\'s operation to see its screenshot' })
async def teams_list(request, page): MAX_LABEL = 17 if page < 1 or page > MAX_LABEL: abort(404) # improved from tba page_labels = ['1-999'] + [f"{x * 1000}'s" for x in range(1, MAX_LABEL)] cur_page_label = page_labels[page - 1] teams = await Team.team_list(k=page) num_teams = len(teams) teams_a = teams[:num_teams // 2] teams_b = teams[num_teams // 2:] return html( env.get_template('team_list.html').render({ 'teams_a': teams_a, 'teams_b': teams_b, 'num_teams': num_teams, 'page_labels': page_labels, 'cur_page_label': cur_page_label, 'current_page': page }))
async def remove_apitokens(request, user, tid): if user["auth"] not in ["access_token", "apitoken"]: abort( status_code=403, message= "Cannot access via Cookies. Use CLI or access via JS in browser", ) try: query = await db_model.operator_query() operator = await db_objects.get(query, username=user["username"]) query = await db_model.apitokens_query() apitoken = await db_objects.get(query, id=tid, operator=operator) apitoken_json = apitoken.to_json() await db_objects.delete(apitoken) return json({"status": "success", **apitoken_json}) except Exception as e: print(str(e)) return json({ "status": "error", "error": "failed to find user or tokens" })
async def get_one_config_item(request, name, user): if user['auth'] not in ['access_token', 'apitoken']: abort(status_code=403, message= "Cannot access via Cookies. Use CLI or access via JS in browser") name = unquote_plus(name) try: if name == "default": return json({ 'status': 'success', 'config': Operator.default_config }) elif name == "dark": return json({ 'status': 'success', 'config': Operator.default_dark_config }) else: return json({'status': 'error', 'error': 'config not found'}) except Exception as e: return json({'status': 'error', 'error': 'error getting configs'})
async def get_apitokens(request, user): if user['auth'] not in ['access_token', 'apitoken']: abort(status_code=403, message= "Cannot access via Cookies. Use CLI or access via JS in browser") try: query = await db_model.operator_query() operator = await db_objects.get(query, username=user['username']) query = await db_model.apitokens_query() tokens = await db_objects.execute( query.where(db_model.APITokens.operator == operator)) return json({ "status": "success", "apitokens": [t.to_json() for t in tokens] }) except Exception as e: print(str(e)) return json({ "status": "error", 'error': 'failed to find user or tokens' })
async def _announcements(request): auth_token = request.headers.get('Authorization', None) channel_id = request.json.get("channel_id") msg = request.json['msg'] webhook = request.json.get('webhook',False) await app.ctx.db.execute_job(f"INSERT INTO announcements(msg) VALUES ('{msg}')") if auth_token == app.ctx.sse_token: try: await request.app.sse_send(msg, channel_id=channel_id) except KeyError: abort(HTTPStatus.NOT_FOUND, "channel not found") await app.ctx.db.execute_job("UPDATE seen SET seen='f'") if webhook: em = Embed(color=0x2ecc71, timestamp='now') em.set_author('Announcement', icon_url='https://cdn.discordapp.com/attachments/782105673928146984/984431266516598844/unknown.png') em.description = msg em.set_footer(text='https://opho.physoly.tech/announcements', icon_url='https://cdn.discordapp.com/attachments/782105673928146984/984431266516598844/unknown.png') await app.ctx.webhook.send(embed=em) return json({"status":"ok"}) return response.json({'error' : 'unauthorized'}, status=401)
async def create_credential(request, user): if user["auth"] not in ["access_token", "apitoken"]: abort( status_code=403, message="Cannot access via Cookies. Use CLI or access via JS in browser", ) if user["view_mode"] == "spectator" or user["current_operation"] == "": return json({"status": "error", "error": "Spectators cannot add credentials"}) if user["current_operation"] != "": try: query = await db_model.operation_query() operation = await db_objects.get(query, name=user["current_operation"]) query = await db_model.operator_query() operator = await db_objects.get(query, username=user["username"]) except Exception as e: print(e) return json({"status": "error", "error": "failed to get operation"}) data = request.json return json(await create_credential_func(operator, operation, data)) else: return json({"status": "error", "error": "must be part of a current operation"})
async def get_one_operator(request, oid, user): if user["auth"] not in ["access_token", "apitoken"]: abort( status_code=403, message="Cannot access via Cookies. Use CLI or access via JS in browser", ) try: query = await db_model.operator_query() op = await db_objects.get(query, id=oid) if op.username == user["username"] or user["view_mode"] != "spectator": return json({"status": "success", **op.to_json()}) else: return json( { "status": "error", "error": "Spectators cannot query for specific users", } ) except: print("Failed to get operator") return json({"status": "error", "error": "failed to get operator"})
async def stop_socks_in_callback(request, user, pid): if user['auth'] not in ['access_token', 'apitoken']: abort(status_code=403, message= "Cannot access via Cookies. Use CLI or access via JS in browser") try: if user['view_mode'] == 'spectator': return json({ 'status': 'error', 'error': 'Spectators cannot stop socks' }) query = await db_model.callback_query() proxy = await db_objects.get(query, port=pid) operator_query = await db_model.operator_query() operator = await db_objects.get(operator_query, username=user['username']) await stop_socks(proxy, operator) return json({'status': 'success', **proxy.to_json()}) except Exception as e: print(str(e)) return json({"status": "error", 'error': 'failed to find proxy'})
async def handler(self, request, path=None): if path is not None: assert ".." not in path, "relative paths not supported" assert "\\" not in path, "path must not contain backslash" path_parts = path.split("/") for p in path_parts: assert re.match(r'^[A-Za-z0-9_]+(?:\.[A-Za-z0-9_]+)*$', p), "Invalid file path" else: path = "index.html" try: path2 = importlib_resources.files( self._package) / 'webui_static' / path ret = path2.read_bytes() except FileNotFoundError: abort(404) print(f"Got request! {path}") return res.raw(ret, content_type=mimetypes.guess_type(path))
async def search_tasks(request, user): if user['auth'] not in ['access_token', 'apitoken']: abort(status_code=403, message="Cannot access via Cookies. Use CLI or access via JS in browser") try: data = request.json if 'search' not in data: return json({'status': 'error', 'error': 'failed to find search term in request'}) query = await db_model.operation_query() operation = await db_objects.get(query, name=user['current_operation']) except Exception as e: return json({'status': 'error', 'error': 'Cannot get that response'}) query = await db_model.task_query() tasks = await db_objects.prefetch(query .where((Task.params.contains(data['search'])) | (Task.original_params.contains(data['search']))) .switch(Callback).where(Callback.operation == operation).order_by(Task.id), Command.select()) output = [] for t in tasks: query = await db_model.response_query() responses = await db_objects.execute(query.where(Response.task == t)) output.append({**t.to_json(), "responses": [r.to_json() for r in responses]}) return json({'status': 'success', 'output': output})
async def remove_uploaded_container_files_for_payloadtype(request, user, ptype): if user['auth'] not in ['access_token', 'apitoken']: abort(status_code=403, message="Cannot access via Cookies. Use CLI or access via JS in browser") # apitoken access for this won't help since it's rabbitmq based payload_type = unquote_plus(ptype) try: query = await db_model.payloadtype_query() payloadtype = await db_objects.get(query, ptype=payload_type) except Exception as e: print(e) return json({'status': 'error', 'error': 'failed to get payload type'}) try: data = request.json status = await send_pt_rabbitmq_message(payload_type, "removefile", base64.b64encode(js.dumps({ "folder": data['folder'], "file": data['file'] }).encode()).decode('utf-8')) return json(status) except Exception as e: return json({'status': 'error', 'error': 'failed sending message: ' + str(e)})
async def list_uploaded_container_files_for_payloadtype(request, user, ptype): if user['auth'] not in ['access_token', 'apitoken']: abort(status_code=403, message= "Cannot access via Cookies. Use CLI or access via JS in browser") # apitoken for this won't help much since it's rabbitmq based payload_type = unquote_plus(ptype) try: query = await db_model.payloadtype_query() payloadtype = await db_objects.get(query, ptype=payload_type) except Exception as e: print(e) return json({'status': 'error', 'error': 'failed to get payload type'}) try: status = await send_pt_rabbitmq_message(payload_type, "listfiles", "") return json(status) except Exception as e: return json({ 'status': 'error', 'error': 'failed getting files: ' + str(e) })
async def get_all_responses_for_task(request, user, id): if user["auth"] not in ["access_token", "apitoken"]: abort( status_code=403, message= "Cannot access via Cookies. Use CLI or access via JS in browser", ) try: query = await db_model.operation_query() operation = await db_objects.get(query, name=user["current_operation"]) query = await db_model.task_query() task = await db_objects.get(query, id=id) except Exception as e: return json({ "status": "error", "error": "failed to get operation or task" }) query = await db_model.response_query() responses = await db_objects.execute( query.where(Response.task == task).order_by(Response.id)) return json([r.to_json() for r in responses])
async def get(self, request, name, platform): platform = platform.strip().lower() if platform not in (PLAT_ANDROID, PLAT_IOS): abort(400, "wrong platform") # where 中 一定要用 == True,用 is True会报错 current_version = await get_current_app_version(name, platform) # TODO downloads count logging.info(current_version) logging.info(Path().absolute()) if current_version: file_path = Path(f'uploads/{current_version.file}') if not file_path.exists(): abort(500, "no file found") return await file_stream(file_path, mime_type="application/octet-stream", filename=file_path.name) else: return abort(400, "no app found")
async def start_c2profile(request, info, user): if user["auth"] not in ["access_token", "apitoken"]: abort( status_code=403, message= "Cannot access via Cookies. Use CLI or access via JS in browser", ) try: if user["view_mode"] == "spectator" or user["current_operation"] == "": return json({ "status": "error", "error": "Spectators cannot start c2 profiles" }) query = await db_model.c2profile_query() profile = await db_objects.get(query, id=info) except Exception as e: print(e) return json({"status": "error", "error": "failed to find C2 Profile"}) status = await send_c2_rabbitmq_message(profile.name, "start", "", user["username"]) return json(status)
def handler_abort_message(request): abort(500, message="Abort")
def handler_500_error(request): abort(500) return text("OK")
def handler_401_error(request): abort(401)
def handler_invalid(request): abort(500) return text("OK")
def no_no(request): abort(401) # this won't happen text("OK")