1. 题目背景与初步分析
这道来自护网杯2018的题目名为"easy_tornado",从名称就能看出它考察的是Tornado框架相关的安全知识。Tornado是一个Python编写的非阻塞式Web服务器框架,在CTF比赛中经常作为服务端模板注入(SSTI)漏洞的载体出现。
初次接触这类题目时,我们需要建立几个关键认知:
- Tornado框架使用Python语言编写,这意味着如果存在SSTI漏洞,注入的也是Python代码
- Tornado的模板语法使用双大括号
{{}}包裹变量或表达式 - 题目名称中的"easy"提示解法不会过于复杂,但需要熟悉Tornado的特有对象和方法
2. 信息收集与漏洞定位
2.1 初始页面分析
访问题目提供的Web服务,首页显示了三个可点击的链接。这是典型的CTF题目设计模式,每个链接都可能隐藏着关键信息。在实际渗透测试中,这种设计相当于网站的"功能点",我们需要逐一测试每个功能。
通过点击测试发现两个重要信息:
/file路径下存在文件读取功能/error路径会返回错误消息,且消息内容可通过msg参数控制
提示:在CTF比赛中,任何用户可控的输入点都可能是漏洞入口,特别是能够直接输出内容的位置。
2.2 Cookie信息检查
通过Burp Suite等工具拦截请求,检查HTTP头部信息是Web安全测试的标准操作。虽然初步检查未发现明显可利用的Cookie,但这一步不能省略,因为:
- 某些CTF题目会设置特殊的Cookie作为验证机制
- 真实环境中,Cookie往往是身份认证的关键
3. SSTI漏洞利用
3.1 发现注入点
在/error路径测试msg参数时,发现其输出内容直接反映在页面上。尝试输入{{7*7}}等基本SSTI测试payload,确认存在模板注入漏洞。
Tornado框架的模板注入与Flask等框架有所不同,它的内置对象和方法有自己的特点。其中最关键的是handler.settings,这是Tornado特有的一个字典,包含应用程序的配置信息。
3.2 handler.settings详解
在Tornado框架中:
handler是tornado.web.RequestHandler的实例settings是Application的配置字典- 这个字典通常包含cookie_secret等敏感信息
通过构造payload:msg={{handler.settings}},我们可以获取到应用程序的全部配置信息。这在真实渗透测试中相当于拿到了网站的"配置清单",危害性极大。
4. 关键信息获取与利用
4.1 获取cookie_secret
从handler.settings的输出中,我们能够提取出关键的cookie_secret值。这个值在Tornado中用于签名验证,是安全机制的核心部分。
在Tornado框架中,cookie_secret用于:
- 签名Cookie防止篡改
- 生成安全令牌
- 加密敏感数据
4.2 文件读取漏洞利用
题目中的/file路径需要两个参数:
- filename:要读取的文件名
- filehash:文件签名
通过分析发现filehash的生成算法是:
hash_value = md5(cookie_secret + md5(filename))
因此我们需要:
- 计算目标文件名的MD5值
- 拼接cookie_secret和文件名MD5
- 计算最终MD5作为filehash
5. 完整利用过程
5.1 步骤详解
- 访问/error路径,注入
msg={{handler.settings}}获取cookie_secret - 确定目标文件名为/flllllllag(通过尝试发现)
- 计算filename的MD5:
md5("/flllllllag") - 拼接cookie_secret和文件名MD5
- 计算最终MD5作为filehash
- 构造/file请求获取flag
5.2 Python实现代码
python复制import hashlib
# 从handler.settings获取的cookie_secret
cookie_secret = "your_cookie_secret_here"
filename = "/flllllllag"
# 计算文件名的MD5
filename_md5 = hashlib.md5(filename.encode()).hexdigest()
# 计算最终hash
final_hash = hashlib.md5((cookie_secret + filename_md5).encode()).hexdigest()
print(f"Filehash: {final_hash}")
6. 防御措施与安全建议
6.1 开发者防护方案
-
避免直接渲染用户输入:
python复制# 错误做法 self.render("template.html", msg=user_input) # 正确做法 self.render("template.html", msg=escape(user_input)) -
设置严格的模板沙箱:
python复制settings = { "autoescape": True, "debug": False, "compile_templates": True } -
定期更新框架版本
6.2 渗透测试技巧
-
遇到Tornado框架时,优先测试handler.settings
-
记住常见payload:
{{handler.settings}}{{handler.application.settings}}{{handler.request.connection.stream.socket.getpeername()}}
-
结合其他漏洞:
- SSTI + 文件读取
- SSTI + 命令执行
- SSTI + 反序列化
7. 经验总结与思考
在实际CTF比赛和渗透测试中,Tornado框架的SSTI漏洞利用有几个关键点:
- 语言特性认知:必须熟悉Python的各种魔术方法和内置函数
- 框架知识储备:了解Tornado特有的handler对象及其属性
- 工具链准备:准备好MD5计算、请求构造等工具链
- 逻辑推理能力:从有限的信息中推导出关键算法
这道题目虽然标注为"easy",但完整考察了选手的:
- 信息收集能力
- 漏洞识别敏感度
- 加密算法理解
- 工具使用熟练度
对于Web安全学习者,建议:
- 搭建本地Tornado测试环境
- 练习各种SSTI payload
- 研究框架源代码理解其工作原理
- 参与更多CTF比赛积累经验
最后需要强调的是,在真实环境中发现这类漏洞时,应当遵循负责任的披露流程,切勿进行未授权的测试。