考点
- 判断SSTI类型
- 分析过滤
- 构造payload
![flask + jinja2 的 SSTI ---[攻防世界shrine] - 图1](/uploads/projects/u390550@fftlfh/0f32dfce9899ce8a0f0d1a45a3044b7e.png)
解题
打开页面就是一段源码
![flask + jinja2 的 SSTI ---[攻防世界shrine] - 图2](/uploads/projects/u390550@fftlfh/bd9590645fff35c25776dec3965ef5e0.png)
这明显是个flask在/shrine/下的SSTI
而且对payload进行了过滤了
- 对小括号进行了替换,将(和)替换为空字符串- 将config和self添加进了黑名单
- 既然是模板注入,那么我们先试试{{7*7}}
![flask + jinja2 的 SSTI ---[攻防世界shrine] - 图3](/uploads/projects/u390550@fftlfh/397457a31bd5b7b75821de09d76f6086.png)
- 再试试{{7*’7’}}
![flask + jinja2 的 SSTI ---[攻防世界shrine] - 图4](/uploads/projects/u390550@fftlfh/c5ef7b7a85648c0bd4614ee25423ac7e.png)
经过这两个测试发现是jinjia2或者Twig,后端源码是为flask
所以这个是关于flask+jinjia2的SSTI
至于为什么 请看图
![flask + jinja2 的 SSTI ---[攻防世界shrine] - 图5](/uploads/projects/u390550@fftlfh/cfe85d2ccd4fecb9a7947b8c30addfc0.png)
- {{‘’.class.mro[2].subclasses()}}
![flask + jinja2 的 SSTI ---[攻防世界shrine] - 图6](/uploads/projects/u390550@fftlfh/09e7ac6908e8431febfde72cd7f29be9.png)
这里明显对()进行了过滤
这能从别的地方入手,例如flask的内置函数和变量
当然,config和self也被加入了黑名单
但是通过变量去读取app.config也会涉及到()的使用
所以值剩下内置函数
- get_flashed_messages(), url_for()
构造payload
- {{getflashedmessages.__globals[‘current_app’].config[‘FLAG’]}}
