WordPress sürekli hackleniyor mu? Arka kapıyı bulun
WordPress temizlikten sonra yine hacklendi mi? Kalıcı arka kapıları bulun: auto_prepend_file, mu-plugins, sahte eklentiler, cron, kardeş siteler, açık kapılar.
Diğer diller: English Deutsch Français Español Italiano Polski Português
WordPress'i temizledikten sonra yine hacklendiyse, saldırganın büyük olasılıkla hâlâ içeri girecek bir yolu vardır. Ya temizlikten bir arka kapı sağ çıkmıştır ya da ilk seferde kullanılan açık hâlâ kapanmamıştır. WordPress çekirdeğinin temiz bir kopyasını yüklemek ve birkaç dosyayı silmek bunların hiçbirini çözmez.
Bu rehber, temizliğin zaten yapıldığını varsayar. Temizlikten sonra tipik olarak ayakta kalan yerleri, kodun çalışma sırasına göre tek tek gezer ve her biri için somut bir kontrol verir. Sonunda döngüyü gerçekten kıran adımla biter.
Temizlikten sonra WordPress neden yeniden hacklenir
İki neden vardır ve çoğu zaman ikisi birlikte görülür. Birincisi kalıcılıktır. Saldırganlar nadiren tek bir arka kapı bırakır. Farklı yerlere birkaç tane yerleştirirler; biriniz bulunsa bile diğerleri çalışmaya devam eder. İkincisi hâlâ açık olan giriş noktasıdır. Bu, açığı olan bir eklenti, çalınmış bir parola ya da aynı hosting hesabındaki komşu bir site olabilir.
Zamanlama size ipucu verir. Temizlikten birkaç saat sonra gelen yeniden bulaşma çoğunlukla ayakta kalmış bir arka kapıya ya da dosyaları yeniden yazan zamanlanmış bir göreve işaret eder. Günler veya haftalar sonra gelen bulaşma ise bir kişinin ya da botun yeniden bulduğu açık bir kapıyı düşündürür.
Açıklar hızlı bulunur. Patchstack'in State of WordPress Security in 2026 raporu bir yazılım satıcısının raporudur, öyle okuyun. Rapora göre yoğun biçimde istismar edilen açıklarda toplu istismara kadar geçen ağırlıklı medyan süre 5 saat olmuştur. Yüksek etkili açıkların yaklaşık yarısı 24 saat içinde istismar edilmiştir. Aynı rapor, açıkların %46'sının kamuya duyurulduğu anda yayımlanmış bir düzeltmesinin bulunmadığını söylüyor. Yamalanmamış bir eklenti, gelecek hafta ele alabileceğiniz küçük bir risk değildir.
Aramaya başlamadan önce: delilleri kopyalayın
Başka bir şey silmeden önce dosyaların ve veritabanının tam bir kopyasını alın, web sunucusunun erişim günlüklerini de kaydedin. Ardından dosya zaman damgalarını kaydedin; böylece değişiklikleri sonradan günlük kayıtlarıyla eşleştirebilirsiniz:
cd /path/to/site
find . -type f -printf '%T@ %TY-%Tm-%Td %TH:%TM %p\n' | sort -n > ~/file-times-$(date +%F).txt
wp db export ~/evidence-db-$(date +%F).sql
Veritabanı dökümü kişisel veri içerir; bu kopyaları sunucudan çıkarıp güvenli bir depolama alanına taşıyın. Aksi halde aşağıdaki yedek araması bunları da listeler ve yanlışlıkla okunabilir ya da silinebilirler. Sildiğiniz her dosyanın, kullanıcının ve cron işinin tarihli basit bir listesini tutun. Giriş noktasını bulmak için buna ihtiyacınız olacak. Kişisel veriler söz konusuysa bir nedeni daha var: GDPR (AB Genel Veri Koruma Tüzüğü) madde 33(5), bildirmediğiniz olaylar dahil her kişisel veri ihlalini belgelemenizi şart koşar. Tüm sınırlandırma adımları WordPress kötü amaçlı yazılım temizleme planımızda yer alıyor.
WordPress yüklenmeden önce çalışan arka kapılar
PHP'nin auto_prepend_file ayarı, her PHP isteğinden önce, WordPress yüklenmeden ve herhangi bir güvenlik eklentisi görmeden bir dosya çalıştırır. Saldırganlar tam da bu yüzden onu sever. Ayar php.ini içinde, herhangi bir dizindeki .user.ini dosyasında ya da mod_php ile çalışan Apache'de .htaccess içindeki php_value ile yapılabilir. Tüm hesabı tarayın:
grep -Rn --include='*.ini' --include='.htaccess' -E 'auto_(prepend|append)_file' ~ 2>/dev/null
php --ini
php --ini, komut satırındaki PHP'nin hangi yapılandırma dosyalarını yüklediğini gösterir. Web sunucusunun PHP'si başka dosyalar kullanıyor olabilir; bu yüzden hosting panelindeki PHP ayarlarına da bakın. Tanımadığınız bir dosyayı gösteren her değer bir bulgudur. Yolu not edin, o dosyanın bir kopyasını saklayın, sonra ayarı kaldırın. .user.ini değişikliklerinin devreye girmesi birkaç dakika sürebilir, çünkü PHP bu dosyaları önbelleğe alır.
Sıra wp-config.php'de. Temiz bir dosyada sonlara doğru tek bir require_once ABSPATH . 'wp-settings.php'; satırı vardır ve açılıştaki yorum bloğunun üstünde çalıştırılabilir hiçbir şey bulunmaz. Başka bir şey var mı diye bakın:
head -n 5 wp-config.php
grep -nE 'eval\(|base64_decode|gzinflate|str_rot13|include|require' wp-config.php
awk 'length > 300 {print FILENAME": line "NR" is "length" chars"}' wp-config.php
Sonra dosyayı eski bir yedekteki temiz kopyayla diff ile karşılaştırın. Temiz kopyanız yoksa yapısını wp-config-sample.php ile kıyaslayın. Fazladan include satırları, çok uzun satırlar ve yorum bloğundan önce gelen kod orada olmamalıdır.
wp-content içindeki saklanma yerleri: mu-plugins ve sahte eklentiler
Must-use eklentiler ve drop-in dosyaları
wp-content/mu-plugins içindeki her şey her istekte otomatik çalışır. WordPress bunları yalnızca Eklentiler ekranındaki ayrı bir Must-Use sekmesinde gösterir; alt klasörlerdeki PHP dosyaları hiç listelenmez ve hiçbiri panelden devre dışı bırakılamaz. Pek çok sitede must-use eklenti hiç yoktur. Bazı hosting sağlayıcıları önbellek ya da yönetim için bir tane kurar.
ls -la wp-content/mu-plugins
wp plugin list --status=must-use
wp plugin list --status=dropin
Drop-in dosyalar da kontrol edilecek bir yerdir: doğrudan wp-content içindeki object-cache.php, advanced-cache.php ve db.php. Bunları önbellek eklentiniz ya da hosting sağlayıcınız koyduysa meşrudurlar. Kurduğunuz hiçbir şey varlıklarını açıklamıyorsa şüpheli sayın.
Sahte ve taklit eklenti klasörleri
Geçerli bir eklenti başlığı olmayan bir eklenti klasörü WordPress'te görünmez, ama PHP dosyalarına yine de doğrudan URL ile erişilebilir. Diskte olanı WordPress'in bildikleriyle karşılaştırın:
ls -1 wp-content/plugins | sort > on-disk.txt
wp plugin list --field=name | sort > registered.txt
comm -23 on-disk.txt registered.txt
index.php ile hello.php gibi tek dosyalı eklentiler çıktıda görünecektir. Geri kalan her şeye bakmak gerekir. Gerçek eklentileri taklit eden adlara dikkat edin: fazladan bir tire, klasör adında sürüm numarası ya da "wp-security-core" gibi. Sonra wp plugin verify-checksums --all komutunu çalıştırın. Bu komut yalnızca WordPress.org'da barındırılan eklentileri kapsar. Premium eklentiler için satıcıdan temiz bir kopya indirip diff -r ile karşılaştırın. WordPress çekirdeği için WordPress sağlama toplamlarını doğrulama rehberimizi izleyin.
Yakın zamanda değişen PHP dosyaları
find wp-content -type f -name '*.php' -mtime -30 -printf '%TY-%Tm-%Td %p\n' | sort
find wp-content -type f -name '*.php' -ctime -30
Çekirdeği henüz yeniden kurmadıysanız -newer wp-includes/version.php de işe yarar bir başka referans noktasıdır. Saldırganlar değiştirilme zamanını touch ile taklit edebilir, ancak değişiklik zamanını (-ctime) kolayca taklit edemezler; bu yüzden ikisini de çalıştırın. Yükleme klasöründeki PHP dosyaları ayrıca wp-content/uploads içindeki web shell'ler rehberimizde ele alınıyor.
Veritabanı ve zamanlayıcıdaki kalıcılık: cron, yöneticiler, uygulama parolaları
WP-Cron olayları veritabanında durur ve dosya temizliğinden sağ çıkar. Hepsini listeleyin:
wp cron event list --fields=hook,next_run_relative,recurrence
Her hook ya çekirdeğe ya da tanıdığınız bir eklentiye ait olmalıdır. Tanımadığınız bir hook için kodda grep -Rn "hook_name" wp-content ile arama yapın. Onu kaydeden kod bir mu-plugin'de ya da açıklayamadığınız bir dosyada duruyorsa bir arka kapı bulmuşsunuz demektir. Eşleşen kodu olmayan bir hook, arka kapının silindiğini ama olayın kaldığını gösterebilir. Olayı wp cron event delete hook_name ile silin.
Sonra sunucu tarafına bakın: hosting kullanıcısı için crontab -l ve hosting panelinizdeki cron bölümü. curl ya da wget çalıştıran veya web köküne yazan bir iş, her gece sessizce bir arka kapıyı geri yükleyebilir.
Sırada hesaplar var. Aşağıdaki komutlar önce tüm yöneticileri, sonra her birinin uygulama parolalarını listeler:
wp user list --role=administrator --fields=ID,user_login,user_email,user_registered
for id in $(wp user list --role=administrator --field=ID); do echo "User $id"; wp user application-password list "$id"; done
Uygulama parolaları, parola değiştirildikten sonra da çalışmaya devam eder; bu yüzden buradaki tanımadığınız bir kayıt, tanımadığınız bir yönetici kadar ciddidir. Tam inceleme WordPress kullanıcı rolleri rehberimizde.
Son olarak içerikte ve ayarlarda enjekte edilmiş betik arayın. Tablo ön ekiniz farklıysa wp_ değerini değiştirin:
wp db search 'script src=' wp_options wp_posts --stats
wp db search 'atob(' wp_options wp_posts --stats
wp db query "SELECT option_name, LENGTH(option_value) AS size FROM wp_options WHERE autoload IN ('yes','on','auto','auto-on') ORDER BY size DESC LIMIT 20;"
İlk iki arama, harici betik eklemelerini ve enjekte edilen JavaScript'in sık kullandığı base64 çözmeyi bulur. Sorgu, otomatik yüklenen en büyük seçenekleri listeler; değeri büyük olan, adı tanıdık gelmeyen bir seçenek daha yakından bakılmayı hak eder.
secaudit.eu'nun denetim eklentisi bu ele geçirilme göstergelerini tek yerde raporlar: gizli yöneticiler, şüpheli cron kayıtları, veritabanı spam'i ve çekirdek sağlama toplamı uyuşmazlıkları. Eklenti tespit eder ve raporlar. Neyin kaldırılacağına siz karar verirsiniz → secaudit.eu
Hosting hesabının geri kalanı: kardeş siteler ve eski kopyalar
Paylaşımlı hostingde birkaç site çoğunlukla tek bir sistem kullanıcısı altında çalışır. Bulaşmış bir staging kopyası, unutulmuş bir /old/ ya da /test/ kurulumu veya web kökünde duran bir yedek ZIP'i, az önce temizlediğiniz siteyi yeniden bulaştırır. Hesaptaki her şeyi listeleyin:
find ~ -name wp-config.php 2>/dev/null
find ~ -type d -name wp-includes 2>/dev/null
find ~ -type f \( -name '*.zip' -o -name '*.tar.gz' -o -name '*.sql' \) 2>/dev/null
Hesaptaki tüm siteleri aynı anda temizleyin ya da kimsenin ihtiyaç duymadıklarını silin. Tüm siteler tek bir SFTP kullanıcısını ve tek bir veritabanı kullanıcısını paylaşıyorsa, ele geçirilen herhangi bir site diğerlerinin hepsine yazabilir. Mümkün olan yerde bunları ayrı kullanıcılara ya da ayrı hosting hesaplarına bölün.
Giriş noktasını kapatın ve her şeyi aynı anda değiştirin
Giriş noktasını, ilk bulaşmanın zaman damgası civarındaki erişim günlüklerinde arayın. Tuhaf dosyalara ve şüphelendiğiniz eklentinin uç noktalarına giden POST isteklerine bakın:
grep '"POST ' access.log | awk '{print $7}' | sort | uniq -c | sort -rn | head -30
Açığı olan eklentiyi güncelleyin. Düzeltme yoksa ya da eklenti terk edilmişse başka bir eklentiyle değiştirin. İhtiyacınız yoksa silin. Devre dışı bırakmak yetmez; dosyalar diskte kalır ve URL ile hâlâ erişilebilir.
Ardından tüm sırları tek oturumda, temizlikten önce değil sonra değiştirin. Erken değiştirirseniz ayakta kalan bir arka kapı yeni değerleri de okur.
- Tüm WordPress yönetici parolaları ve her uygulama parolası
- Veritabanı parolası: hosting panelinde değiştirin, sonra wp-config.php içindeki
DB_PASSWORDdeğerini güncelleyin - Hosting paneli girişi, SFTP parolaları ve SSH anahtarları (tanımadığınız anahtarları kaldırın)
- Eklentilerde saklanan API anahtarları (ödeme, SMTP, CDN, yedek depolama)
- Güvenlik anahtarları ve salt değerleri:
wp config shuffle-salts
Aynı kontrolleri 24 saat sonra ve 7 gün sonra yeniden çalıştırın, sonuçları delil dosyalarınızla karşılaştırın. Bir mu-plugin, cron olayı ya da değiştirilmiş dosya geri geliyorsa, henüz bulamadığınız bir şey var demektir.
SSS
Kendi başıma uğraşmayı ne zaman bırakmalıyım?
İkinci yeniden bulaşmada bırakın; müşteri verilerinin açığa çıkmış olabileceği ya da sitenin siparişli bir mağaza olduğu durumlarda ise hemen. Bu noktada profesyonel bir olay müdahale ekibine başvurun. Kişisel veriler etkilendiyse, denetim otoritesine yapılacak GDPR 72 saatlik bildirimin geçerli olup olmadığını da kontrol edin. 72 saatlik ihlal bildirimi rehberimiz sürenin ne zaman başladığını açıklıyor.
Yedeği geri yüklemek yeterli mi?
Yalnızca yedek ilk arka kapıdan öncesine aitse ve giriş noktasını kapattıysanız. Aksi halde siteyle birlikte sorunu da geri yüklersiniz.
Tüm parolaları değiştirmek saldırıları durdurur mu?
Hayır. Ayakta kalan bir arka kapının parolaya ihtiyacı yoktur. Kimlik bilgilerini aramanın yerine değil, aramadan sonra değiştirin.
Bu makale genel bilgilendirme amaçlıdır, hukuki danışmanlık değildir.
Kendi sitenizi kontrol edin
Security Audit & Compliance, secaudit.eu’nun WordPress eklentisidir: zararlı yazılımları, gizli spam’i, değiştirilmiş çekirdek dosyalarını ve açıklı kodu tarar; bulguları GDPR Md. 32, NIS2 Md. 21 ve OWASP Top 10 ile eşleştirir.
Eklentinin neleri kontrol ettiğini görün