题目来自:
[护网杯 2018]easy_tornado
首先进页面发现三个跳转:
乍一看真没有什么思路,就只有hints.txt里说了个md5加密的东西。
根据 "flag in /fllllllllllllag",可以猜测filename=/fllllllllllllag,那么关键就在于这个cookie_secret怎么拿到手呢?
看到网址上的反馈:
那么估计payload就是:
/file?filename=/fllllllllllllag&filehash=.....
没有试的地方,那就在这个filehash上乱试吧:
/file?filename=/fllllllllllllag&filehash=123
然后发生关键跳转和报错:
这里就是SSTI的知识了,来自博客:https://blog.csdn.net/qq_51927659/article/details/116031923
扩展:SSTI注入 SSTI就是服务器端模板注入(Server-Side Template Injection),也给出了一个注入的概念。 服务端模板:相当于很多公式,根据变量输出结果。这里的模板就是模板引擎根据数据自动生成前端页面。 常见的注入有:SQL 注入,XSS 注入,XPATH 注入,XML 注入,代码注入,命令注入等等。sql注入已经出世很多年了,对于sql注入的概念和原理很多人应该是相当清楚了,SSTI也是注入类的漏洞,其成因其实是可以类比于sql注入的。 sql注入是从用户获得一个输入,然后又后端脚本语言进行数据库查询,所以可以利用输入来拼接我们想要的sql语句,当然现在的sql注入防范做得已经很好了,然而随之而来的是更多的漏洞。 SSTI也是获取了一个输入,然后在后端的渲染处理上进行了语句的拼接,然后执行。错误的执行了用户输入。类比于 sql 注入。当然还是和sql注入有所不同的,SSTI利用的是现在的网站模板引擎(下面会提到),主要针对python、php、java的一些网站处理框架,比如Python的jinja2 mako tornado django,php的smarty twig,java的jade velocity。当这些框架对运用渲染函数生成html的时候会出现SSTI的问题。
filename知道了,cookie_secret
在哪呢?hints提示render,又根据题目
easy_tornado
可推测是服务器模板注入。
因为render()是tornado里的函数,可以生成html模板。是一个渲染函数 ,就是一个公式,能输出前端页面的公式。
tornado是用Python编写的Web服务器兼Web应用框架,简单来说就是用来生成模板的东西。和Python相关,和模板相关,就可以推测这可能是个ssti注入题了。
/file?filename=/fllllllllllllag&filehash={{1}}
为什么使用双花括号?
Tornado templates support control statements and expressions. Control statements are surrounded by {% %}, e.g. {% if len(items) > 2 %}. Expressions are surrounded by {{ }}, e.g. {{ items[0] }}.
Tornado模板支持控制语句和表达式。控制 语句被{%%}包围,例如{%if len(items)>2%}。 表达式被{{}}所包围,例如{{items[0]}。
模板注入必须通过传输型如{{xxx}}的执行命令。探测方式很简单,给一个参数赋值{{22*22}}
返回484则必然存在模板注入。
但是当我们输入error?msg={{1}}
就可以得到回显,说明此处是存在SSTI注入漏洞的。
当我构造的payload为:error?msg={{2*2}}的时候,回显的结果是orz。因此我们可以猜测出,此处是出现了过滤。
而此时我们需要找的是cookie_secret。
搜素百度得Tornado框架的附属文件handler.settings中存在cookie_secret;
Handler这个对象,Handler指向的处理当前这个页面的RequestHandler对象:
RequestHandler中并没有settings这个属性,与RequestHandler关联的Application对象(Requestion.application)才有setting这个属性 handler 指向RequestHandler 而RequestHandler.settings又指向self.application.settings 所有handler.settings就指向RequestHandler.application.settings了!
此时构造payload:
/error?msg={{handler.settings}
那么这个cookie_secret我们就拿到手了,现在直接可以按照它的意思,先对filename进行md5加密,然后把这个cookie_secret拼接在前面再进行md5加密拿到最后的payload,也就是hash值。
(注:这里用的是32位小写,MD5加密后的位数有两种类型:16位与32位,默认使用32位。16位实际上是从32位字符串中取中间的第9位到第24位的部分,一般都是默认的32位)
/file?filename=/fllllllllllllag&filehash=0ed1e3f7c4490e013a75f2201478afa5
得到flag。