理论基础
-
序列化与反序列化
序列化和反序列化是指用于将对象或数据结构转换为字节流的过程,以便在不同系统之间进行传输或存储,并在需要时重新构造。
- 序列化是指将对象或数据结构转换为字节流的过程。在序列化过程中,对象的状态和数据被转换为一系列字节,这些字节可以按照一定的协议进行传输或存储。序列化通常用于将对象存储到磁盘或通过网络发送到其他系统。序列化后的字节流可以被保存下来,以后可以通过反序列化操作重新构建对象并恢复其状态和数据。
- 反序列化是指将序列化后的字节流转换回对象或数据结构的过程。在反序列化过程中,字节流被读取并解析,以还原为原始的对象或数据结构。反序列化通常用于从磁盘加载保存的对象或接收通过网络传输的序列化数据。通过反序列化,可以重新构建对象并恢复其之前序列化的状态和数据。
序列化和反序列化在许多领域都有广泛的应用,例如分布式系统、持久化存储、缓存机制以及跨平台通信。它们允许将复杂的对象或数据结构转换为字节流进行传输或存储,从而实现不同系统之间的数据交换和共享。
-
反序列化漏洞介绍
不安全的反序列化是指在反序列化过程中存在潜在安全风险的情况,如果序列化的内容可控,在传递给应用进行反序列化时,可能会导致执行恶意代码或触发其他不受控制的行为。
- 漏洞成因
- 不受限制的反序列化:如果反序列化操作没有适当的验证和限制,允许任意的序列化数据被反序列化,攻击者可以构造恶意的序列化数据来执行恶意代码。
- 未经过滤的输入:如果反序列化操作接受未经过滤的输入数据,攻击者可以通过构造特定的恶意数据来执行命令或导致不受控制的行为。
- 自定义的反序列化逻辑:如果使用自定义的反序列化逻辑而不是使用安全的序列化库或框架,可能会导致安全问题。自定义逻辑可能缺乏必要的安全验证和过滤步骤,从而容易受到攻击。
- 恶意的序列化数据:如果攻击者能够在反序列化操作中提供恶意构造的序列化数据,可能会导致命令执行或其他不受控制的行为。
- pickle反序列化漏洞
-
pickle反序列化的数据直接用于命令拼接,则会直接导致命令执行。
-
pickle中
__reduce__
魔法函数会在一个对象被反序列化时自动执行,我们可以通过在__reduce__
魔法函数内植入恶意代码的方式进行任意命令执行。通常会利用到Python的反弹shell。
-
- pickle反序列化相关函数
pickle.dump()
:将obj对象序列化为字节(bytes)写入到file文件中。pickle.load()
:从一个对象文件中读取序列化数据,将其反序列化之后返回一个对象。pickle.dumps()
:方法将obj对象序列化并返回一个bytes对象。pickle.loads()
:将bytes反序列化并返回一个对象。- pickle的更多使用:Python 对象序列化
- pickle前置知识之Python基础
-
pickle前置知识之Python魔术方法
Python魔术方法(Magic Methods)是一系列特殊命名的方法,其名称以双下划头和尾(例如
__init__
和__new__
)的形式出现,这些方法在类的特定事件被触发时自动执行,无需显式调用。这些方法允许程序员自定义类的行为,以创建更具表现力和功能的类实例。-
常用的魔术方法:
__init__(self):实例化对象之后立即触发。 __reduce__(self):在反序列化过程开始时被调用。 __new__(cls):它在__init__之前被调用,并必须返回一个对象实例。 __str__(self):定义对象转换为字符串时的行为,当使用str()函数或print()函数时自动调用。 __call__(self):将对象当作函数调用时触发。 __getattr__(self, name):获取不存在的对象属性时被触发 __setattr__(self, name, value):设置对象成员值的时候触发 __del__(self):当该类对象被销毁时,自动触发。
-
更多魔术方法:CSDN-Python魔术方法
-
-
pickle反序列化进阶之错误使用产生RCE
不安全的序列化数据直接进行命令拼接或执行,产生命令执行漏洞。此种类型漏洞利用难度低,只要正确拼接了命令,即可完成攻击。
- pickle反序列化进阶之reduce进行RCE
-
产生原因:Python 中的魔术方法
__reduce__()
在反序列化过程开始时被调用,所以我们可以序列化一个__reduce__
魔术方法中有系统命令的实例并且让服务器将它反序列化,从而达到任意命令执行的效果。 -
攻击案例:
import pickle import os class Rce(object): def __reduce__(self): return (os.system,('ipconfig',)) a = Rce() b = pickle.dumps(a) print(b) # b是反序列化数据 pickle.loads(b) # 执行该语句进行反序列化,自动执行 __reduce__ 方法,并且执行 os.system('ipconfig')
-
- 漏洞危害
- 远程代码执行:攻击者可以通过构造恶意序列化数据注入和执行任意代码,从而完全控制目标系统,并执行恶意操作。
- 远程命令执行:攻击者可以通过反序列化漏洞在目标系统上执行远程命令,从而对其他系统或网络资源造成进一步的威胁。
- 信息泄露:攻击者可以利用反序列化漏洞读取和获取目标系统中的敏感信息,例如数据库凭据、用户密码、加密密钥等。
- 拒绝服务(DoS)攻击:攻击者可以发送恶意序列化数据来触发异常或消耗过多的系统资源,导致系统崩溃或无法提供正常的服务。
- 修复建议
- 不要将不安全的反序列化数据应用在命令执行等高危操作中。
- 使用安全的序列化库或框架,这些库经过严格测试和审查,并提供了适当的安全防护机制。
- 对反序列化输入进行严格的验证和过滤,只接受预期的数据格式和内容。
- 不要从不受信任的来源接受序列化数据,尽量限制数据来源。
- 定期更新和修复序列化库和相关组件,以获取最新的安全修补程序。
- 配置系统和应用程序的安全设置,限制恶意代码执行的可能性。
实践学习
漏洞环境以Pilot靶场为例:下载地址与部署教程
-
进入漏洞页面,发现服务器进程监控每隔固定时间会刷新。
-
抓包拦截刷新请求,发现通过Base64编码进行了命令执行,但无法解码出命令:
-
根据格式判断,此处考虑解码后的数据经过Pickle序列化为字节类型,所以写脚本尝试验证:
import base64, pickle data = "gASVDwAAAAAAAACMC3RvcCAtYiAtbiAxlC4=" print(pickle.loads(base64.b64decode(data)))
-
成功反序列化出命令。重新写脚本,将需要执行的系统命令序列化并编码:
import pickle,base64 print(base64.b64encode(pickle.dumps("echo 'python pickle serialize'")))
-
将生成的字符串编码放入请求包重新执行,成功执行命令: