Flask模板注入梳理

模板开始介绍:

Flask中有许多不同功能的模板,他们之间是相互隔离的地带,可供引入和使用。

Flask中的模块

  1. flask 主模块:包含框架的核心类和函数,如 Flask(应用实例)、request(请求对象)、response(响应对象)、render_template(模板渲染)等。(很多函数其实属于下面各自的模块,但是会被 “导入” 到 Flask 主模块(flask)中,方便开发者直接从 flask 导入使用。)
  2. flask.config:处理应用配置(如密钥、数据库连接信息等)。
  3. flask.context:管理请求上下文(requestg)和应用上下文(current_appconfig)。
  4. flask.helpers:提供辅助函数,如 url_for(生成 URL)、flash(消息闪现)等。
  5. flask.blueprints:支持蓝图(Blueprint),用于拆分大型应用为模块化组件。
  6. flask.templating:模板渲染相关功能,依赖 Jinja2 模板引擎。
  7. flask.wrappers:定义请求(Request)和响应(Response)的封装类。

比如说我本地搭建的一个简单靶场:

from flask import Flask
from flask import request
from flask import render_template_stringapp = Flask(__name__)@app.route('/test', methods=['GET', 'POST'])
def test():template = '''<div class="center-content error"><h1>Oops! That page doesn't exist.</h1><h3>%s</h3></div> ''' % (request.url)return render_template_string(template)if __name__ == '__main__':app.debug = Trueapp.run()

就从flask中引入request、render_template_string函数。他们分别定义在什么模块以及有什么作用可以自行分析一下。

该靶场的漏洞在于render_template_string,将一个用户可控字符串当作模板内容渲染,就像是往eval()函数中放入用户可控参数一样。

但是要想利用这个漏洞,没有命令注入那么方便,因为Jinja2 模板引擎的安全隔离机制让我们无法直接引用python内置函数和其他模块中定义的函数。

在 Flask 中,Jinja2 模板默认可以访问一些框架预定义的全局变量,例如:

  • {{ config }}:Flask 应用的配置信息(如密钥、端口等)。
  • {{ request }}:当前请求对象(包含 URL、参数、请求方法等)。
  • {{ g }}:Flask 的全局临时变量(用于请求生命周期内共享数据)。
  • {{ session }}:当前会话对象(存储用户会话数据)。

其实在Jinja2模板中还应该有一些默认导入的python内置函数例如globals()、locals()、vars()等等但是为了安全性不暴露。

所以,我们需要讲到沙箱逃逸

通俗来说就是我们现在需要在jinja2模板引擎的安全隔离机制下调用其他模块的方法甚至是Python内置函数,以此达到各种渗透目的。

先说说怎么调用其他模块的方法吧。

{{''.__class__.__mro__[1].__subclasses__()}}

  1. ''
    空字符串,是 Python 中 str(字符串)类型的一个实例。

  2. .__class__
    Python 中所有对象都有 __class__ 属性,用于获取该对象所属的类。
    这里 ''.__class__ 会返回字符串的类 str(即 <class 'str'>)。

  3. .__mro__[1]

    • __mro__ 是类的属性,全称 “Method Resolution Order”(方法解析顺序),返回一个元组,包含类的继承链(从当前类到最顶层父类)。
    • 对于 str 类,其继承链是 (str, object)str 继承自 objectobject 是 Python 中所有类的基类)。
    • __mro__[1] 取元组的第二个元素(索引从 0 开始),即 object 类。
  4. .__subclasses__()
    object 类的 __subclasses__() 方法会返回所有直接或间接继承自 object 的子类列表(几乎包含 Python 中所有的类,因为所有类最终都继承自 object)。

也可以用{{''.__class__.__bases__[0].__subclasses__()}}代替,base仅返回上一级父类。

通过 object.__subclasses__() 获取的子类列表是全局的,涵盖 Python 内置类、已导入的第三方库类、当前项目中定义的类等所有已加载的 object 子类

