首页科技娱乐体育干货女人设计时尚旅游美食语录健康

服务端模板注入攻击 (SSTI) 之浅析

2015-11-05 17:11:00来源:20区编辑:转角遇见你

服务端模板注入攻击 (SSTI) 之浅析


点击上方“红客联盟”可以订阅哦!



Author: RickGray (知道创宇404安全实验室)


在今年的黑帽大会上 James Kettle 讲解了 《Server-Side Template Injection: RCE for the modern webapp》,从服务端模板注入的形成到检测,再到验证和利用都进行了详细的介绍。本文在理解原文内容的基础上,结合更为具体的示例对服务端模板注入的原理和扫描检测方法做一个浅析。


0x00 模板注入与常见Web注入



就注入类型的漏洞来说,常见 Web 注入有:SQL 注入,XSS 注入,XPATH 注入,XML 注入,代码注入,命令注入等等。注入漏洞的实质是服务端接受了用户的输入,未过滤或过滤不严谨执行了拼接了用户输入的代码,因此造成了各类注入。下面这段代码足以说明这一点:


12345678// SQL 注入$query = "select * from sometable where id=".$_GET['id'];mysql_query($query); ------------- 华丽的分割线 ------------- // 模版注入$temp->render("Hello ".$_GET['username']);


而服务端模板注入和常见Web注入的成因一样,也是服务端接收了用户的输入,将其作为 Web 应用模板内容的一部分,在进行目标编译渲染的过程中,执行了用户插入的恶意内容,因而可能导致了敏感信息泄露、代码执行、GetShell 等问题。其影响范围主要取决于模版引擎的复杂性。


0x01 模板注入原理



模板注入涉及的是服务端Web应用使用模板引擎渲染用户请求的过程,这里我们使用 PHP 模版引擎 Twig 作为例子来说明模板注入产生的原理。考虑下面这段代码:


1234567<?phprequire_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;


使用 Twig 模版引擎渲染页面,其中模版含有 {{name}} 变量,其模版变量值来自于 GET 请求参数 $_GET["name"]。显然这段代码并没有什么问题,即使你想通过 name 参数传递一段 JavaScript 代码给服务端进行渲染,也许你会认为这里可以进行 XSS,但是由于模版引擎一般都默认对渲染的变量值进行编码和转义,所以并不会造成跨站脚本攻击:



但是,如果渲染的模版内容受到用户的控制,情况就不一样了。修改代码为:


1234567<?phprequire_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;


上面这段代码在构建模版时,拼接了用户输入作为模板的内容,现在如果再向服务端直接传递 JavaScript 代码,用户输入会原样输出,测试结果显而易见:



对比上面两种情况,简单的说服务端模板注入的形成终究还是因为服务端相信了用户的输出而造成的(Web安全真谛:永远不要相信用户的输入!)。当然了,第二种情况下,攻击者不仅仅能插入 JavaScript 脚本,还能针对模板框架进行进一步的攻击,此部分只说明原理,在后面会对攻击利用进行详细说明和演示。


0x02 模板注入检测



上面已经讲明了模板注入的形成原来,现在就来谈谈对其进行检测和扫描的方法。如果服务端将用户的输入作为了模板的一部分,那么在页面渲染时也必定会将用户输入的内容进行模版编译和解析最后输出。


借用本文第二部分所用到的代码:


123456