[护网杯 2018] easy_tornado 1

看到题目,查一下tornado是什么,发现是python的web框架,因此猜测存在模板注入。

首先进入环境,有三个文件,一个文件告诉我们flag在哪,一个文件提示我们请求的url中的filehash如何构造,另外的welcome.txt里是render。经过谷歌后知道,render是python中的一个渲染函数,因此这题考察的应该是python的模板注入了。
因此我们接下来解题有2个点,一个就是要想办法得到cookie_secret,另外一个是要想办法利用模板注入。
这里原理直接引用一下别人的:

tornado render是python中的一个渲染函数,也就是一种模板,通过调用的参数不同,生成不同的网页,如果用户对render内容可控,不仅可以注入XSS代码,而且还可以通过{ {}}进行传递变量和执行简单的表达式。
例子:

#!/usr/bin/env python
# -*- coding:utf-8 -*- from tornado.web import UIModule from tornado import escape   class custom(UIModule):
 
    def render(self, *args, **kwargs):
        return escape.xhtml_escape('<h1>wupeiqi</h1>')
        #return escape.xhtml_escape('<h1>wupeiqi</h1>') ```#!/usr/bin/env python
# -*- coding:utf-8 -*-   import tornado.ioloop import tornado.web   class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.render('index.html')
        
         class LoginHandler(BaseHandler):
    def get(self):
        '''
        当用户访登录的时候我们就得给他写cookie了,但是这里没有写在哪里写了呢?
        在哪里呢?之前写的Handler都是继承的RequestHandler,这次继承的是BaseHandler是自己写的Handler
        继承自己的类,在类了加扩展initialize! 在这里我们可以在这里做获取用户cookie或者写cookie都可以在这里做
        '''
        '''
        我们知道LoginHandler对象就是self,我们可不可以self.set_cookie()可不可以self.get_cookie()
        '''
        # self.set_cookie()
        # self.get_cookie()
 
        self.render('login.html', **{
     
     'status': ''})   def login(request):
    #获取用户输入
    login_form = AccountForm.LoginForm(request.POST)
    if request.method == 'POST':
        #判断用户输入是否合法
        if login_form.is_valid():#如果用户输入是合法的
            username = request.POST.get('username')
            password = request.POST.get('password')
            if models.UserInfo.objects.get(username=username) and models.UserInfo.objects.get(username=username).password == password:
                    request.session['auth_user'] = username
                    return redirect('/index/')
            else:
                return render(request,'account/login.html',{
     
     'model': login_form,'backend_autherror':'用户名或密码错误'})
        else:
            error_msg = login_form.errors.as_data()
            return render(request,'account/login.html',{
     
     'model': login_form,'errors':error_msg})
 
    # 如果登录成功,写入session,跳转index

    return render(request, 'account/login.html', {
     
     'model': login_form})

在tornado模板中,存在一些可以访问的快速对象,例如:

<title>
     {
    
    {
    
     escape(handler.settings["cookie"]) }}
 </title>

handler.settings指向RequestHandler.settings,而RequestHandler.settings又指向self.application.settings 。  
所有handler.settings就指向RequestHandler.application.settings了。而这里面正是我们的环境变量。。

怎么利用到模板注入呢?只要你访问的不正确,就会跳转到这个页面:
在这里插入图片描述
get传入的msg参数里的内容似乎出现到了网页里,似乎这里就是模板注入的点。尝试输入{ {1+2}},发现500。。输入{ {1*2}},输出ORZ。。。。
经过一些尝试,发现这里应该是存在了过滤,但是并没有对我们要进行注入的内容进行过滤,因此直接获取环境变量:
在这里插入图片描述
成功得到了cookie_secret。然后写个python脚本,得到md5后的结果,就可以成功得到flag:

import hashlib
filename='/fllllllllllllag'
cookie_secret='3edd4d3c-190e-415f-9a7b-c6e4520f8249'
m=hashlib.md5()
m.update(filename.encode("utf-8"))
n=m.hexdigest()

v=cookie_secret+n
m=hashlib.md5()
m.update(v.encode("utf-8"))
n=m.hexdigest()
print(n)
    

猜你喜欢

转载自blog.csdn.net/rfrder/article/details/109119076
今日推荐