Kısa cevap: PHP2Shell, saldırganın oturum açmadan web sunucusunda kod çalıştırmasına izin veren iki kritik PHP güvenlik açığının (CVE-2026-109618 ve CVE-2026-109619) ortak adıdır. PHP 5.4 ve sonrası etkilenir. PHP’yi 8.2.35, 8.3.36, 8.4.27 veya 8.5.12’ye yükseltin, tüm PHP süreçlerini yeniden başlatın, ardından sunucuya yamadan önce girilip girilmediğini kontrol edin.

21 Ekim 2026’da PHP ekibi acil durum sürümleri yayımladı. Sorun WordPress’te, Laravel’de ya da bir eklentide değil, doğrudan PHP motorunun içinde. Bu fark çok önemli: Siteniz güncel olabilir, yönetim paneliniz iki adımlı doğrulamayla korunuyor olabilir, yine de sunucu ele geçirilebilir. Çünkü açıklı kod, PHP isteği okurken, yani uygulamanız daha devreye girmeden çalışıyor. Üstelik ayrıntılar yamadan bir gün önce sızdı, ilk saldırı girişimleri ise ondan da dört gün önce görüldü. Bu yazıda iki açığın tam olarak ne yaptığını, hangi sürümlerin sorunu çözdüğünü, sunucularınızı nasıl doğru kontrol edeceğinizi, bugün güncelleme yapamıyorsanız ne yapabileceğinizi ve birinin sizden önce içeri girip girmediğini nasıl anlayacağınızı anlatıyoruz. Kendi sunucularımızı yamanın yayımlandığı günün ertesi sabahı güncelledik; aşağıdaki kontrol listesi bizzat kullandığımız liste.

PHP2Shell güvenlik açığı nedir?

PHP2Shell, Calif’teki araştırmacıların PHP yorumlayıcısındaki iki ayrı bellek güvenliği hatası üzerine kurduğu saldırı zincirine verdiği isim. İki açığın CVSS v4 puanı da 9.2. İkisi de düz bir HTTP isteğiyle, kimlik doğrulaması olmadan tetiklenebiliyor ve web sunucusu kullanıcısının yetkileriyle uzaktan kod çalıştırmaya varıyor. PHP güvenlik ekibi bunları GitHub’da iki ayrı bülten olarak yayımladı: GHSA-w8hw-w9fx-j79w (CVE-2026-109618) ve GHSA-6wmf-4rv5-p3rp (CVE-2026-109619).

Sorunlu kod, 2012’de çıkan PHP 5.4.0’a kadar uzanıyor. Etkilenen sunucu sayısının bu kadar büyük olmasının nedeni de bu: Sunucu tarafı dili bilinen her on siteden yaklaşık yedisi PHP kullanıyor ve neredeyse hepsi form gönderimlerini ve dosya yüklemelerini tam da bu kod üzerinden işliyor.

CVE-2026-109618: İstek yarıdayken bellek bitiyor

PHP memory_limit sınırına ulaştığında işi düzgünce toparlamaz, o an ne yapıyorsa oradan doğrudan çıkar. Bu, PHP istek verisini hazırlarken olursa, örneğin bir form alanını $_POST dizisine eklerken, dizinin iç sayacı anahtarı ve değeri henüz yazılmamış bir elemanı çoktan saymış olur. İstek bittiğinde PHP $_POST’u temizlerken sayılan her elemanı dolaşır ve yarım kalanı da geçerliymiş gibi işler. Bellek düzeni dikkatle hazırlanırsa, saldırgan bu yarım elemanın neyi göstereceğini kontrol edebilir.

Bültende post_max_size sınırının altında kalarak PHP’nin belleğini tüketmenin birkaç yolu sayılıyor: Kullanılabilir bir Content-Length bilgisi taşımayan multipart istekler, binlerce başlık içeren multipart parçaları ve max_file_uploads sınırına takılmadan her biri ayrı bir dizi oluşturan, iç içe isimli boş dosya alanları. Saldırı, varsayılan bellek ve girdi ayarlarıyla çalışan Apache mod_php üzerinde gösterildi. PHP-FPM, FrankenPHP ve LiteSpeed de kaynak kod incelemesine göre risk altında; yayın anında FPM için tam bir istismar gösterilmemiş olsa bile.

CVE-2026-109619: Bir istek, sonrakini zehirliyor

