virusdefender's blog ʕ•ᴥ•ʔ

Python 模板字符串与模板注入

这几年比较火的一个漏洞就是 jinjia2 之类的模板引擎的注入,通过注入模板引擎的一些特定的指令格式,比如{% raw %}{{1+1}}{% endraw %}而返回了2得知漏洞存在。实际类似的问题在 Python 原生字符串中就存在,尤其是Python 3.6新增 f 字符串后,虽然利用还不明确,但是应该引起注意。

最原始的%

1userdata = {"user" : "jdoe", "password" : "secret" }
2passwd  = raw_input("Password: ")
3
4if passwd != userdata["password"]:
5    print ("Password " + passwd + " is wrong for user %(user)s") % userdata

如果用户输入 %(password)s 那就可以获取用户的真实密码了。

format方法相关

https://docs.python.org/3/library/functions.html#format

除了上面的 payload 改写为print ("Password " + passwd + " is wrong for user {user}").format(**userdata)之外,还可以

1>>> import os
2>>> '{0.system}'.format(os)
3'<built-in function system>'

会先把0替换为format中的参数,然后继续获取相关的属性。

但是貌似只能获取属性,不能执行方法?但是也可以获取一些敏感信息了。

例子: http://lucumr.pocoo.org/2016/12/29/careful-with-str-format/

 1CONFIG = {
 2    'SECRET_KEY': 'super secret key'
 3}
 4
 5class Event(object):
 6    def __init__(self, id, level, message):
 7        self.id = id
 8        self.level = level
 9        self.message = message
10
11def format_event(format_string, event):
12    return format_string.format(event=event)

如果 format_string{event.__init__.__globals__[CONFIG][SECRET_KEY]} 就可以泄露敏感信息。

理论上,可以通过类的各种继承关系找到想要的信息,比如在 Django 中的思路为 https://xianzhi.aliyun.com/forum/read/615.html

Python 3.6中的f字符串

这个字符串非常厉害,和 Javascript ES6 中的模板字符串类似,有了获取当前 context 下变量的能力。

https://docs.python.org/3/reference/lexical_analysis.html#f-strings

1>>> a = "Hello"
2>>> b = f"{a} World"
3>>> b
4'Hello World'

而且不仅仅限制为属性了,代码可以执行了。

1>>> import os
2>>> f"{os.system('ls')}"
3bin      etc      lib      media    proc     run      srv      tmp      var
4dev      home     linuxrc  mnt      root     sbin     sys      usr
5'0'
6
7>>> f"{(lambda x: x - 10)(100)}"
8'90'

但是貌似没有把一个普通字符串转换为 f 字符串的方法,也就是说用户很可能无法控制一个 f 字符串,可能无法利用,还需要继续查一下。

提交评论 | 微信打赏 | 转载必须注明原文链接

#安全 #Python