Python 模板引擎的注入问题分析
这几年比较火的一个漏洞就是jinjia2之类的模板引擎的注入,通过注入模板引擎的一些特定的指令格式,比如{{1+1}}而返回了2得知漏洞存在。实际类似的问题在Python原生字符串中就存在,尤其是Python3.6新增f字符串后,虽然利用还不明确,但是应该引起注意。
最原始的%
userdata={"user":"jdoe","password":"secret"} passwd=raw_input("Password:") ifpasswd!=userdata["password"]: print("Password"+passwd+"iswrongforuser%(user)s")%userdata
如果用户输入%(password)s那就可以获取用户的真实密码了。
format方法相关
https://docs.python.org/3/library/functions.html#format
除了上面的payload改写为print("Password"+passwd+"iswrongforuser{user}").format(**userdata)之外,还可以
>>>importos >>>'{0.system}'.format(os) '<built-infunctionsystem>'
会先把0替换为format中的参数,然后继续获取相关的属性。
但是貌似只能获取属性,不能执行方法?但是也可以获取一些敏感信息了。
例子:http://lucumr.pocoo.org/2016/12/29/careful-with-str-format/
CONFIG={ 'SECRET_KEY':'supersecretkey' } classEvent(object): def__init__(self,id,level,message): self.id=id self.level=level self.message=message defformat_event(format_string,event): returnformat_string.format(event=event)
如果format_string为{event.__init__.__globals__[CONFIG][SECRET_KEY]}就可以泄露敏感信息。
Python3.6中的f字符串
这个字符串非常厉害,和JavascriptES6中的模板字符串类似,有了获取当前context下变量的能力。
https://docs.python.org/3/reference/lexical_analysis.html#f-strings
>>>a="Hello" >>>b=f"{a}World" >>>b 'HelloWorld'
而且不仅仅限制为属性了,代码可以执行了。
>>>importos >>>f"{os.system('ls')}" binetclibmediaprocrunsrvtmpvar devhomelinuxrcmntrootsbinsysusr '0' >>>f"{(lambdax:x-10)(100)}" '90'
但是貌似没有把一个普通字符串转换为f字符串的方法,也就是说用户很可能无法控制一个f字符串,可能无法利用,还需要继续查一下。