美文网首页
[护网杯 2018]easy_tornado

[护网杯 2018]easy_tornado

作者: jun123123 | 来源:发表于2020-05-11 20:08 被阅读0次

    [护网杯 2018]easy_tornado

    给了三个txt,flag.txt给出了flag文件,welcome.txt提示了render,hints.txt给出了摘要算法md5(cookie_secret+md5(filename))。并且观察url可以发现提交了两个参数分别为一个filename和一个filehash。既然这里给出了摘要算法,应该就是提交的filehash值算法。

    这里要计算filehash值就要获取cookie_secret,根据welcome提示,应该是render模板注入(ssti),通过ssti获取cookie_secret再计算出filehash读取flag文件获取flag。注入点在一个错误提示中,当提交的filehash不正确时就会跳转到一个错误消息的url,其中有一个参数为msg,修改这个参数发现提交的值显示在页面中。提交msg={{1}}回显为1,尝试提交{{1+1}}发现被过滤了,但是{{2^2}}回显为0,说明确实存在ssti。但是如何获取cookie_secret还是不知道,看了一下wp发现时利用handler.settings进行读取,但是都没有说明为什么这样读取。我们利用这个变量可以获取到cookie_secret然后使用hints.txt中给出的算法即可计算出filehash读取flag文件。

    Tornado templates support control statements and expressions. Control statements are surrounded by {% and %}, e.g. {% if len(items) > 2 %}. Expressions are surrounded by {{ and }}, e.g. {{ items[0] }}.

    Python中从服务端模板注入到沙盒逃逸的源码探索 (一)一文对为什么利用handler.settings获取cookie_secret做出了部分解释,该文放出了部分tornado源码,我们可以在一下代码中看到有一个将self赋值给handler的操作

        def get_template_namespace(self):
            namespace = dict(
                handler=self,
                request=self.request,
                current_user=self.current_user,
                locale=self.locale,
                _=self.locale.translate,
                pgettext=self.locale.pgettext,
                static_url=self.static_url,
                xsrf_form_html=self.xsrf_form_html,
                reverse_url=self.reverse_url
            )
            namespace.update(self.ui)
            return namespace
    

    这是RequestHandler类中的一个方法,也就是说这里将RequestHandler类本身赋值给了handler,因此handler.settings实际上就是RequestHandler.settings(self.settings),这一点在tornado文档中也有说明。

    tornado提供了一些变量可以在模板中访问,因此我们可以利用handler来访问settings。

    Tornado小记 -- 模板中的Handler一文对RequestHandler.settings做出了解释,RequestHandler.settings实际上是指向了self.application.settings,在tornado文档中也能看到这个说明。

    RequestHandler.settings

    An alias for self.application.settings.

    在[tornado文档](https://www.tornadoweb.org/en/stable/guide/security.html#User authentication)此处能够看到

    class MainHandler(BaseHandler):
        @tornado.web.authenticated
        def get(self):
            name = tornado.escape.xhtml_escape(self.current_user)
            self.write("Hello, " + name)
    
    settings = {
        "cookie_secret": "__TODO:_GENERATE_YOUR_OWN_RANDOM_VALUE_HERE__",
        "login_url": "/login",
    }
    application = tornado.web.Application([
        (r"/", MainHandler),
        (r"/login", LoginHandler),
    ], **settings)
    

    在这里我们可以看到在cookie_secret是存在settings中的,settings又作为参数传入了Application构造函数,因此可以通过self.application.settings获取到cookie_secret。

    既然这里最终是访问到self.application.settings获取cookie_secret,并且需要利用tornado提供的handler来访问,那么我们不仅可以通过handler.settings来获取,也可以使用handler.application.settings,这样实际上也是访问到self.application.settings。

    相关文章

      网友评论

          本文标题:[护网杯 2018]easy_tornado

          本文链接:https://www.haomeiwen.com/subject/haupnhtx.html