本文给大家主要讲述的是 Python 模板引擎的注入问题分析,以及如何防范和需要注意的地方,有需要的小伙伴可以参考下
Python 是一种面向对象、解释型计算机程序设计语言,由 Guido van Rossum 于 1989 年底发明,第一个公开发行版发行于 1991 年。Python 语法简洁而清晰,具有丰富和强大的类库。它常被昵称为胶水语言,它能够把用其他语言制作的各种模块(尤其是 C/C++)很轻松地联结在一起。
这几年比较火的一个漏洞就是 jinjia2 之类的模板引擎的注入,通过注入模板引擎的一些特定的指令格式,比如 {{1+1}} 而返回了 2 得知漏洞存在。实际类似的问题在 Python 原生字符串中就存在,尤其是 Python 3.6 新增 f 字符串后,虽然利用还不明确,但是应该引起注意。
最原始的 %
- userdata = {"user" : "jdoe", "password" : "secret" }
- passwd = raw_input("Password: ")
- if passwd != userdata["password"]:
- print ("Password " + passwd + " is wrong for user %(user)s") % userdata
如果用户输入 %(password)s 那就可以获取用户的真实密码了。
format 方法相关
除了上面的 payload 改写为 print ("Password" + passwd + "is wrong for user {user}").format(**userdata) 之外,还可以
- >>> import os
- >>> '{0.system}'.format(os)
- '<built-in function system>'
会先把 0 替换为 format 中的参数,然后继续获取相关的属性。
但是貌似只能获取属性,不能执行方法?但是也可以获取一些敏感信息了。
例子: {aa1aa}
- CONFIG = {
- 'SECRET_KEY': 'super secret key'
- }
- class Event(object):
- def __init__(self, id, level, message):
- self.id = id
- self.level = level
- self.message = message
- def format_event(format_string, event):
- return format_string.format(event=event)
如果 format_string 为 {event.__init__.__globals__[CONFIG][SECRET_KEY]} 就可以泄露敏感信息。
Python 3.6 中的 f 字符串
这个字符串非常厉害,和 Javascript ES6 中的模板字符串类似,有了获取当前 context 下变量的能力。
- >>> a = "Hello"
- >>> b = f"{a} World"
- >>> b
- 'Hello World'
而且不仅仅限制为属性了,代码可以执行了。
- >>> import os
- >>> f"{os.system('ls')}"
- bin etc lib media proc run srv tmp var
- dev home linuxrc mnt root sbin sys usr
- '0'
- >>> f"{(lambda x: x - 10)(100)}"
- '90'
但是貌似 没有 把一个普通字符串转换为 f 字符串的方法,也就是说用户很可能无法控制一个 f 字符串,可能无法利用,还需要继续查一下。
来源: