flask下模版注入学习

文章参考自这里 以前只会一点php的漏洞,这里学习一下python开发的网站的漏洞

服务器模版注入

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from flask import Flask, request, render_template_string, render_template
app = Flask(__name__)
@app.route('/hello-template-injection')
def hello_ssti():
person = {'name':"world", 'secret':"UGhldmJoZj8gYWl2ZnZoei5wYnovcG5lcnJlZg=="}
if request.args.get('name'):
person['name'] = request.args.get('name')
template = '''<h2>Hello %s!</h2>'''%person["name"]
return render_template_string(template, person=person)
##### Private function if the user has local files.###



def get_user_file(f_name):
with open(f_name) as f:
return f.readlines()

app.jinja_env.globals['get_user_file'] = get_user_file
# Allows for use in Jinja2 templates
if __name__ == "__main__":
app.run(debug=True)

这里的服务器会在其context中执行用户输入的代码比如 blacsheep 而且加上在这个应用里面有获取文件信息的功能,所以还会导致文件包含的漏洞,比如 blacsheep 甚至是py的源代码 blacsheep 然后补的话也简单,这里主要还是开发者个人的问题,如果我们利用jinja2在模版里面用{{}}来包含变量,就不会导致任意代码的执行了 blacsheep

xss

这里不得不说有个很迷的事情... flask对很多文件提供了自动转义的特性,但是这里还是得说

1.模版可以关闭自动转义的特性 2.模版字符串非公共文件扩展名(.html,.htm一类)的时候不启用自动转义功能

所以按道理来说,payload为 http://127.0.0.1:5000/hello-template-injection?name=123.%3Cscript%3Ealert(/xss/)%3C/script%3E 的时候应该是会xss的,但是却并没有,我也不知道为什么,大概是玄学吧,后期要是懂了会回来改的...附图 blacsheep

静态模版xss

有的应用使用的是静态的模版,利用render_template返回,而render_template并不是一个会自动转义的扩展,所以如果我们hello.unsafe里面没有加转义的话,还是会导致xss的,比如我们在flaskrun.py下面建一个templates文件夹,里面放一个模版名字叫hello.unsafe(就用别人的名字了,我懒得想),然后里面写

1
2
3
4
5
6
7
8
9
10
11
{% autoescape true %} 
<h2>Good</h2>
<p>
Hello {{ name }}! I don't trust your input. I escaped it, just in case.
</p>
{% endautoescape %}

<h2>Bad</h2>
<p>
I trust all data! How are you {{ name }}?
</p>

顺便改一下python的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from flask import Flask, request, render_template_string, render_template

app = Flask(__name__)
@app.route('/hello-template-injection')
def hello_ssti():
person = {'name':"world", 'secret':"UGhldmJoZj8gYWl2ZnZoei5wYnovcG5lcnJlZg=="}
if request.args.get('name'):
person['name'] = request.args.get('name')
template = '<h2>Hello {{person.name}}!</h2>'
return render_template_string(template, person=person)
##### Private function if the user has local files.###

@app.route('/hello-xss')
def hello_xss():
name = "world"
template = 'hello.unsafe' # 'unsafe' file extension... totally legit.
if request.args.get('name'):
name = request.args.get('name')
return render_template(template, name=name)


def get_user_file(f_name):
with open(f_name) as f:
return f.readlines()

#app.jinja_env.globals['get_user_file'] = get_user_file # Allows for use in Jinja2 templates
if __name__ == "__main__":
app.run(debug=True)

xss的图 blacsheep 所以我们应该开启自动转义 在bad部分里面把改成 blacsheep

flask属性xss

首先代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
from flask import Flask, request, render_template_string, render_template

app = Flask(__name__)
@app.route('/hello-template-injection')
def hello_ssti():
person = {'name':"world", 'secret':"UGhldmJoZj8gYWl2ZnZoei5wYnovcG5lcnJlZg=="}
if request.args.get('name'):
person['name'] = request.args.get('name')
template = '<h2>Hello {{person.name}}!</h2>'
return render_template_string(template, person=person)
##### Private function if the user has local files.###

@app.route('/hello-xss')
def hello_xss():
name = "world"
template = 'hello.unsafe' # 'unsafe' file extension... totally legit.
if request.args.get('name'):
name = request.args.get('name')
return render_template(template, name=name)

@app.route("/hello-hi")
def hello_hi():
template = '''<title>No Injection Allowed!</title>
<a href='{{ url_for('hello_xss')}}?name={{ name e}}'>
Click here for a welcome message</a>'''
name = "world"
if request.args.get('name'):
name = request.args.get('name')
return render_template_string(template, name=name)

def get_user_file(f_name):
with open(f_name) as f:
return f.readlines()

#app.jinja_env.globals['get_user_file'] = get_user_file # Allows for use in Jinja2 templates
if __name__ == "__main__":
app.run(debug=True)


转义函数对于html的属性没卵用,链接作为一个整体,如果不加引号封装的话就会导致用户用onmouseover一类payload触发xss blacsheep 利用引号封装可以解决这个问题 blacsheep