PHP süreçleri tekrar tekrar kullanılır. Tek bir php-fpm alt süreci ya da Apache süreci arka arkaya pek çok isteğe hizmet eder ve motorun her istek arasında kendi durumunu sıfırlaması gerekir. İkinci açık, hata, oturum ve serileştirme gibi bazı durum bilgilerinin, arkasındaki bellek serbest bırakıldıktan sonra da yaşamaya devam edebilmesi. Zaman aşımı veya bellek tükenmesi gibi bir fatal error temizliği atlatabiliyor, kapanış sırasında üretilen bir uyarı da temizlenmiş durumu sessizce yeniden oluşturabiliyor. Aynı süreçteki sonraki istek bu bilgiyi sıfırlanmadan okuduğunda PHP, serbest bırakılmış belleği gösteren bir işaretçiyi izliyor.

Bu açığı tetikleyen iki yol doğrulandı. Birincisi varsayılan olarak açık gelen session upload progress özelliği; kodunuz hiç session_start() çağırmasa bile her multipart yüklemede çalışıyor. İkincisi yalnızca PHP 8.5’te bulunan ve yine varsayılan olarak açık olan fatal_error_backtraces. PHP, mod_php üzerinde ve oturum yolu için PHP-FPM üzerinde komut çalıştırmayı doğruladı.

Giriş ekranı, WAF ve güncel eklentiler neden korumuyor?

İki açık da PHP isteği ayrıştırırken ya da kapatırken, yani uygulamanız çalışmadan önce ve çalıştıktan sonra tetikleniyor. Giriş formu, güvenlik eklentisi ya da CMS güncellemesi isteği zamanında göremiyor. Sansec; WordPress, Drupal, Joomla, Magento, Nextcloud, phpMyAdmin, Laravel ve Symfony uygulamalarının güncel sürümlerinde oturum açmadan kod çalıştırmayı doğruladığını bildiriyor. Bu aslında form kabul eden PHP yazılımlarının listesi. WAF biraz işe yarar; Cloudflare ücretsiz plan dahil bu saldırılar için kural yayımladı. Ama çok büyük istek gövdeleri, birçok WAF’ın kestiği ya da incelemeyi bıraktığı türden istekler. WAF’ı bir hız kesici olarak görün, çözüm olarak değil.

PHP2Shell zaman çizelgesi: Saldırılar yamadan önce başladı

Olayların sırası neden acele etmek gerektiğini açıklıyor. Calif, Ağustos 2026’nın başında birden fazla kod çalıştırma yolu buldu ve ilkini 11 Ağustos’ta PHP’ye bildirdi. Wiz Research da açıkları birbirinden bağımsız olarak 24 Ağustos’ta bildirdi. Koordineli yayın 22 Ekim’e planlanmıştı; ancak CVE numaraları ve bazı ayrıntılar 20 Ekim’de sızınca yayın 21 Ekim saat 14:00 UTC’ye (Türkiye saatiyle 17:00) çekildi.

Asıl rahatsız edici kısım bundan önce yaşananlar. Amazon’un tehdit istihbarat ekibi, tuzak sunucularında ilk istismar girişimini 17 Ekim’de, yani ortada henüz hiçbir yamalı sürüm yokken gördü ve incelemelere bu tarihten başlanmasını öneriyor. Cloudflare, yamadan altı saatten fazla önce, 21 Ekim 07:43 UTC’den itibaren saldırılar gördüğünü açıkladı. Yayın gününün akşamında Datadog ve Tenable geniş çaplı, hedef gözetmeyen taramalar raporluyordu.

1 Ağustos ile 21 Ekim 2026 arasındaki PHP2Shell zaman çizelgesi. Calif 1 Ağustos’ta uzaktan kod çalıştırma yollarını buluyor ve 11 Ağustos’ta PHP’ye bildiriyor; Wiz de 24 Ağustos’ta bildiriyor. İşaretli risk penceresi, AWS tuzak sunucularında 17 Ekim’de görülen ilk saldırı girişimiyle başlıyor, 20 Ekim’deki sızıntıyla devam ediyor ve 21 Ekim 14:00 UTC’deki yamalı PHP sürümleriyle bitiyor.
İstismar girişimleri 17 Ekim’de, yani yamalı sürümden dört gün önce başladı. Yayın günü yamalanan bir sunucu bile bu süre boyunca açıkta kalmış olabilir.

Kısacası, sunucunuz etkilenen bir PHP sürümüyle 17 Ekim’den sonra internete açıksa, yama kapıyı kapatır ama içeri biri girip girmediğini söylemez. Bu konuya ele geçirilme kontrolü bölümünde döneceğiz.

CVE-2026-109618 yaması hangi PHP sürümünde?

İki açık da aynı dört sürümde kapatıldı. Kullandığınız sürüm hâlâ destekleniyorsa yapmanız gereken bir taşıma değil, küçük bir güncelleme:

PHP sürümüEkim 2026 itibarıyla durumYamalı sürümNe yapmalı
8.5Aktif destek8.5.12Güncelleyin. Güncelleyene kadar fatal_error_backtraces ayarını kapatın.
8.4Aktif destek8.4.27Güncelleyin. Eski sitelerinizi taşıyacağınız sürüm bu olmalı.
8.3Yalnızca güvenlik yamaları8.3.36Güncelleyin.
8.2Yalnızca güvenlik yamaları, 31 Aralık 2026’da bitiyor8.2.35Hemen güncelleyin ve 8.4’e geçişi planlayın.
7.4 – 8.1Desteği bittiResmi sürüm yokPHP’nin kaynak kod yamasını ya da sağlayıcı paketini uygulayın, sonra yükseltin.
5.4 – 7.3Desteği bittiYama yokYükseltin. Başka çıkış yolu yok.

Destek tarihleri PHP’nin resmi desteklenen sürümler sayfasından alındı. Her sürüm dalında yamalı sürümden önceki tüm sürümler açıklı; yani 8.4.26 açıklı, 8.4.27 değil.

PHP sürüm dalları ve PHP2Shell’i düzelten sürümleri gösteren tablo. PHP 8.5 için 8.5.12, 8.4 için 8.4.27, 8.3 için 8.3.36, 8.2 için 8.2.35; 8.2’den 2027 öncesinde çıkılması notuyla. PHP 7.4 ile 8.1 arasının desteği bitmiş, resmi sürüm yok, kaynak kod yaması veya dağıtım paketi gerekiyor; 5.4 ile 7.3 arası yükseltilmeli; 5.4 öncesi açıktan eski ama on yılı aşkın süredir desteksiz. Alt notta dağıtım paketlerinin yamayı eski sürüm numarasıyla getirebileceği belirtiliyor.
Her PHP dalı için yamalı sürüm. Bunu yalnızca komut satırındaki sürümle değil, web trafiğini karşılayan sürümle karşılaştırın.

Dağıtım paketleri eski numarayla yamalı olabilir

Ubuntu, Debian, Red Hat gibi dağıtımlar güvenlik yamalarını çoğu zaman kendi paketledikleri sürüme geriye taşır. Bu yüzden tamamen yamalı bir makinede php -v hâlâ 8.1.2 ya da 8.2.7 diyebilir. Bunu sürümün sonundaki ekten anlarsınız: 8.1.2-1ubuntu2.20 veya 8.2.7-1~deb12u1 gibi. Bu paketlerde sürüm numarası tek başına hiçbir şey kanıtlamaz. Bunun yerine paketin değişiklik kaydında CVE numarasını arayın:

# Debian / Ubuntu
apt changelog php8.2-fpm | grep -E 'CVE-2026-10961(8|9)'

# RHEL, AlmaLinux, Rocky, Fedora
rpm -q --changelog php-fpm | grep -E 'CVE-2026-10961(8|9)'

Sonuç çıkmıyorsa kurulu paket henüz yamayı içermiyor demektir. Yayın gününden bir uyarı: RHEL dünyasında çok kullanılan Remi deposu 21 Ekim’de güncel paketleri henüz yayımlamamıştı; birçok araştırmacı o zamana kadar dağıtımın kendi paketlerine ya da kaynak koddan derlemeye geçmeyi önerdi.

PHP 8.1 ve öncesini kullananlar

PHP güvenlik ekibi alışılmadık bir adım atıp 7.4, 8.0 ve 8.1 için kaynak kod yamaları yayımladı. Yani PHP’yi kendisi derleyen bir ekip desteği bitmiş sürümünü de yamalayabilir. Site sahiplerinin çoğu bunu yapmaz; onlar için gerçekçi seçenekler uzatılmış destek satan bir sağlayıcı, kendi yamalı paketlerini dağıtan bir hosting paneli ya da yükseltme. 5.4 ile 7.3 arasındaki her sürüm açıklı ve hiçbir yaması yok. 2026’nın sonunda hâlâ PHP 7 ile çalışan bir site zaten yıllardır bilinen, yamasız açıklar taşıyor; PHP2Shell yükseltmeyi ertelemeyi imkânsız hale getiren açık oldu.

Sitem PHP2Shell açığından etkileniyor mu? Nasıl kontrol edilir?

Kontrol tek bir komutmuş gibi görünse de en sık gördüğümüz hata yanlış PHP’ye bakmak. Bir sunucuda üç dört farklı PHP kurulu olabilir ve SSH’ta karşınıza çıkan, çoğu zaman web sayfalarını sunan PHP değildir. Şu dört adımı sırayla izleyin.

1. adım: PHP’nin çalıştığı her yeri listeleyin

İnternetten erişilen herhangi bir şey için PHP çalıştıran her sunucuyu, sanal makineyi, container imajını ve hosting hesabını not edin. Yıllar önce açılmış kampanya sitesini, herkese açık IP’si olan test sunucusunu, phpMyAdmin’i ve izleme panelini unutmayın. Kendi PHP’sini içinde getiren yazılımlar da bu listeye dahil: Docker imajları, kurulum paketleri ve PHP tabanlı yönetim paneli olan cihaz yazılımları.

2. adım: Web trafiğini gerçekten karşılayan sürüme bakın

php -v size komut satırındaki PHP’yi söyler. Siteniz bambaşka bir sürümle çalışıyor olabilir. Web tarafını doğrudan kontrol edin:

  • cPanel ve Plesk: Türkiye’deki paylaşımlı hostinglerin çoğu bu panellerle çalışır. cPanel’de MultiPHP Manager’da, Plesk’te alan adının PHP Ayarları sayfasında her sitenin sürümüne ayrı ayrı bakın; aynı hesaptaki iki site farklı PHP ile çalışıyor olabilir.
  • PHP-FPM (nginx veya FPM’li Apache): FPM’in kendisini çalıştırın, örneğin php-fpm8.3 -v ya da /usr/sbin/php-fpm -v. Çalışan havuzları ps aux | grep php-fpm ile listeleyin; farklı havuzlar farklı sürümle çalışabilir.
  • Apache mod_php: apache2ctl -M | grep php hangi modülün yüklü olduğunu gösterir. Önemli olan modülün sürümü; PHP de en yüksek riski bu yapılandırmaya veriyor.
  • Windows ve IIS: PHP, FastCGI üzerinden php-cgi.exe olarak çalışır. IIS Yöneticisi’ndeki FastCGI Ayarları’nda yazan yoldaki dosyayı çalıştırın, örneğin C:\PHP\php-cgi.exe -v.
  • Docker: Çalışan container’da docker exec <container> php -v komutunu çalıştırın, ardından Dockerfile’daki temel imaj etiketine bakın; bir sonraki deploy o imajdan yeniden derlenir.

Siteyi hangi PHP’nin sunduğundan emin değilseniz yalnızca sürümü yazdıran geçici bir dosya koyun, adresini açın ve hemen silin. Tam bir phpinfo() sayfasını asla açık bırakmayın; saldırgana tam sürümünüzü, yüklü modülleri ve dosya yollarını verir.

<?php // surum.php: kullandıktan hemen sonra silin
echo PHP_VERSION, ' ', PHP_SAPI;

3. adım: Dışarıdan kontrol edin

Sonra sitenize bir tarayıcı botun gözüyle bakın. Birçok sunucu PHP sürümünü X-Powered-By başlığında ilan eder ve böyle bir açık duyurulduktan sonra otomatik saldırılar hedeflerini tam olarak bu başlıktan seçer. Ücretsiz Web Sitesi Güvenlik Kontrolü aracımız bu başlığı, Server başlığını ve açıkta kalmış bir phpinfo sayfası varsa onu okur; bulduğu sürümü yamalı sürümlerle karşılaştırır ve sitenin açıklı mı, yamalı mı göründüğünü ya da sürümünü gizleyip gizlemediğini söyler. Aynı taramada HTTPS, güvenlik başlıkları, açıkta kalan .env ve Git dosyaları, çerez ayarları gibi genel kontrolleri de yapar.

Dışarıdan yapılan bir kontrolün neyi kanıtlayıp neyi kanıtlayamayacağını bilin. Sürüm görünüyorsa ve eskiyse sorununuz var. Sürüm gizliyse, ki doğru olan budur, dışarıdan kimse sunucunun yamalı olduğunu kanıtlayamaz; 2. adım yine şart. Sitede hiç PHP izi görünmüyorsa bile aynı alan adındaki başka servisler PHP kullanıyor olabilir.

4. adım: Hosting firmanıza doğru soruyu sorun

Paylaşımlı ya da yönetilen hostingde yukarıdaki komutların hiçbirini çalıştıramayabilirsiniz. Firmaya “Güvende miyim?” diye sormayın; cevabı doğrulanabilir sorular sorun: Alan adımı hangi PHP sürümü sunuyor, bu sürüm CVE-2026-109618 ve CVE-2026-109619 yamalarını içeriyor mu, güncellemeden sonra PHP süreçleri ne zaman yeniden başlatıldı? İyi bir hosting firması üç soruyu da bir gün içinde cevaplar.

PHP2Shell nasıl kapatılır: Güncelleme ve yeniden başlatma

PHP bültenleri bu konuda alışılmadık derecede net: Yamayı içeren bir sürüme geçmek tek tam çözüm. Bir sonraki bölümdeki her şey yalnızca bilinen yolları daraltır. Aşağıdaki sıralama, adımların kendisi kadar önemli.