这个估计几乎每个讲沙箱逃逸都会讲一遍原理,所以不过多赘述。通过这个方法呢,我们就可以调用全局的已有类中的方法。举几个例子:

1. 文件读写类:file 或 io.FileIO

  • 作用:读取 / 写入服务器文件(如敏感配置文件、密码文件等)。
  • 示例

        假设 file 类在子类列表中的索引为 40(不同环境索引可能不同):

        # 读取 /etc/passwd 文件

        {{''.__class__.__bases__[0].__subclasses__()[40]('/etc/passwd').read()}}

        若目标是 Windows 服务器,可读取 C:\Windows\system32\drivers\etc\hosts 等

2. 命令执行类:subprocess.Popen

  • 作用:执行系统命令(如 lswhoamiipconfig 等)。
  • 示例

        假设 subprocess.Popen 在子类列表中的索引为 258

        # 执行 ls 命令(Linux)并返回结果
{{''.__class__.__bases__[0].__subclasses__()[258]('ls', shell=True,         stdout=-1).communicate()[0].decode()}}

        # 执行 whoami 命令(查看当前用户权限)
{{''.__class__.__bases__[0].__subclasses__()[258]('whoami', shell=True,         stdout=-1).communicate()[0].decode()}}

        Windows 系统可替换为 diripconfig 等命令。

但是很多时候没有可利用的类,就需要进一步逃逸调用python内置函数。

就需要用到globals:

__globals__ 是 Python 函数的内置属性
在 Python 中,每个函数对象都有 __globals__ 属性,它返回该函数定义所在模块的全局变量字典。这个字典包含了模块中定义的所有变量、函数、类、导入的模块等。

这样的话我们就能利用某些jinja2模板中可以调用的”安全函数“,得到全局变量字典。可是得到全局变量字典,也只是得到本身模块中的东西呀,如果还是无法利用呢,怎么得到python内置函数呢?

这就需要用到builtins:

builtins 模块
这是 Python 解释器内置的核心模块,包含了所有 Python 内置函数(如 printleneval)、内置类型(如 intstrlist)和异常类(如 ExceptionTypeError)。我们在 Python 中直接使用的 print()str() 等,本质上都是 builtins 模块中的成员

那得到这个模块我们就能得到内置函数啦。怎么得到呢?

__globals__ 得到的字典中有一个关键的东西——导入的模块,我们知道不管是哪个模块,那都属于是python,所以python内置函数就像是基础设施,几乎不管哪个模块,都得利用内置函数实现其功能。因此几乎所有模块__globals__属性返回的字典中都有builtins模块。

那就出现了类似

url_for.__globals__['__builtins__']['eval']("__import__('os').popen('ls').read()")

这样的答案。

这里的url_for就是上面说到的可利用的”安全函数“,那万一没有呢?

我们就需要结合 ''.__class__.__mro__[1].__subclasses__() 方法啦:

有些类例如warnings.catch_warnings中一定有一个方法,那就是__init__,用来初始化对象。

而__init__也算是函数对象,那不就有__global__属性了!

因此,就出现了类似

''.__class__.__mro__[1].__subclasses__()[59].__init__.__globals__['__builtins__']['eval']("__import__('os').popen('ls').read()")

这样的答案。

写这篇文章主要为了梳理一遍Flask模板注入的原理,一定有一些理解错误或者不充分的地方。

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

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

相关文章

企业级的即时通讯平台怎么保护敏感行业通讯安全?

聊天记录存在第三方服务器、敏感文件被误发至外部群组、离职员工仍能查看历史消息.对于金融、医疗、政务等对数据安全高度敏感的行业而言&#xff0c;“沟通效率与”信息安全”的矛盾&#xff0c;从未像今天这样尖锐。企业即时通讯怎么保护敏感行业通讯安全&#xff1f;这个问题…

