jinja2模板注入_Flask Jinja2开发中遇到的的服务端注入问题研究

本文探讨了在Flask/Jinja2开发中遇到的服务端模板注入(SSTI)问题,通过分析`render_template_string`函数的默认上下文对象,揭示了request对象可能导致的DOS攻击风险以及config对象暴露敏感信息的隐患。通过URL注入,攻击者可能执行服务器端代码,如关闭应用服务或获取配置信息。文章强调了理解和防范SSTI的重要性。
摘要由CSDN通过智能技术生成

原标题:Flask Jinja2开发中遇到的的服务端注入问题研究

0×00. 前言

作为一个安全工程师,我们有义务去了解漏洞产生的影响,这样才能更好地帮助我们去评估风险值。本篇文章我们将继续研究Flask/Jinja2 开发中遇到的SSTI (服务端模板注入)问题, 如果你从未听过SSTI 或者没有弄清楚它到底是个什么东东,建议您最好先阅读一下。

0×01. 测试代码

为了更好地演示Flask/Jinja2 开发中的SSTI问题,我们搭建一个小的POC程序(基于Flask 框架),主要由两个python脚本组成:

Flask-test.py

e9038f88880e2fd3ad16fb5b35043e69.png

3ecb2d87171ecc3f99219048bef3c111.png

5b81ff930e139dcd02404edc5a4f21f1.png

一些开发者可能认为为一个简单的404错误页面去单独创建一个模板文件是多余的,他们更喜欢在404 视图函数中用模板字符串(正如上述测试代码中的page_not_found函数中的template字符串)代替单独的404模板文件; 一些开发者还会在返回的错误页面中提示用户是哪一个URL导致了404错误,但他们不把错误的URL传递给render_template_string模板上下文,而是喜欢用%s动态地将问题URL传递给模板字符串,这些看起来都很OK。但实际上真的是这样的吗,让我们接着往下看

0×02. render_template_string 函数中默认上下文对象引起的SSTI问题

我们开始测试,404函数功能没得问题,确实显示了错误信息,并指出哪一个URL导致了此问题

5ea8d6b01bfef4cbd3567032e1406b34.png

到这里,很多人可能都想到了这个404函数存在的问题,对,就是XSS,是的,的确存在XSS漏洞,这也属于SSTI,但这篇文章不想讨论这一点, 如果你再深入思考一下,可能会发现这里存在代码注入,比如当我们的URL是下面这样,URL中包含了Jinjia2语法表达式:

http://10.1.100.3:5000/{{8+8}}

490855f5f5493edc7e67ef2bd9c1eb0a.png

我们发现模板引擎执行了8+8,并返回了结果,这是一个简单的SSTI问题,我们再来看看其他有趣的SSTI 问题, 我们来看看

render_template_string 函数的定义:

def render_template_string(source, **context):"""Renders a template from the given template source string

with the given context.

:param source: the sourcecode of the template to be

rendered

:param context: the variables that should be available in the

context of the template.

"""ctx = _app_ctx_stack.top

ctx.app.update_template_context(context)return _render(ctx.app.jinja_env.from_string(source),

context, ctx.app)

这里有两个参数,一个是source,很简单就是需要渲染的模板字符串, 另一个是个包裹关键字传递参数(字典), 表示的是模板上下文,这里我们

就简单说一下这个Flask/Jinjia2开发中的模板上下文。主要有三个上下文,

一个是Jinjia globals(http://jinja.pocoo.org/docs/dev/templates/#builtin-globals)

一个是Flask Template globals(http://flask.pocoo.org/docs/0.10/templating/#standard-context)

最后一个是开发者自己显示添加的(这里暂且不表),前两个都是默认内置的(也就是上述代码中context参数默认值),这两个是我们要讨论的

render_template_string 默认上下文对象之request对象

经过一番调查,我们发现Flask Template globals 中有一个request对象,它表示当前请求对象(flask.request),它和你在视图代码中用到的

request对象(就是flask.request)一样,包含了所有的请求上下文信息,request 对象中包含一个environ对象,environ是一个字典,包含了所有的服务端环境变量信息,这个environ中有一个key:werkzeug.server.shutdown,这个key指向一个方法,这个方法是shutdown_server,就是用来关闭服务的,很显然这可以用来进行DOS攻击,

比如执行下面的URL,就可以关闭应用程序服务:

http://10.1.100.3:5000/{{request.environ['werkzeug.server.shutdown']()}}

幸亏生产环境用的是gunicorn这样的WSGI 服务器而不是werkzeug,这样才不会造成更大影响

render_template_string 默认上下文对象之config对象

这config对象也是一个Flask template global,它代表中当前配置文件对象,也就是flask.config 中Config对象实例(源代码flask/config.py)

5f5564c482c623f522277a9fa5be38f0.png

它是一个类似字典的对象,包含了应用程序所有的配置文件信息(你所有的用app.config.xxx | app.config['xxx'] 配置信息 都在config这个上下文对象中),在很多的例子中,这个condfig对象包含了很多敏感的信息,比如数据库连接信息,连接第三方服务的SECRET_KEY等

执行下面的URL,就可以获取当前应用程序所有的配置信息

http://10.1.100.3:5000/{{config.items()}}

75b1f786e9e88c238b5fcb010835204c.png

可以看到我们确实获取到了很多敏感的信息,包括数据库连接的密码, 所以不要认为把敏感信息保存在环境变量中就是安全的。

0×03. 反思render_template_string 默认上下文对象之config对象

0×02节已经提到过,render_template_string 默认上下文对象之config对象是flask.config中config对象的实例,它是一个类似字典的对象,config上下文对象有一些非常有意思的成员方法,比如:from_envvar , from_object ,from_pyfile , 当然还有一个成员属性root_path

这里我们先研究其成员方法from_object, 源代码如下:

27a0bce78f75bfefce19ba8bbfb43e8b.png

这段代码意思就是,如果传入from_object方法的参数obj是str|unicode类型,那么就载入obj所代表的的模块,然后将参数obj所代表的模块中所有的大写属性加入到当前config对象实例中

http://10.1.100.3:5000/{{config.from_object(‘os’)}}

这个url就是调用Flash Template Globals 中 config上下文对象中的from_object方法载入os模块,并将os模块中的大写属性加入config对象实例中

我们先来看一下os模块中有哪些大写属性值, 下面是一段测试代码,用来输出OS模块中所有的大写属性及其值

import os

for key in dir(os):

if key.isupper():

print key, ' ', getattr(os, key)

6b8d5f0eb26c15549b4c29e49bfe7398.png

e65a245a7b006256b47ad0629ada8136.png

我们执行一下下面这个URL,看看是否真的导入了指定模块(这里指的是os一些大写属性,当然也包括一些os模块内置方法)中大写属性到当前上下文对象config中http://10.1.100.3:5000/{{config.items()}}

00207f18fadf796251fb54c1f309613c.png

恩,确实导入了OS模块中所有大写属性,其实这里给我们提供了一个思路,我们可以通过SSTI漏洞执行config上下文对象中from_object这类的方法导入一些模块,然后寻找可以callabled属性,以此来绕过Jinjia2模板沙盒。

0×04. 总结

本篇文章是我对Flask/Jinjia2 开发中遇到的一些问题的初步研究,config这个上下文对象其实还有一些其他的利用方式,危害也更大些, 我会在下篇文章中涉及

Origin Refer: https://nvisium.com/blog/2016/03/09/exploring-ssti-in-flask-jinja2/

*本文作者ForrestX386,转载请注明来自FreeBuf.COM返回搜狐,查看更多

责任编辑:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值