打开题目,发现有三个链接,分别是
- /flag.txt
- /welcome.txt
- /hints.txt
内容分别为
/flag.txt
flag in /fllllllllllllag
/welcome.txt
render
/hints.txt
md5(cookie_secret+md5(filename))
从第二个welcome.txt可以猜到,这题应该是考SSTI注入,而flag就在fllllllllllllag文件里面。
但是观察url发现,后面还需要一个filehash参数,如果不正确就会报错
http://220.249.52.134:39518/file?filename=/hints.txt&filehash=7ead89c8b1dd04017dcc2d72dbce2be2
而这个filehash的计算方式在hints.txt中也给了
md5(cookie_secret+md5(filename))
filename是fllllllllllllag,就剩下cookie_secret需要找出来了。
经过查阅tornado文档,找到cookie_secret的定义:
application = tornado.web.Application([
(r"/", MainHandler),
], cookie_secret="__TODO:_GENERATE_YOUR_OWN_RANDOM_VALUE_HERE__")
并且尝试在源码中搜索,还可以看到cookie_secret可以通过self.application.settings["cookie_secret"]
的形式取得。
这段代码在RequestHandler
类中,那么只要能得到这个对象,就可以得到cookie_secret
。
因为前面welcome.txt已经提示是SSTI注入,那么肯定是有一处地方是可以注入的,经过一番测试,最后发现Error页面可以注入。
http://220.249.52.134:39518/error?msg=Error
//return Error
http://220.249.52.134:39518/error?msg=12345
//return 12345
但是测试后发现[]()_/*"'
都被过滤了,所以魔术方法是用不了了。
查阅文档,发现这么一段:
表达式可以是任意的Python表达式, 包括函数调用. 模板代码会在包含以下对象 和函数的命名空间中执行 (注意这个列表适用于使用
RequestHandler.render
和render_string
渲染模板的情况. 如果你直接在RequestHandler
之外使用tornado.template
模块, 下面这些很多都不存 在).
escape
:tornado.escape.xhtml_escape
的别名xhtml_escape
:tornado.escape.xhtml_escape
的别名url_escape
:tornado.escape.url_escape
的别名json_encode
:tornado.escape.json_encode
的别名squeeze
:tornado.escape.squeeze
的别名linkify
:tornado.escape.linkify
的别名datetime
: Pythondatetime
模块handler
: 当前的RequestHandler
对象request
:handler.request
的别名current_user
:handler.current_user
的别名locale
:handler.locale
的别名_
:handler.locale.translate
的别名static_url
:handler.static_url
的别名xsrf_form_html
:handler.xsrf_form_html
的别名reverse_url
:Application.reverse_url
的别名- 所有从
ui_methods
和ui_modules
Application
设置的条目- 任何传递给
render
或render_string
的关键字参数
也就是说,在模板中可以直接使用列表中的这些别名,来使用原本的模块或者对象。
可以看到,handler代表的就是当前的RequestHandler对象,那么通过handler.application.settings
就可以得到cookie_secret了。
加密部分就很简单了,写个python脚本就可以:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import hashlib
filename="/fllllllllllllag"
cookie_secret="******************"
enc=""
enc=hashlib.md5(cookie_secret+hashlib.md5(filename.encode(encoding='utf-8')).hexdigest()).hexdigest()
print(enc)
将filename和filehash分别替换后访问,得到flag。