Java Spring框架最新版本及发展史详解(截至2025年8月)-优雅草卓伊凡

Java Spring框架最新版本及发展史详解&#xff08;截至2025年8月&#xff09;-优雅草卓伊凡引言今天有个新项目 客户问我为什么不用spring 4版本&#xff0c;卓伊凡我今天刚做完项目方案&#xff0c;我被客户这一句问了有点愣住&#xff0c;Java Spring框架最新版本及发展史详解…

Android实现Glide/Coil样式图/视频加载框架,Kotlin

Android实现Glide/Coil样式图/视频加载框架&#xff0c;Kotlin <uses-permission android:name"android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name"android.permission.READ_EXTERNAL_STORAGE" /><uses-permiss…

【k8s】pvc 配置的两种方式volumeClaimTemplates 和 PersistentVolumeClaim

pvc配置实例 实例1在Deployment中配置 template:xxxxxxvolumeClaimTemplates:- metadata:name: dataspec:accessModes:- ReadWriteOnceresources:requests:storage: 1GistorageClassName: nfsdev-storageclass (创建好的storageClassName)实例2#先创建一个pvc 然后在 Deploym…

Logistic Loss Function|逻辑回归代价函数

----------------------------------------------------------------------------------------------- 这是我在我的网站中截取的文章&#xff0c;有更多的文章欢迎来访问我自己的博客网站rn.berlinlian.cn&#xff0c;这里还有很多有关计算机的知识&#xff0c;欢迎进行留言或…

计算机网络技术-知识篇(Day.1)

一、网络概述 1、网络的概念 两个不在同一地理位置的主机&#xff0c;通过传输介质和通信协议&#xff0c;实现通信和资源共享。 2、网络发展史 第一阶段&#xff08;20世纪60年代&#xff09; 标志性事件&#xff1a;ARPANET的诞生关键技术&#xff1a;分组交换技术 第二…

工业元宇宙:迈向星辰大海的“玄奘之路”

一、从认知革命到工业革命&#xff1a;文明跃迁的底层逻辑1.1 认知革命&#xff1a;人类协作的基石时间线&#xff1a;约7万年前&#xff0c;智人通过语言和想象力构建共同虚拟现实&#xff0c;形成部落协作模式。核心突破&#xff1a;虚构能力&#xff1a;创造神、国家、法律等…

9. React组件生命周期

2. React组件生命周期 2.1. 认识生命周期 2.1.1. 很多事物都有从创建到销毁的整个过程&#xff0c;这个过程称之为生命周期&#xff1b;2.1.2. React组件也有自己的生命周期&#xff0c;了解生命周期可以让我们在最合适的地方完成想要的功能2.1.3. 生命周期和生命周期函数的关系…

【单板硬件开发】关于复位电路的理解

阅读紫光同创供应商提供的FPGA单板硬件开发手册&#xff0c;发现复位电路他们家解释的很通俗易懂&#xff0c;所以分享一下。如下图&#xff0c;RST_N 是低有效的异步全芯片复位信号&#xff0c;一般外部连接电路有 3 种形式如图 3–2&#xff0c;可根据实际需要选择合适的电路…

《Unity Shader入门精要》学习笔记一

1、本书的源代码 https://github.com/candycat1992/Unity_Shaders_Book 2、第1章 Shader是面向GPU的工作方式 3、第2章 渲染流水线 Shader&#xff1a;着色器 渲染流水线&#xff1a;目标是渲染一张二维纹理&#xff0c;输入是一个虚拟摄像机、一些光源、一些Shader以及纹…

从零到一:TCP 回声服务器与客户端的完整实现与原理详解

目录 一、TCP 通信的核心逻辑 二、TCP 服务器编程步骤 步骤 1&#xff1a;创建监听 Socket 步骤 2&#xff1a;绑定地址与端口&#xff08;bind&#xff09; 步骤 3&#xff1a;设置监听状态&#xff08;listen&#xff09; 步骤 4&#xff1a;接收客户端连接&#xff08…

