2025.2.8——二、Confusion1 SSTI模板注入|Jinja2模板

news2025/2/11 11:08:38

题目来源:攻防世界  Confusion1

目录

一、打开靶机,整理信息

二、解题思路

step 1:查看网页源码信息

step 2:模板注入

step 3:构造payload,验证漏洞

step 4:已确认为SSTI漏洞中的Jinjia2模板漏洞,构造payload

三、小结


一、打开靶机,整理信息

        题目信息:php语言,可以用扫描器,

        Login和Register功能都用不了,Home就是当前页面

冷知识:蟒蛇——python  大象——elePHPant

蛇缠住了大象,猜测本题中用到了php+python,网页源码中该图片名称为:PythonVsPhp

二、解题思路

step 1:查看网页源码信息

Home页面读到了网页源码信息

Login、Register页面虽然报错,但是也包含了信息(看到其他师傅的wp才发现,报错页面也是会包含信息的)

        根据txt后缀,这里应该是暗示了flag的位置

step 2:模板注入

        新知识:服务器模板注入(SSTI)

服务器模板注入(SSTI)

1.概念:当应用程序在处理用户输入并将其直接嵌入到模板中进行渲染,而没有进行适当的输入验证和过滤时,就可能发生 SSTI 漏洞。攻击者可以利用这个漏洞,通过精心构造恶意输入,让模板引擎执行恶意代码,从而控制服务器。

2.攻击原理

  • 模板引擎工作流程:正常情况下,模板引擎从应用程序获取数据,将数据填充到模板的占位符中,然后生成最终的 HTML 页面返回给用户。例如,一个简单的模板可能是 “Hello, {{username}}!”,其中 {{username}} 是占位符,应用程序会将实际的用户名数据填充进去。
  • 攻击方式:攻击者利用 SSTI 漏洞,将恶意代码作为数据输入,模板引擎会把这些恶意代码当作合法的模板指令进行解析和执行。例如,在某些支持 Python 代码执行的模板引擎中,攻击者可能输入 {{__import__('os').system('rm -rf /')}},这条恶意代码如果被执行,就可能删除服务器根目录下的所有文件(在 Linux 系统中),造成严重破坏。

3.检测方法

  • 手动测试:在输入处输特殊字符与模板语句,如 Jinja2 中输{{7*7}} ,看能否执行。故意输错引发报错,分析含模板引擎调试信息的错误提示,判断是否存在漏洞。
  • 自动化扫描工具:借助 OWASP ZAP 等 Web 漏洞扫描器,模拟攻击场景检测。利用 Bandit 等代码扫描工具,排查开发代码中用户输入直接嵌入模板且无过滤的风险。
  • 日志分析:审查 Web 服务器日志,找含模板语法或恶意代码的异常请求。查看应用程序日志,依据处理用户输入时的异常记录,判断是否存在 SSTI 漏洞。

        如果处于解题阶段,可以挨个尝试漏洞(需要很大的知识储备量),但是学习的目的是为了增加知识储备量,所以学会漏洞原理以及出现场景才是重点。

        参考思路:https://blog.csdn.net/l8947943/article/details/122241240

step 3:构造payload,验证漏洞

        构造如下payload:(Login.php页面同样效果)

/register.php/{{7*7}}}

        说明存在SSTI漏洞,继续测试

/register.php/{{7*'7'}}}

        成功回显,说明是Jinja2或Twig模板

Jinja2

1.解释:Jinja2 是 Python 中一个非常流行的模板引擎,就像是一个神奇的 “代码模板加工厂” ,帮助开发者轻松创建动态网页或生成各种格式化文本。

2.基本用途:

  • 动态网页生成:在 Web 开发中,你可能需要根据不同用户请求,展示不同数据的网页。比如,电商网站要根据每个用户的浏览历史,展示个性化推荐商品列表。使用 Jinja2,你可以创建一个网页模板,里面预留一些 “空位”,然后根据具体数据来填充这些 “空位”,快速生成动态网页。
  • 配置文件生成:在开发过程中,有时需要生成各种配置文件。比如,为不同的服务器环境生成对应的数据库连接配置文件。Jinja2 能依据通用的配置模板和特定环境参数,生成准确的配置文件。

