不安全的反序列化
翻译
原文:https://portswigger.net/web-security/deserialization
- name: 翻译
desc: 原文:https://portswigger.net/web-security/deserialization
bgColor: '#F0DFB1'
textColor: 'green'
2
3
4
反序列化以难以理解而闻名,但它可能比你想象的要容易得多。我们将逐步指导你完成整个过程,以便你可以发现一些高严重性漏洞,即使是经验丰富的测试人员也可能完全错过这些漏洞。
访问官方链接 (opens new window)学习不安全的反序列化。
# 0不安全的反序列化
在本节中,我们将介绍什么是不安全的反序列化,并描述它如何可能使网站遭受高严重性攻击。我们将重点介绍典型场景,并使用 PHP、Ruby 和 Java 反序列化的具体示例演示一些广泛适用的技术。我们还将研究一些方法,可以防止你自己的网站中出现不安全的反序列化漏洞。
实验室
如果你已经熟悉反序列化漏洞背后的基本概念,并且只想在一些实际的、易受攻击的目标上练习和利用它们,那么你可以从下面的链接访问本主题中的所有实验室。
# 1什么是序列化?
序列化是将复杂的数据结构(如对象及其字段)转换为 “更扁平” 格式的过程,该格式可以作为顺序字节流发送和接收。序列化数据使以下操作变得更加简单:
- 将复杂数据写入进程间内存、文件或数据库
- 例如,通过网络、在应用程序的不同组件之间或在 API 调用中发送复杂数据
至关重要的是,在序列化对象时,其状态也会持久化。换言之,对象的属性及其对应的值都将得到保留。
# 1.1序列化 vs 反序列化
反序列化是将此字节流 还原到原始对象的全功能副本的过程,其状态与序列化时的状态完全相同。然后,网站的逻辑可以与这个反序列化对象进行交互,就像它与任何其他对象一样。
许多编程语言都提供了对序列化的本地支持。对象序列化的确切方式取决于语言。一些语言将对象序列化为二进制格式,而另一些语言则使用不同的字符串格式,具有不同程度的人类可读性。请注意,原始对象的所有属性都存储在序列化数据流中,包括任何私有字段。若要防止字段被序列化,必须在类声明中将其显式标记为 “transient”。
(((译者加:Java中的transient关键字 (opens new window))))
请注意,当使用不同的编程语言时,序列化可能被称为封送(Ruby)或 pickling (Python)。在这种情况下,这些术语是 “序列化” 的同义词。
# 2什么是不安全的反序列化?
不安全的反序列化是指 用户可控制的数据被网站反序列化。这可能使攻击者能够操纵序列化对象,以便将有害数据传递到应用程序代码中。
甚至可以将 序列化对象 替换为完全不同类的对象。令人震惊的是,不管预期的是哪个类,只要是网站可用的任何类的对象,都将被反序列化和实例化。因此,不安全的反序列化有时也被称为 “对象注入” 漏洞。
意外类的对象可能会导致异常。然而,到这个时候,损害可能已经造成。许多基于反序列化的攻击,在反序列化结束之前就已经完成攻击。这意味着反序列化过程本身也可以用于发起攻击,即使网站自身的功能 不会直接与恶意对象交互。因此,一些基于强类型语言逻辑的网站,也可能容易受到这些技术的攻击。
# 3不安全的反序列化漏洞是如何产生的?
会出现不安全的反序列化,通常是因为人们普遍缺乏 对用户可控数据进行反序列化 的危险性的理解。理想情况下,用户输入永远不应该被反序列化。
然而,有时网站所有者认为它们是安全的,因为它们对反序列化数据实施了某种形式的附加检查。这种方法通常是无效的,因为 实现验证或清理 不可能考虑到每一种突发情况。这些检查也存在根本性的缺陷,因为它们依赖于 在反序列化后 检查数据,这在许多情况下为时已晚,无法阻止攻击。
由于反序列化对象通常被认为是可信的,因此也可能出现漏洞。特别是在使用具有二进制序列化格式的语言时,开发人员可能会认为用户无法有效地读取或操作数据。但是,虽然可能需要更多的努力,但攻击者利用二进制序列化对象的可能性 与 利用基于字符串格式的可能性一样大。
由于现代网站中存在的依赖项数量众多,基于反序列化的攻击也成为可能。一个典型的站点可能会实现许多不同的库,每个库都有自己的依赖项。这造就了一个难以安全管理的大量类和方法池。由于攻击者可以创建这些类中的任何一个实例,因此很难预测恶意数据可以调用哪些方法。如果攻击者能够将一长串意外的方法调用链接在一起,将数据传递到与初始源完全无关的接收器中,则尤其如此。因此,几乎不可能预测恶意数据的流动并堵塞每一个潜在的漏洞。
简而言之,不可信的输入不可能被安全地反序列化。
# 4不安全的反序列化有什么影响?
不安全的反序列化的影响可能非常严重,因为它为大量增加的攻击面提供了入口点。它允许攻击者以有害的方式重用现有应用程序代码,从而导致许多其他漏洞,这通常是远程代码执行。
即使是在无法远程代码执行的情况下,不安全的反序列化也可能导致权限提升、任意文件访问和拒绝服务攻击。
# 5如何利用不安全的反序列化漏洞
现在,你已经熟悉了序列化和反序列化的基础知识,我们可以看看如何利用不安全的反序列化漏洞。
# 6如何防范不安全的反序列化漏洞
一般来说,除非绝对必要,否则应避免对用户输入进行反序列化。在许多情况下,它可能引发高严重性的漏洞利用,而且防范这些漏洞的难度超过了反序列化带来的好处。
如果确实需要对 来自不受信任源的数据 进行反序列化,请采用可靠的措施来确保数据未被篡改。例如,你可以实现数字签名来检查数据的完整性。但是,请记住,任何检查都必须在开始反序列化过程之前进行。否则,它们几乎没有用处。
如果可能的话,你应该完全避免使用 泛型反序列化 功能。来自这些方法的序列化数据 包含原始对象的所有属性,包括可能具有敏感信息的私有字段。相反,你可以针对特定的类,创建自己的序列化方法,这样至少可以控制公开哪些字段。
最后请记住,该漏洞是 “对用户输入的反序列化” 而产生,而不是由于随后处理数据的小工具链的存在。不要试图消除你在测试期间发现的小工具链,尝试将它们全部堵塞是不切实际的。几乎可以肯定地存在于您的网站上。在任何给定的时间,公开记录的内存破坏漏洞也是一个因素,这意味着你的应用程序无论如何都可能容易受到攻击。