MyBatis-Plus核心内容

MyBatis-Plus MyBatis-Plus 是一个基于 MyBatis的增强工具&#xff0c;旨在简化开发过程&#xff0c;减少重复代码。它在MyBatis的基础上增加了CRUD操作封装&#xff0c;条件构造器、代码生成器等功能。 一、核心特性与优势 1. 核心特性 无侵入&#xff1a;只做增强不做改变&am…

计算机网络摘星题库800题笔记 第4章 网络层

第4章 网络层4.1 网络层概述题组闯关1.在 Windows 的网络配置中&#xff0c;“默认网关” 一般被设置为 ( ) 的地址。 A. DNS 服务器 B. Web 服务器 C. 路由器 D. 交换机1.【参考答案】C 【解析】只有在计算机上正确安装网卡驱动程序和网络协议&#xff0c;并正确设置 IP 地址信…

非root用户在linux中配置zsh(已解决ncurses-devel报错)

Zsh&#xff08;Z Shell&#xff09;是一款功能强大的交互式 Unix shell&#xff0c;以其高度可定制性和丰富的功能著称&#xff0c;被视为 Bash 的增强替代品。它支持智能补全、主题美化、插件扩展&#xff08;如 Oh My Zsh 框架&#xff09;、自动纠错、全局别名等特性&#…

《Foundations and Recent Trends in Multimodal Mobile Agents: A Survey》论文精读笔记

论文链接&#xff1a;https://arxiv.org/pdf/2411.02006 摘要 文章首先介绍了核心组件&#xff0c;并探讨了移动基准和交互环境中的关键代表性作品&#xff0c;旨在全面理解研究重点及其局限性。 接着&#xff0c;将这些进展分为两种主要方法&#xff1a; 基于提示的方法&a…

npm安装时一直卡住的解决方法

npm install 卡住通常是由于网络问题或缓存问题导致的。以下是几种解决方法&#xff1a; 方法1&#xff1a;清理npm缓存 npm cache clean --force npm install方法2&#xff1a;删除node_modules和package-lock.json重新安装 rm -rf node_modules package-lock.json npm instal…

[密码学实战]使用Java生成国密SM2加密证书等(四十三)

[密码学实战]使用Java生成国密SM2加密证书等(四十三) 本文将详细介绍如何通过Java代码生成符合国密标准的SM2加密证书,包括密钥对生成、证书扩展属性配置、PEM格式保存等关键步骤。 一. 运行结果示例 二. 国密算法与加密证书 国密算法(SM系列)是中国自主研发的密码算法体…

从零开始之stm32之CAN通信

从小白的视角了解并实现简单的STM32F103的CAN通信&#xff0c;直接上手。一、CAN协议简介CAN总线上传输的信息称为报文&#xff0c;当总线空闲时任何连接的单元都可以开始发送新的报文&#xff0c;有5种类型的帧&#xff1a;数据帧、遥控帧、错误帧、过载帧、帧间隔。数据帧有两…

Java 课程,每天解读一个简单Java之利用条件运算符的嵌套来完成此题:学习成绩>=90分的同学用A表示,60-89分之间的用B表示, * 60分以下

package ytr250812;/*题目&#xff1a;利用条件运算符的嵌套来完成此题&#xff1a;学习成绩>90分的同学用A表示&#xff0c;60-89分之间的用B表示&#xff0c;* 60分以下*/import java.util.Scanner;public class GradeEvaluator {public static void main(String[] args) …

Word XML 批注范围克隆处理器

该类用于处理 Word 文档&#xff08;XML 结构&#xff09;中被批注标记的文本范围&#xff0c; 实现指定内容的深度克隆&#xff0c;并将其插入到目标节点之后。 适用于在生成或修改 .docx 文件时复制批注内容块。/*** Word XML 批注范围克隆处理器* * 该类用于处理 Word 文档&…