前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Flask Jinja2开发中遇到的的服务端注入问题研究

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

作者头像
FB客服
发布2018-02-26 15:53:02
9640
发布2018-02-26 15:53:02
举报
文章被收录于专栏:FreeBufFreeBuf

0×00. 前言

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

0×01. 测试代码

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

Flask-test.py

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

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

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

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

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

我们发现模板引擎执行了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)

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

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

<点击阅读原文查看链接>

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

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

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, 源代码如下:

这段代码意思就是,如果传入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)

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

恩,确实导入了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/

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-06-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FreeBuf 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0×00. 前言
  • 0×01. 测试代码
  • 0×02. render_template_string 函数中默认上下文对象引起的SSTI问题
  • 0×03. 反思render_template_string 默认上下文对象之config对象
  • 0×04. 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档