3.基础语法——Python表达式

  • 变量:用 {{ variable_name }} 来表示。变量就是你在 Python 代码中定义好,要传递到模板中的数据。例如,在 Python 代码中定义 name = "Alice",在 Jinja2 模板里就可以用 {{ name }} 来显示 “Alice”。
  • 控制结构
    • if 语句:类似于 Python 中的 if 条件判断。例如,{% if user.is_authenticated %} 欢迎,{{ user.name }}! {% else %} 请登录 {% endif %},它会根据 user.is_authenticated 的真假来决定显示哪部分内容。
    • for 循环:用于遍历列表等可迭代对象。比如,有一个商品列表 products = ['手机', '电脑', '平板'],在模板中可以用 {% for product in products %} <li>{{ product }}</li> {% endfor %},这样就能循环展示每个商品列表项。
  • 过滤器:对变量进行处理。例如,{{ "hello world" | capitalize }},这里 capitalize 是过滤器,它会把字符串 “hello world” 首字母大写,结果为 “Hello world”。常用过滤器还有 length(获取字符串或列表长度)、format(格式化字符串)等。

Twig模板

1.简述:展示逻辑分离。Twig 允许开发者创建模板文件,其中包含静态内容(如 HTML 标签)和动态占位符,然后通过 PHP 代码将动态数据填充到这些占位符中,最终生成完整的输出页面。

2.基本语法:

  • 变量输出:使用双花括号 {{ }} 来输出变量。例如,在 PHP 代码中定义了一个变量 $name = 'John';,在 Twig 模板中可以使用 {{ name }} 来输出这个变量的值。
  • 控制结构
    • if 语句:用于条件判断。
    • for 循环:用于遍历数组或对象。

    • 过滤器:用于对变量进行处理。例如,{{ text|upper }} 会将 text 变量的值转换为大写。常用的过滤器还有 length(获取字符串或数组的长度)、date(格式化日期)等。

        二者差异性:Jinja2 的语法相对更灵活一些,能支持更多 Python 风格的表达式。Twig 语法更多遵循 PHP 的规范和习惯。

区分方法:用python的表达式,看能否正确解析,成功则为Jinja2,否则为Twig

  • Jinja2
    • Python 风格表达式:尝试输入 Python 风格的表达式,如 {{ [1, 2, 3][0] }} (列表索引操作)或 {{ __import__('os').system('id') }} (尝试执行系统命令,在有漏洞情况下)。如果页面能正确解析并执行这些 Python 风格的操作,很可能是 Jinja2 模板引擎。因为 Jinja2 与 Python 紧密结合,支持这类 Python 表达式。
    • 内置函数:测试 Jinja2 特有的内置函数,如 {{ cycler('a', 'b').next() }} ,若能得到预期结果,则可辅助判断为 Jinja2。
  • Twig
    • PHP 相关特性:输入符合 PHP 语法习惯的内容。例如,测试 Twig 中特有的功能,如使用 date 过滤器按照 PHP 的日期格式进行日期处理,输入 {{ "now"|date("Y-m-d") }} ,如果能正确显示格式化后的日期,更倾向于是 Twig 模板。

传参:/register.php/{{ __import__('os').system('id') }}

得到回复:不要使用这种方法——意为该漏洞存在,说明方向正确

传参:/register.php/{{ "now"|date("Y-m-d") }}

得到回复:不行!换一种方法

        由此可以确定是Jiinjia2模板,这里也验证了Home页面的图片,蟒蛇python更胜一筹

step 4:已确认为SSTI漏洞中的Jinjia2模板漏洞,构造payload

        使用python的open函数来读取文件,构造payload如下

/register.php/{{ open('/opt/flag_1de36dff62a3a54ecfbc6e1fd2ef0ad1.txt').read() }}

        回显失败,应该是被过滤了,再次构造

getattr函数