PHP2Shell’i altı adımda kapatma şeması. Bir, PHP çalıştıran her sunucu, container ve hosting hesabını listeleyin. İki, gerçek sürümü bulun: php -v komut satırıdır, php-fpm, mod_php veya IIS FastCGI’a da bakın. Üç, 8.2.35, 8.3.36, 8.4.27 veya 8.5.12’yi ya da yamalı dağıtım paketini kurun. Dört, php-fpm, Apache, IIS havuzları dahil tüm süreçleri yeniden başlatın ve container’ları yeniden derleyin. Beş, sunucudaki sürümü ve ardından dışarıdan tarama ile doğrulayın. Altı, 17 Ekim’den beri loglarda, yeni dosyalarda ve shell açan web süreçlerinde iz arayın. Alt panel bugün güncelleyemeyenler için geçici önlemleri listeliyor.
Sırasıyla tam çözüm. En sık atlanan adımlar 4 ve 6.

Yamalı sürümü kurmak

  • Ubuntu ve Debian: sudo apt update && sudo apt install --only-upgrade 'php8.*', ardından yukarıdaki değişiklik kaydı kontrolünü yapın.
  • RHEL ailesi (AlmaLinux, Rocky): Dağıtımın kendi deposundan ya da AppStream modülünden sudo dnf upgrade 'php*'.
  • cPanel ve Plesk: EasyApache veya Plesk PHP paketlerini güncelleyin. Paylaşımlı hostingdeyseniz bunu firmanın yaptığını yazılı olarak teyit edin.
  • Windows ve IIS: windows.php.net’ten yeni sürümü indirip ayrı bir klasöre açın, php.ini dosyanızı kopyalayın, FastCGI uygulamasını ve işleyici eşlemesini yeni php-cgi.exe’ye çevirin.
  • Docker: Temel imajı yamalı sürüme çıkacak şekilde güncelleyin, yeniden derleyin ve o imajı kullanan her servisi yeniden dağıtın. Çalışan container’a elle yapılan yama bir sonraki deploy’da kaybolur.

Bütün PHP süreçlerini yeniden başlatın

“Güncelleme başarılı” mesajından sonra sunucuyu açıkta bırakan adım budur. Çalışan süreçler, yerlerine yenisi gelene kadar eski motoru bellekte tutar. Kurulu her PHP sürümü için php-fpm’i yeniden başlatın (systemctl restart php8.3-fpm), mod_php kullanıyorsa Apache’yi yeniden başlatın, IIS uygulama havuzlarını ya da FastCGI sürecini geri dönüştürün, her container’ı yenileyin. Ardından kontrol bölümündeki 2. ve 3. adımları tekrarlayıp trafiği karşılayan sürümün gerçekten yenisi olduğunu kanıtlayın.

seomods.com’u nasıl yamaladık?

SeoMods, Windows Server üzerinde IIS ile çalışıyor; yani PHP burada FastCGI altında php-cgi.exe olarak çalışıyor. Bültenler yayımlandığında PHP 8.2.13 kullanıyorduk, yani açıklıydık. 22 Ekim’de 8.2.35 yerine doğrudan 8.4.27’ye geçtik, çünkü 8.2’nin güvenlik desteği 2026 sonunda bitiyor ve onu yamalamak bize yalnızca iki ay kazandıracaktı. Yeni sürümü kendi klasörüne, eskisinin yanına kurduk; zamanlanmış görevler ve betikler hiç değiştirilmeden çalışmaya devam etsin diye eski kurulum yolunu bir dizin bağlantısıyla (junction) yeni klasöre yönlendirdik; IIS’teki FastCGI uygulamasını ve işleyici eşlemelerini değiştirdik ve geri dönüş için eski 8.2 klasörünü sakladık. Geçişten önce tüm PHP dosyalarını 8.4 ile söz dizimi denetiminden geçirdik ve üretilen sayfaları bayt bayt karşılaştırdık; sonrasında da sunucunun dışarıya artık hiçbir sürüm bilgisi vermediğini doğruladık. Testler dahil bütün iş bir sabah sürdü. Aynı dal içinde bir yama sürümüne geçmek bundan da kolay.

PHP güncellenemiyorsa geçici önlemler

Bazen aynı gün güncelleme yapmak mümkün olmaz: Dondurulmuş bir üretim ortamı, paketi olmayan eski bir sürüm ya da güncellemeyi henüz yayımlamamış bir hosting firması. Aşağıdaki ayarlar doğrulanmış saldırı yollarına karşı riski azaltır. Ancak geçicidir, kısmidir ve güncellemeyi yine de planlamanız gerekir.

