一进去
以为 就是个简单的目录泄露
进去 flag.txt 提示
flag 在 /flllllllllllllag里面
这里给出了 访问这种文件的方法
一开始我 以为 只是简单把文件名 进行 hash加密 就好
但是 这样试了 一下 就有4种情况
因为它没具体指明文件名
可能是加密flllllllag 也可能是加密 /flllllllllag
所以就比较恶心
里面给出了提示
但是 怎么抓包 我也找不到 cookie_secret
之后进welcome 给出了个render
一开始没反应过来
之后 百度一下
没接触过 之前 最多碰到了ssti 还不是很熟
tornado render 我感觉 应该和 python 的jinjia注入差不多
感觉 也比较类似 命令执行 不过需要用{{}} 进行传递变量 主要是render可控 可控我们就有机会
别人的一个例子:
python SSTI tornado render模板注入
------------------------------------------------------------------------------------
import tornado.ioloop # 调库 里面的方法
import tornado.web #web 很明显了 就是利用 tomado 来开发web
class MainHandler(tornado.web.RequestHandler): #Handler 头 形参为 tornado.web.RequestHandler xxx.RequestHandler 这个库中web模块的RequestHandler方法
def get(self): #声明 获取函数
self.render('index.html') #获取self 中的 .render 方法 来获取当前页面 可能
class LoginHandler(BaseHandler): # 登录头 形参为 BaseHandler 基础头
def get(self): #获取函数
'''
当用户访登录的时候我们就得给他写cookie了,但是这里没有写在哪里写了呢?
在哪里呢?之前写的Handler都是继承的RequestHandler,这次继承的是BaseHandler是自己写的Handler #这居然是Py的继承??
继承自己的类,在类了加扩展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': #如果请求信息 是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}
escape 感觉可以省去
这里 获取 请求头的设置 原理 为
好家伙 模板注入 入门 都在这了: https://www.cnblogs.com/bmjoker/p/13508538.html https://www.jb51.net/article/88388.htm
差不多了 我理解 大概是通过了 Python 网络编程的方法 自动获取 用户提交的请求包 然后在服务器端 用了 python 来分析 然后调用了各种分装好的库自动生成个html页面 返回客户端
而客户端 通过{{}}可以构造用户的变量 上传到服务器 这里有点懵 为什么可以用这个{{}}构造
猜测 是把这些 已经提交的变量 放在一个字典里了 然后通过 {{}}进行 访问 与传参
看了篇文章 深入理解 Py模板 简单看了 大致 就是 用{{}}括起来的 会被 服务端 Py当作模板处理
用了 tornado 会 自动对 {{}}内容进行编译 这个 和很多 模板注入原理 应该都是一样的
服务端把我们请求包的 {{}} 包括的内容当作了模板 然后插进了里面的py代码然后执行 返回我们想要的页面
了解了 这些 可以开始做了 以为很简单 其实 我都没怎么接触
先找
应该可以构造{{escape(handler.settings['cookie_secret'])}}
失败了
也不行 可能是 对()解析出了问题 又或者没有 escape这个函数
直接
可以看到返回了 cookie_secret
那么 我们拿着 这个 按着 提示 进行md5 32位小写加密
可以得到
注意对文件名的加密 是'/flllllllag' ‘’ 内的文件名
然后 访问 也是 这样访问 /flllllllag 这应该和 模板的规则有关系 之前用jinja 搞的时候 它不能主动划分目录 需要用 / 来告诉它
手动出了 结果
准备写 poc验证
用 pocsuite3进行构造 payload
要用到的 库主要有 hashlib
参考 #主要是 少用 py 去进行md5加密
倒霉 pocsuite3 出了点小问题 懒得搞了 没必要 时间紧凑
简单用py 试了下
提示我们获取了 flag 我们可以 直接报全部 也可想办法只报 flag
这里运气比较好 flag 后面 啥都没有
over