SSTI服务器模板注入
0x00 前言
前段时间打本校的ctf,有道叫幸运数字的题,只挖到一个xss,看了很久对题完全没有头绪,后来交wp的时候,出题师傅在群里说是SSTI,然后就去百度了一下,复现并学习一下这个漏洞。
0x01 SSTI服务端模板注入
服务端模板注入是服务端接收了用户的输入,将其作为 Web 应用模板内容的一部分,在进行目标编译渲染的过程中,执行了用户插入的恶意内容,因而可能导致了敏感信息泄露、代码执行、GetShell 等问题。其影响范围主要取决于模版引擎的复杂性。
通常测试模块类型的方式如下图:
0x02 环境配置
前面两篇正好写了python的后端模块flask和jinja2,这次我们使用flask+jinja2框架来测试一下。
首先后端是python,所以需要python环境,python在官网下载并安装,配置环境变量即可。
接着我们安装需要用到的库
- pip install jinja2
- pip install flask
- pip install virtualenv
只要上述所有库成功安装,环境就配置完毕了。
0x03 漏洞复现
我们的环境需要一个run.py文件和一个templates文件夹,templates文件夹内要有一个index.html。
index.html内容如下:
1 |
|
可以看到,html中只有一个post型的from需要我们填写提交。
然后是run.py(注意这次我用了python2.7):
1 |
|
这里python文件实现了将几个页面通过jinja2模块渲染部署,然后添加了一个敏感数据SECRET_KEY一会用得到,剩下的就是将index.html页面post过来的name,在网站check路径的页面中作为字符串输出。
我们在run.py目录打开命令行先输入python run.py先将服务运行起来:
然后我们打开浏览器输入127.0.0.1:5000,成功显示index.html中的页面:
我们输入任意字符串,浏览器跳转到127.0.0.1:5000/check目录,并且在网页中输出我们的字符串:
如上几步如果都成功,我们漏洞环境就搭建完成了。
0x04 漏洞利用
我们先尝试一下刚才图中的测试数据,输入
发现结果如下:
config是Flask模版中的一个全局对象,它代表“当前配置对象(flask.config)”,它是一个类字典的对象,它包含了所有应用程序的配置值。在大多数情况下,它包含了比如数据库链接字符串,连接到第三方的凭证,SECRET_KEY等敏感值。查看这些配置项目,我们只需注入如下命令
发现结果中存在我们刚才故意放进去的敏感信息:
在接下来的步骤之前,我先介绍两个内省实用程序:__mro__以及__subclasses__属性。
__mro__中的MRO(Method Resolution Order)代表着解析方法调用的顺序,它是每个对象元类的一个隐藏属性,当进行内省时会忽略dir输出。
__subclasses__属性在这里作为一种方法被定义为,对每个new-style class“为它的直接子类维持一个弱引用列表”,之后“返回一个包含所有存活引用的列表”。
__mro__允许我们在当前Python环境中追溯对象继承树,之后__subclasses__又让我们回到原点。从一个new-style object开始,例如str类型。使用__mro__我们可以从继承树爬到根对象类,之后在Python环境中使用__subclasses__爬向每一个new-style object。ok,这让我们能够访问加载到当前Python环境下的所有类。这样,我们就可以实现很多功能。
首先我们要做的第一件事便是选择一个new-style object用于访问object基类。我们可以使用__mro__属性访问对象的继承类。
输入
得到反馈只有str、basestring和object,按照数组的排序,我们应该选__mro__的第三个,也就是__mro__[2],接下来我们构造
可以查看到非常非常多的可访问类,这个时候我们要找到<type ‘file’>类,它是文件系统访问的关键。
然后我们可以用file类的read()方法访问一下当前目录的文本:
访问敏感目录可以得到很多信息:
我们就可以参考目标系统目录结构,对目标系统敏感文件进行访问。
0x05 参考资料
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!