; php.ini veya FPM havuz dosyası; .user.ini ve ini_set() DEĞİL
memory_limit = -1                    ; öngörülebilir bellek tükenmesi yolunu kapatır (CVE-2026-109618)
session.upload_progress.enabled = 0  ; doğrulanmış eski oturum yolunu kapatır (CVE-2026-109619)
fatal_error_backtraces = 0           ; yalnızca PHP 8.5
post_max_size = 8M                   ; yükleme gerekiyorsa 32M, upload_max_filesize bunun altında
max_input_nesting_level = 32         ; varsayılan 64; formlarınız izin veriyorsa düşürün

; php-fpm havuzu karşılıkları (uygulama bunları ezemez)
php_admin_value[memory_limit] = -1
php_admin_flag[session.upload_progress.enabled] = off

İşe yarayan bir önlemle yalnızca işe yarıyormuş gibi görünen bir önlem arasındaki farkı şu kurallar belirler:

  • Ayarları yönetici düzeyinde yapın ve yeniden başlatın. .user.ini dosyaları ve çalışma anındaki ini_set() çağrıları çok geç okunur; açıklı ayrıştırma çoktan yapılmıştır. Ardından tüm süreçleri yeniden başlatın ve hiçbir havuzun, dizinin ya da uygulama ayarının memory_limit’i geri getirmediğini kontrol edin.
  • Bellek sınırını başka bir katmanda koyun. memory_limit -1 olduğunda kontrolden çıkan tek bir istek sunucunun belleğini bitirebilir. Container veya cgroup düzeyinde bellek sınırı koyun ve belleği yakından izleyin. ulimit -v, RLIMIT_AS ya da RLIMIT_DATA kullanmayın; bunlar bellek ayırmayı başarısız kılar ki ilk açığın ihtiyaç duyduğu yol tam olarak budur.
  • İstekleri sunucunun önünde sınırlayın. Gövde boyutunu nginx’te veya yük dengeleyicide sınırlayın (client_max_body_size 8m;); Content-Length başlığı olmayan istekleri de kapsayacak şekilde. Sitede dosya yükleme yoksa multipart/form-data isteklerini tamamen engelleyin. Bu engelin dosya yüklemeyi ve bazı ödeme formlarını bozacağını bilin.
  • Hataları gizlemeye güvenmeyin. display_errors veya log_errors ayarını kapatmak ya da @ eklemek eski durumun okunmasını engellemez. Saldırganın tetikleyebileceği fatal error’ları ve zaman aşımlarını düzeltmek ise gerçekten işe yarar.
  • FPM süreçlerini yenilemeyi düşünün. pm.max_requests = 1 her isteğe yeni bir süreç verir ve istekler arası yolu keser; bedeli ciddi bir performans kaybıdır.

PHP ekibi, kullanmıyorsanız session upload progress özelliğini yama sonrasında da kapalı tutmanızı öneriyor. Neredeyse hiç kimse kullanmıyor.

Yamadan sonra derin kontrol: Sunucu ele geçirildi mi?

Etkilenen bir sunucu 17 Ekim’den sonra internete açık kaldıysa birinin denemiş olabileceğini varsayın. Aşağıdaki kontroller önce yayımlanan araştırmalarda anlatılan izlere, ardından web shell’lerin bilinen belirtilerine bakar.

Loglarda saldırı desenini arayın

  • PHP hata logu: Allowed memory size of 16777216 bytes exhausted (tried to allocate 3500032 bytes) in Unknown on line 0 gibi fatal error’lar. “Unknown on line 0”, hatanın PHP isteği okurken, hiçbir betik çalışmadan önce olduğunu gösterir. Normal trafik de bunu üretebilir; aynı IP’lerden gelen ani ve tekrarlayan kayıtlara odaklanın.
  • Web sunucusu hata logu: AH00052: child pid 1234 exit signal Segmentation fault (11) gibi süreç çökmeleri. Başarısız denemeler süreçleri çökertir; başarılı bir saldırı ise iz bırakmayabilir.
  • Erişim logu: Olağandışı büyük form gövdeli POST istekleri, hiç dosya kabul etmeyen sayfalara gelen multipart istekler ve kısa sürede gelen çok sayıda neredeyse aynı istek.

Saldırganın geride bıraktıklarına bakın

Datadog’un analizine göre en güçlü tek belirti, web sunucusu sürecinin bir shell başlatması: www-data, apache ya da nginx kullanıcısının sh veya bash açması. Uç nokta izleme yazılımınız varsa tam olarak bunu arayın. Sonra dosya sistemine bakın:

# risk penceresi açıldığından beri oluşturulan veya değişen PHP dosyaları
find /var/www -type f -name '*.php' -newermt '2026-10-17' -ls

# bilinen web shell desenleri
grep -rlE 'eval\(base64_decode|gzinflate\(base64|assert\(\$_(POST|GET|REQUEST)' /var/www

