SSTI模板注入

2022-10-27 14:34:34 浏览数 (1)

前言

模板引擎

模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档。

模板引擎会提供一套生成HTML代码的程序,然后只需要获取用户的数据,然后放到渲染函数里,然后生成模板 用户数据的前端HTML页面,然后反馈给浏览器,呈现在用户面前。

这是一个模板的例子:

代码语言:javascript复制
<html>
    <head>
        <title>{{title}}</title>
    </head>
    <body>
        <form method="{{method}}",action={{action}}>
            <input type="text" name="user" value="{{username}}">
        </form>
        <p>
            This page took {{microtime(true) - time}} seconds to render.
        </p>
    </body>
</html>

对应的后端代码逻辑是:

代码语言:javascript复制
$templateEngine = new TemplateEngine();
$tpl = $templateEngine->loadFile(login.tpl);
$tpl->assign('title','Login');
$tpl->assign('method','post');
$tpl->assign('action','login.php');
$tpl->assign('username',getUserNameFromCookie());
$tpl->assign('time',microtime(true));
$tmp->show();

SSTI(服务器端模板注入)

SSTI(Server-Side Template Injection)就是服务器端模板注入。

SSTI的本质也是注入,

SQL注入在本应该插入正常数据的地方插入了SQL语句,破坏了原本的SQL语句的格式,从而执行攻击者想要的SQL语句。

注入就是格式化字符串漏洞的一种体现。

利用漏洞可以对服务端进行输入,服务端在接收用户的恶意输入以后,未经任何处理就将其作为 Web 应用模板内容的一部分,模板引擎在进行目标编译渲染的过程中,执行了用户插入的可以破坏模板的语句,因而可能导致了信息泄露代码执行GetShell 等问题。

各模板引擎的相关信息

SSTI模板注入基本原理

用户的输入作为模板变量中的值

代码语言:javascript复制
<?php
    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;
?>

对这段代码输入<script>alert(welcome)</script>,不会执行脚本中的代码,会进行HTML编码转义,以原样输出,不会造成XSS攻击。

用户的输入作为模板内容的一部分

代码语言:javascript复制
<?php
    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;
?>

对这段代码模板输入<script>alert(welcome)</script>,这段JavaScript代码会作为模板内容的一部分并执行,会造成XSS漏洞。

不同的模板有不同的语法,见本文各模板引擎相关信息

例题

题目基本信息

看题目名,可以知道是考察SSTI相关知识。

解题步骤

查看网页的源代码

需要我们传入一个flag参数。

同时可以看到这样一段注释:

代码语言:javascript复制
<!-- You know, in the flask, We often set a secret_key variable.-->

可知,该网页使用的是Flask框架,模板引擎使用的是Jingja2

Flask模板中,configFlask模版中的一个全局对象,它包含了所有应用程序的配置值。会有一个SECRET_KEY变量,根据这个提示,我们需要获取这个SECRET_KEY

接下来我们尝试用get方式传入一段HTML代码:

可以看到源码发生了改变,所以可以使用SSTI进行攻击。

下面是Jinja2的基础语法:

代码语言:javascript复制
{% … %}
{{ … }}
{# … #}

要查看SECRET_KEY,设置我们的payload为:

代码语言:javascript复制
?flag = {{config.SECRET_KEY}}

使用get方式传参得到flag。

0 人点赞