1.Python内置函数,主要用于获取对象的属性值。

2.语法和参数

getattr(object, name[, default])

  • object:必选参数,要获取属性的对象,可以是自定义类的实例、内置对象(如列表、字典等)。
  • name:必选参数,字符串类型,表示要获取的属性名。
  • default:可选参数,如果指定的属性不存在,返回该默认值;若未提供该参数,且属性不存在,则会引发 AttributeError 异常。
/register.php/{{ ''.__class__.__mro__[2].__subclasses__()[40]('/opt/flag_1de36dff62a3a54ecfbc6e1fd2ef0ad1.txt' ).read() }}

        仍然回显错误,尝试逐字符拼接函数名

/register.php/{{ ''.__class__.__mro__[2].__subclasses__()[40]('/opt/flag_1de36dff62a3a54ecfbc6e1fd2ef0ad1.txt' )[ 'r' + 'e' + 'a' + 'd' ]() }}

        仍然被过滤,下面用到了request函数,构造payload

/register.php/{{''[request.args.a][request.args.b][2][request.args.c]()[40]('/opt/flag_1de36dff62a3a54ecfbc6e1fd2ef0ad1.txt')[request.args.d]()}}?a=__class__&b=__mro__&c=__subclasses__&d=read

        得到了flag回显。

以上payload解释:

以一个空字符串 '' 作为起始对象,因为在 Python 中,所有对象都继承自 object 类,我们可以通过空字符串对象逐步向上查找类层次结构

''.__class__:获取空字符串对象的类,即 str 类。

__mro__:是 Python 类的一个属性,它表示方法解析顺序(Method Resolution Order),是一个包含类层次结构的元组。

[2]:通过索引 2 可以从 str 类的 __mro__ 元组中获取到 object 类。在 Python 中,object 类是所有类的基类,我们可以通过它获取所有子类列表

__subclasses__() 是 Python 类的一个方法,它会返回该类的所有直接子类组成的列表

索引 40 对应的类通常是 _io.TextIOWrapper 类(在 Python 3 中)或者 file 类(在 Python 2 中),这个类可以用于文件的读写操作

调用 _io.TextIOWrapper 类的构造函数,传入要读取的文件路径,从而打开指定文件

.read():调用打开文件对象的 read 方法,读取文件的全部内容

payload以及注释摘自:3.攻防世界 Confusion1(服务器模板注入SSTI)-CSDN博客

request是Flask框架的一个全局对象,表示“当前请求的对象(flask.request)"

Flask框架

1.基本概念:Flask 是一个轻量级的 Python Web 框架,它只提供了 Web 应用的核心功能,如路由、请求处理、响应返回等。开发者可以根据项目需求自由选择和集成各种扩展,这种灵活性使得 Flask 既适合初学者学习 Web 开发,也适合开发小型到大型的各种 Web 项目。

2.主要特点:

  • 轻量级与简洁性:Flask 的核心代码简洁,易于理解和上手。它不强制使用特定的数据库、模板引擎或其他组件,开发者可以根据自己的喜好进行选择。例如,Flask 本身不自带数据库操作功能,但可以轻松集成 SQLAlchemy(用于关系型数据库)或 MongoEngine(用于 MongoDB)等数据库操作库。
  • 高度可扩展性:拥有丰富的扩展生态系统,涵盖了从用户认证、数据库操作到缓存管理等各个方面。例如,Flask-Login 可用于用户登录管理,Flask-SQLAlchemy 简化了数据库操作,Flask-Caching 可以实现缓存功能。
  • 灵活性:允许开发者自由组织项目结构,无论是小型的单文件应用,还是大型的模块化项目,Flask 都能很好地适应。开发者可以根据业务需求灵活设计路由、视图函数和模板结构。

三、小结

1.SSTI模板注入,以下流程很重要

逐步排查验证,然后构造payload

2.Jinja2模板和Twig模板区别在于,前者更多使用Python,后者更多使用php语言,可以从两种语言的不同进行区分两种模板