# kalıcılık
crontab -l -u www-data; ls -la /etc/cron.d /var/spool/cron

cPanel kullanıyorsanız aynı aramayı /home/*/public_html altında yapın. CMS’inizde yeni yönetici hesabı açılıp açılmadığına, .htaccess veya web.config dosyalarının değişip değişmediğine, yeni SSH anahtarlarına ve tanımadığınız dış bağlantılara da bakın. Google Search Console’da Güvenlik sorunları raporunu açın, saldırıya uğramış içerik veya enjekte edilmiş spam sayfalar olup olmadığını kontrol edin.

Bir şey bulursanız

Shell dosyasını silip devam etmeyin. Siteyi kapatın ya da bakım sayfasının arkasına alın, kodu temiz bir kaynaktan ve 17 Ekim’den önce alınmış bir yedekten yeniden kurun, sunucunun okuyabildiği tüm gizli bilgileri değiştirin: veritabanı parolaları, API anahtarları, .env içindeki değerler, SMTP bilgileri ve ödeme altyapısı anahtarları. Sonra yamalayın, doğrulayın ve siteyi geri açın. Web kullanıcısı olarak kod çalıştırılmışsa, o kullanıcının okuyabildiği her şeyin ele geçtiğini kabul etmek gerekir.

PHP2Shell’in ötesinde: Sunucuyu sıkılaştırmak

PHP2Shell bir PHP hatası. Ama böyle bir duyurunun ardından gelen saldırılar hep aynı kolay açıkları kullanır. Bunları kapatmak bir sonraki acil durumu çok daha az korkutucu yapar:

  • Sürüm ilan etmeyi bırakın. expose_php = Off yapın, sunucu imzalarını gizleyin (Apache’de ServerTokens Prod, nginx’te server_tokens off;, IIS’te removeServerHeader). Tarayıcı botlar hedeflerini bu başlıklardan otomatik seçer.
  • Gizli bilgileri web kökünden çıkarın. Okunabilen bir /.env, /.git/ klasörü ya da wp-config.php.bak küçük bir hatayı tam bir veri sızıntısına çevirir.
  • Güvenlik başlıklarını gönderin. HSTS, Content-Security-Policy, clickjacking koruması ve X-Content-Type-Options: nosniff PHP2Shell’i durdurmaz, ama enjekte edilen içeriğin ziyaretçilerinize yapabileceklerini sınırlar.
  • Çerez bayraklarını ayarlayın. session.cookie_secure, session.cookie_httponly ve session.cookie_samesite = Lax, başka bir şey ters giderse oturumları korur.
  • security.txt yayımlayın. RFC 9116 ile tanımlanan /.well-known/security.txt dosyası, araştırmacıların sorunu saldırganlardan önce size bildirmesini sağlar.

Web Sitesi Güvenlik Kontrolü bu listedeki her maddeyi tek taramada test eder. Yalnızca sertifika için SSL Sertifika Kontrolü, ham yanıt başlıklarını okumak için HTTP Başlık Kontrol Aracı kullanabilirsiniz.

Hacklenen site neden aynı zamanda bir SEO sorunu?

Uzaktan kod çalıştırma nadiren ana sayfayı değiştirmek için kullanılır. Çok daha sık görülen şey, saldırganın sessizce binlerce spam sayfa eklemesi, arama ziyaretçilerini dolandırıcılık sitelerine yönlendirmesi ya da gizli linkler koymasıdır; çünkü Google’da yıllardır güven kazanmış bir site değerlidir. Bunun ardından Google arama sonuçlarında “Bu site saldırıya uğramış olabilir” uyarısı gösterebilir, sorunu Search Console’da bildirebilir ya da etkilenen sayfaları dizinden çıkarabilir. Toparlanmak için siteyi temizlemek, inceleme istemek ve yeniden taranmayı beklemek gerekir; bu haftalar sürebilir. Ekim ortasından sonra organik trafiğiniz aniden düştüyse önce bir ele geçirilme ihtimalini eleyin. Diğer nedenler için trafik düşüşü teşhis rehberimize bakabilir, sonrasında sitenin sağlığını teknik SEO denetim listesiyle doğrulayabilirsiniz.

PHP2Shell yamalanırken yapılan yaygın hatalar

  • Web tarafı yerine komut satırına bakmak. php -v 8.4.27 diyordu; site hâlâ eski bir php-fpm havuzundan sunuluyordu.
  • Güncelleyip yeniden başlatmamak. Paket yeni, çalışan süreçler eski.
  • Sunucuyu yamalayıp imajı unutmak. Container elle düzeltildi, bir sonraki deploy her şeyi geri aldı.
  • Dağıtım paketinde sürüm numarasına güvenmek. Eski görünüp yamalı olabilir ya da güncel görünüp yamasız olabilir. Kararı değişiklik kaydı verir.
  • Önlemleri .user.ini’ye yazmak. Bu dosya işe yarayamayacak kadar geç okunur.
  • Test için internette dolaşan bir istismar kodunu çalıştırmak. Sızıntıdan saatler sonra “PHP2Shell exploit” diye kodlar dolaşmaya başladı. PHP yayın anında bunların hiçbirinin çalışmadığını tespit etti; doğrulanmamış istismar kodu zararlı yazılım dağıtmanın bilinen bir yolu.
  • Yamada durmak. Sunucu 17 Ekim’den beri açıktaysa, ele geçirilme kontrolü çözümün bir parçasıdır.

Bunu kendi sitene uygularken kitleye göre seçilmiş araçlara da bak: WordPress site sahipleri için SEO araçları ve Serbest SEO danışmanları için SEO araçları.

Sıkça sorulan sorular

PHP2Shell nedir?

PHP2Shell, Ekim 2026’da duyurulan ve PHP motorundaki iki bellek güvenliği hatasına (CVE-2026-109618 ve CVE-2026-109619) dayanan saldırı zinciridir. Kimlik doğrulaması olmayan bir saldırganın web sunucusunda, web kullanıcısının yetkileriyle kod çalıştırmasına izin verir. İkisinin de CVSS v4 puanı 9.2.

CVE-2026-109618 hangi PHP sürümünde düzeltildi?

PHP 8.2.35, 8.3.36, 8.4.27 ve 8.5.12 sürümleri hem CVE-2026-109618’i hem CVE-2026-109619’u kapatıyor. Bu dallardaki önceki sürümlerin hepsi açıklı. PHP 7.4 ile 8.1 arası için yalnızca PHP ekibinin kaynak kod yaması var; 5.4 ile 7.3 arası için hiçbir yama yok.

WordPress siteler PHP2Shell’den etkileniyor mu?

Evet, etkilenen bir PHP sürümünde çalışıyorsa. Hata PHP’nin kendisinde olduğu için WordPress çekirdeği, tema ya da güvenlik eklentisi bunu engelleyemez. Sansec, güncel bir WordPress sürümünde oturum açmadan kod çalıştırmayı doğruladı. Çözüm PHP’yi güncellemek.

Sunucuya erişimim yoksa sitemin açıklı olup olmadığını nasıl anlarım?

Web Sitesi Güvenlik Kontrolü gibi dışarıdan bir tarama yapın. Site eski bir PHP sürümü bildiriyorsa büyük olasılıkla açıklıdır. Sürüm gizliyse yamayı yalnızca hosting firması doğrulayabilir; alan adınızı hangi PHP sürümünün sunduğunu ve iki CVE yamasını içerip içermediğini sorun.

WAF veya Cloudflare beni PHP2Shell’den korur mu?

Kısmen. Cloudflare, ücretsiz plan dahil kurallar yayımladı ve bunlar Cloudflare üzerinden gelen trafikte bilinen saldırı desenlerini engelliyor. Sunucunuzun gerçek IP adresine doğrudan ulaşan saldırgan bu kuralları atlar, yeni varyantlar da kurallara takılmayabilir. WAF’ı yama yaparken ek koruma olarak kullanın, yamanın yerine değil.

memory_limit değerini -1 yapmak yeterli mi?

Hayır. Bu ayar CVE-2026-109618’in öngörülebilir bellek tükenmesi yolunu kapatır, ama başka bellek hataları açıklı koda yine ulaşabilir ve CVE-2026-109619 için hiçbir şey yapmaz. Session upload progress’i kapatmak, istek boyutunu sınırlamak ve container bellek sınırı koymakla birlikte, yalnızca güncellemeye kadar kısa bir köprü olarak kullanın.

Hosting firmam sunucunun yamalı olduğunu söylüyor. Nasıl doğrularım?

Alan adınızı sunan PHP sürümünün tam adını ve PHP süreçlerinin ne zaman yeniden başlatıldığını sorun. Dosya yükleyebiliyorsanız PHP_VERSION yazdıran geçici bir dosya gerçek sürümü gösterir; hemen silin. Dağıtım paketlerinde değişiklik kaydında iki CVE numarasının da geçmesi gerekir.

8.2’yi yamalamak yerine PHP 8.4’e mi geçmeliyim?

Yapabiliyorsanız evet. PHP 8.2 31 Aralık 2026’da güvenlik yaması almayı bırakıyor; yani 8.2.35 size yaklaşık iki ay kazandırır. Yükseltme test gerektiriyorsa 8.2’yi bugün yamalayın, 8.4’e geçişi de yıl sonundan önceye planlayın.