3.SSTI模板注入和前面做过的xss模板注入的沙箱逃逸,都用到了双花括号中加入计算式进行验证漏洞,以后也可以多使用,看是否能遇到相似题目

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

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

相关文章

【C语言标准库函数】标准输入输出函数详解[5]:格式化文件输入输出

目录 一、fprintf() 函数 1.1. 函数简介 1.2. fprintf使用场景 1.3. 注意事项 1.4. 示例 二、fscanf() 函数 2.1. 函数简介 2.2. fscanf使用场景 2.3. 注意事项 2.3. 示例 三、总结 在 C 语言中&#xff0c;格式化文件输入输出函数能够让我们以特定的格式对文件进行…

【详细版】DETR系列之Deformable DETR(2021 ICLR)

论文标题Deformable DETR: Deformable Transformers for End-to-End Object Detection论文作者Xizhou Zhu, Weijie Su, Lewei Lu, Bin Li, Xiaogang Wang, Jifeng Dai发表日期2021年03月01日GB引用> Xizhou Zhu, Weijie Su, Lewei Lu, et al. Deformable DETR: Deformable T…

c++----函数重载

目录标题 为什么会有函数重载函数重载的概念函数重载的例子第一个&#xff1a;参数的类型不同第二个&#xff1a;参数的个数不同第三种&#xff1a;类型的顺序不同函数重载的奇异性重载函数的底层原理有关函数重载的一个问题 为什么会有函数重载 大家在学c语言的时候有没有发现…

从云原生到 AI 原生,谈谈我经历的网关发展历程和趋势

作者&#xff1a;谢吉宝&#xff08;唐三&#xff09; 编者按&#xff1a; 云原生 API 网关系列教程即将推出&#xff0c;欢迎文末查看教程内容。本文整理自阿里云智能集团资深技术专家&#xff0c;云原生产品线中间件负责人谢吉宝&#xff08;唐三&#xff09; 在云栖大会的精…

多头自注意力中的多头作用及相关思考

文章目录 1. num_heads2. pytorch源码演算 1. num_heads 将矩阵的最后一维度进行按照num_heads的方式进行切割矩阵&#xff0c;具体表示如下&#xff1a; 2. pytorch源码演算 pytorch 代码 import torch import torch.nn as nn import torch.nn.functional as Ftorch.set…

常用的python库-安装与使用

常用的python库函数 yield关键字openslide库openslide库的安装-linuxopenslide的使用openslide对象的常用属性 cv2库numpy库ASAP库-multiresolutionimageinterface库ASAP库的安装ASAP库的使用 concurrent.futures.ThreadPoolExecutorxml.etree.ElementTree库skimage库PIL.Image…

对接DeepSeek

其实&#xff0c;整个对接过程很简单&#xff0c;就四步&#xff0c;获取key&#xff0c;找到接口文档&#xff0c;接口测试&#xff0c;代码对接。 获取 KEY https://platform.deepseek.com/transactions 直接付款就是了&#xff08;现在官网暂停充值2025年2月7日&#xff0…

ChatGPT提问技巧:行业热门应用提示词案例-文案写作

ChatGPT 作为强大的 AI 语言模型&#xff0c;已经成为文案写作的得力助手。但要让它写出真正符合你需求的文案&#xff0c;关键在于如何与它“沟通”&#xff0c;也就是如何设计提示词&#xff08;Prompt&#xff09;。以下是一些实用的提示词案例&#xff0c;帮助你解锁 ChatG…

分享如何通过Mq、Redis、XxlJob实现算法任务的异步解耦调度

一、背景 1.1 产品简介 基于大模型塔斯&#xff0c;整合传统的多项能力&#xff08;NLP、OCR、CV等&#xff09;&#xff0c;构建以场景为中心的新型智能文档平台。通过文档审阅&#xff0c;实现结构化、半结构化和非结构化文档的信息获取、处理及审核&#xff0c;同时基于大…

8.flask+websocket

http是短连接&#xff0c;无状态的。 websocket是长连接&#xff0c;有状态的。 flask中使用websocket from flask import Flask, request import asyncio import json import time import websockets from threading import Thread from urllib.parse import urlparse, pars…

【大模型实战】使用Ollama+Chatbox实现本地Deepseek R1模型搭建

下载安装Ollama Ollama官方链接:https://ollama.com/,打开链接后就可以看到大大的下载按钮,如下图: 我选择用Win的安装。将Ollama的安装包下载到本地,如果下载慢可以复制链接到迅雷里面,提高下载速度,如下图: 双击之后,就可以开始安装了,如下图: 默认安装到C盘,…

VMware 虚拟机 ubuntu 20.04 扩容工作硬盘

一、关闭虚拟机 关闭虚拟机参考下图&#xff0c;在vmware 调整磁盘容量 二、借助工具fdisk testubuntu ~ $ df -h Filesystem Size Used Avail Use% Mounted on udev 1.9G 0 1.9G 0% /dev tmpfs 388M 3.1M 385M 1% /run /dev/sda5 …

【漫话机器学习系列】082.岭回归(或脊回归)中的α值(alpha in ridge regression)

岭回归&#xff08;Ridge Regression&#xff09;中的 α 值 岭回归&#xff08;Ridge Regression&#xff09;是一种 带有 L2​ 正则化 的线性回归方法&#xff0c;用于处理多重共线性&#xff08;Multicollinearity&#xff09;问题&#xff0c;提高模型的泛化能力。其中&am…

9 Pydantic复杂数据结构的处理

在构建现代 Web 应用时&#xff0c;我们往往需要处理复杂的输入和输出数据结构。例如&#xff0c;响应数据可能包含嵌套字典、列表、元组&#xff0c;甚至是多个嵌套对象。Pydantic 是一个强大的数据验证和序列化库&#xff0c;可以帮助我们轻松地处理这些复杂的数据结构&#…

Day62_补20250210_图论part6_108冗余连接|109.冗余连接II

Day62_20250210_图论part6_108冗余连接|109.冗余连接II 108冗余连接 【把题意转化为并查集问题】 题目 有一个图&#xff0c;它是一棵树&#xff0c;他是拥有 n 个节点&#xff08;节点编号1到n&#xff09;和 n - 1 条边的连通无环无向图&#xff08;其实就是一个线形图&am…

kafka消费端之消费者协调器和组协调器

文章目录 概述回顾历史老版本获取消费者变更老版本存在的问题 消费者协调器和组协调器新版如何解决老版本问题再均衡过程**第一阶段CFIND COORDINATOR****第二阶段&#xff08;JOINGROUP&#xff09;**选举消费组的lcader选举分区分配策略 第三阶段&#xff08;SYNC GROUP&…

IDEA升级出现问题Failed to prepare an update Temp directory inside installation

IDEA升级出现问题"Failed to prepare an update Temp directory inside installation…" 问题来源&#xff1a; 之前修改了IDEA的默认配置文件路径&#xff0c;然后升级新版本时就无法升级&#xff0c;提示"Failed to prepare an update Temp directory insid…

十款开源的论坛建站工具

以下是十款开源的论坛建站工具&#xff0c;它们各具特色&#xff0c;能够满足不同用户的需求&#xff1a; Discuz!&#xff08;Crossday Discuz! Board&#xff09; 特点&#xff1a;基础架构采用web编程组合PHPMySQL&#xff0c;用户可以在不需要任何编程的基础上&#xff0c;…

vue学习6

1. 智慧商城 1. 路由设计配置 单个页面&#xff0c;独立展示的&#xff0c;是一级路由 2.二级路由配置 规则&组件配置导航链接配置路由出口 <template><div id"app"><!--二级路由出口--><router-view></router-view><van-…

线程池以及日志、线程总结

一、线程池以及日志 1、基础线程池写法 主线程在main函数中构建一个线程池&#xff0c;初始化(Init)后开始工作(Start) 此时线程池中每个线程都已经工作起来了&#xff0c;只是任务队列中任务为空&#xff0c;所有线程处于休眠状态(通过线程同步中的条件变量实现&#xff0c…