Sitenizin hacklendiğini fark ettiğinizde ilk sorulardan biri şudur: "Saldırgan sunucuya ne bıraktı?" Çoğu durumda cevap, normal bir dosya gibi görünen ama uzaktan komut çalıştırmaya veya yeni dosya yüklemeye izin veren bir PHP dosyasıdır. Bu tür dosyalara genellikle web shell veya arka kapı (backdoor) denir. Google'ın web.dev rehberi de saldırganların tekrar girebilmek için arka kapı bırakabileceğini ve temizlediğiniz kodu yeniden ekleyebileceğini özellikle belirtir.

Bu yazıda şüpheli PHP dosyalarını sakin ve sıralı bir şekilde nasıl bulacağınızı anlatıyoruz: son değişen dosyaları listelemek, uploads klasöründe olmaması gereken PHP dosyalarını yakalamak, tehlikeli fonksiyon kalıplarını grep ile aramak ve WordPress çekirdeğini WP-CLI ile resmi sağlama değerleriyle karşılaştırmak. Amaç saldırı kodunu anlamak değil, onu bulup güvenli şekilde temizlemektir. Genel temizlik akışı için önce WordPress hacklendi temizleme rehberi yazısına göz atabilirsiniz.

Başlamadan önce: aramayı bozmayacak üç kural

Başlamadan önce: aramayı bozmayacak üç kural: Önce yedek alın., Hiçbir şeyi hemen silmeyin., Notlarınızı tutun.
  • Önce yedek alın. Enfekte haldeki dosyaların ve veritabanının bir kopyasını ayrı bir yere indirin. WordPress.org da temizliğe geçmeden önce, enfekte olsa bile ortamın bir anlık görüntüsünü almanızı önerir. Bu kopya hem inceleme hem de bir şey ters giderse geri dönüş için gereklidir. Ayrıntılar için WordPress yedekleme ve geri yükleme yazısına bakın.
  • Hiçbir şeyi hemen silmeyin. Bulduğunuz dosyanın yolunu, boyutunu ve değişiklik tarihini not edin. Bu tarih, aynı zaman aralığında değişen diğer dosyaları bulmanızı sağlar.
  • Notlarınızı tutun. WordPress.org, ne gördüğünüzü, ne zaman fark ettiğinizi ve son yaptığınız değişiklikleri (yeni eklenti, tema değişikliği vb.) yazmanızı ister. Bu, olay raporunun temelidir.

1. Son değişen PHP dosyalarını listeleyin

Saldırının fark edildiği tarihe yakın değişmiş dosyalar en güçlü ipucudur. Google'ın Japon anahtar kelime hack rehberi de aramayı varsayılan olmayan dosyalara, saldırıyı fark ettiğiniz zamana yakın değişen dosyalara ve alışılmadık büyüklükteki dosyalara daraltmayı önerir. Komutları WordPress'in kurulu olduğu klasörde (örneğin public_html) çalıştırın:

bash
# Son 7 gunde degistirilmis PHP dosyalari, tarihe gore sirali
find . -type f -name '*.php' -mtime -7 -printf '%TY-%Tm-%Td %TH:%TM  %p\n' | sort

# Degisiklik zamani (mtime) sahte gosterilebilir; ctime ile de bakin
find . -type f -name '*.php' -ctime -7

# Alisilmadik buyuklukteki PHP dosyalari
find . -type f -name '*.php' -size +500k

Burada iki ayrıntı önemlidir. Birincisi, dosyanın değişiklik zamanı (mtime) bir dosya üzerinde elle değiştirilebilir; bu yüzden durum değişikliği zamanını gösteren ctime ile de bakmak iyi bir alışkanlıktır. İkincisi, yakın zamanda WordPress, eklenti veya tema güncellemesi yaptıysanız listede çok sayıda meşru dosya çıkar. Bu normaldir; listeyi güncelleme tarihleriyle karşılaştırın.

2. Uploads klasöründe PHP dosyası arayın

wp-content/uploads klasörü görseller ve belgeler içindir. Burada çalıştırılabilir PHP dosyası bulmak, en sık rastlanan uyarı işaretlerinden biridir. Aşağıdaki komut, uploads altındaki PHP ve benzeri uzantılı dosyaları listeler:

bash
find wp-content/uploads -type f \( -name '*.php' -o -name '*.phtml' -o -name '*.php5' -o -name '*.phar' \)

# Tum sitedeki .htaccess dosyalari (gizli olanlar dahil)
find . -type f -name '.htaccess'

Bazı eklentiler uploads altında kendi klasörlerini oluşturur ve içine dizin listelemeyi engellemek için içi boş bir index.php koyabilir. Böyle bir dosyanın içi genellikle tek satırlık bir yorumdur. İçinde uzun, okunmaz metinler veya aşağıdaki fonksiyonlar varsa şüpheli kabul edin. Uploads altındaki beklenmedik .htaccess dosyaları da incelenmelidir; WordPress.org, .htaccess dosyasının enfeksiyon türünden bağımsız olarak en sık değiştirilen dosyalardan biri olduğunu ve kök dışında başka klasörlerde de bulunabileceğini belirtir.

3. Şüpheli kalıpları grep ile arayın

3. Şüpheli kalıpları grep ile arayın: eval(, base64_decode(, gzinflate(, str_rot13(, strrev(, assert(

Kötü amaçlı PHP kodu genellikle okunmasın diye gizlenir (obfuscation). Google'ın rehberleri bu tür kodların yanında sık görülen fonksiyonları sayar: base64_decode, rot13, eval, strrev, gzinflate. Search Console yardım sayfası da yanıtlarda "eval", "base64_decode" ve "unescape" aramayı önerir. Aşağıdaki aramalar yalnızca dosya adını ve satır numarasını gösterir; kodu çalıştırmaz:

bash
# Sik kullanilan gizleme ve calistirma fonksiyonlari
grep -rnE --include='*.php' 'eval\(|base64_decode\(|gzinflate\(|str_rot13\(|strrev\(|assert\(' wp-content

# Eski PHP surumlerinde kod calistirmaya izin veren preg_replace /e kalibi
grep -rnE --include='*.php' "preg_replace\(\s*['\"].*/[a-z]*e[a-z]*['\"]" wp-content

# Cok uzun, kesintisiz kodlanmis metin iceren dosyalar (sadece dosya adlari)
grep -rlE --include='*.php' '[A-Za-z0-9+/=]{300,}' wp-content
KalıpNeden dikkat çeker?Meşru kullanım olabilir mi?
eval(Metin olarak gelen kodu çalıştırır; gizlenmiş kodla birlikte sık görülür.Nadiren. Tema ve eklentilerde görülmesi tek başına alarm sebebi olmasa da mutlaka incelenmelidir.
base64_decode(Kodlanmış içeriği açar; eval(base64_decode(...)) klasik gizleme örneğidir.Evet. Görsel verisi, lisans veya API işlemleri için yaygın kullanılır.
gzinflate(, str_rot13(, strrev(Gizleme katmanı olarak base64 ile zincir halinde kullanılabilir.Evet, sıkıştırma ve metin işleme için kullanılabilir.
assert(Eski PHP sürümlerinde metin olarak verilen ifadeyi çalıştırabiliyordu.Evet, test ve hata ayıklama kodlarında görülür.
preg_replace ile /eEski PHP sürümlerinde değiştirme sonucunu kod olarak çalıştırıyordu (PHP 7.0 ile kaldırıldı).Güncel kodda beklenmez.
Çok uzun kodlanmış metinAsıl zararlı kod çoğu zaman bu metnin içine saklanır.Evet, gömülü fontlar, görseller veya sıkıştırılmış JS içeren dosyalarda olabilir.

4. Çekirdek ve eklentileri resmi sağlama değerleriyle karşılaştırın

Elle aramanın en büyük zorluğu, binlerce dosya içinde neyin orijinal olduğunu bilmektir. WP-CLI bu işi sizin yerinize yapar. wp core verify-checksums komutu, kurulu WordPress sürümünün MD5 sağlama değerlerini WordPress.org'dan indirir ve dosyalarınızla karşılaştırır. Komut WordPress'i yüklemeden çalışır; bu, enfekte bir sitede kullanılmasını daha güvenli kılar.

bash
# WordPress cekirdek dosyalarini dogrula
wp core verify-checksums

# Kok dizindeki WordPress'e ait olmayan dosyalar icin de uyari ver
wp core verify-checksums --include-root

# Turkce paket kurduysaniz yerel ayari belirtin
wp core verify-checksums --locale=tr_TR

# WordPress.org dizinindeki tum eklentileri dogrula
wp plugin verify-checksums --all

Her şey yolundaysa çekirdek için "Success: WordPress installation verifies against checksums." mesajını görürsünüz. Bir dosya eşleşmezse komut o dosyayı uyarı olarak listeler ve sonunda kurulumun doğrulanamadığını bildirir. WP-CLI belgesi, doğrulama başarısız olursa yönetim panelindeki Dashboard > Updates ekranında görünen sürüm ve yerel ayar değerleriyle tekrar denemenizi önerir.

Bu komutların sınırlarını bilmek de önemlidir:

  • wp core verify-checksums yalnızca WordPress çekirdek dosyalarını kapsar. Temalarınız, eklentileriniz ve uploads içeriğiniz bu karşılaştırmanın konusu değildir.
  • wp plugin verify-checksums eklenti dosyalarını WordPress.org'daki sağlama değerleriyle karşılaştırır. WordPress.org dizininde olmayan ücretli veya özel eklentiler için karşılaştırılacak resmi veri bulunmaz; bunları satıcının sitesinden indireceğiniz temiz kopyayla değiştirmek gerekir.
  • --strict seçeneği, readme.txt gibi dosyalardaki küçük değişiklikleri de hata sayar. İlk taramada seçeneksiz çalıştırıp sonra sıkılaştırabilirsiniz.
  • Temaların otomatik doğrulaması için bu iki komut gibi resmi bir karşılık yoktur; temayı resmi kaynağından indirip diff ile karşılaştırabilirsiniz.

Elinizde temiz olduğundan emin olduğunuz bir yedek varsa, web.dev rehberinin önerdiği gibi tüm klasörü karşılaştırmak da çok etkilidir:

bash
# Mevcut site ile temiz yedek arasindaki farkli ve yeni dosyalar
diff -qr public_html/ yedek/public_html/

# Tek bir dosyayi karsilastirma
md5sum public_html/index.php yedek/public_html/index.php

Komut satırınız yoksa: tarayıcı eklentileri ve uzak tarayıcılar

WordPress.org'un "My site was hacked" sayfası, uygulama düzeyinde tarama için uzun süredir var olan eklentileri listeler: Wordfence, Sucuri Security, Quttera Web Malware Scanner ve GOTMLS. Uzaktan tarama için ise Sucuri SiteCheck ve VirusTotal önerilir. Aynı sayfa, tek bir çözümün en iyisi olmadığını, farklı türdeki tarayıcıların birlikte kullanılmasının başarı şansını artırdığını vurgular.

Uzak tarayıcılar yalnızca dışarıdan görünen sayfayı inceler; sunucuda sessizce bekleyen bir web shell'i göremeyebilirler. Eklenti tabanlı tarayıcılar ise dosyaları içeriden okur ama saldırgan WordPress'in kendisini değiştirdiyse sonuçlar yanıltıcı olabilir. Bu yüzden mümkünse eklenti taramasını yukarıdaki komutlarla veya temiz yedekle karşılaştırmayla destekleyin. Ayrıca WordPress.org, saldırının çoğu zaman sizin bilgisayarınızdan çalınan FTP veya panel şifreleriyle başladığını hatırlatır; kendi bilgisayarınızda da tam bir virüs taraması yapın.

Yanlış alarmları nasıl ayırırsınız?

Yanlış alarmları nasıl ayırırsınız? Dosya yeri, Doğrulama, Ad benzetmesi, Okunabilirlik
  • Dosya yeri: Bilinen bir eklentinin kendi klasöründe ve eklentinin son güncelleme tarihinde değişmiş bir dosya, uploads altında rastgele adlı bir PHP dosyasından çok daha az şüphelidir.
  • Doğrulama: Dosya wp plugin verify-checksums ile doğrulanıyorsa, içindeki base64_decode eklentinin orijinal kodudur.
  • Ad benzetmesi: Çekirdek dosyalara benzeyen ama çekirdekte olmayan adlar (örneğin farklı bir klasöre konmuş wp-*.php benzeri dosyalar) dikkat ister. --include-root kök dizindeki yabancı dosyaları gösterir.
  • Okunabilirlik: Meşru kod genellikle yorumlu ve okunabilirdir. Tek satıra sıkıştırılmış, değişken adları anlamsız ve yüzlerce karakterlik kodlanmış metin içeren dosyalar şüphelidir.
  • Ortak hedef dosyalar: WordPress.org, değiştirildiklerinde tüm sayfa isteklerini etkileyebildikleri için index.php, header.php, footer.php ve tema fonksiyon dosyasına özellikle bakmanızı önerir. Google da index.php, wp-load.php, 404.php ve view.php dosyalarını sık enjekte edilen dosyalar arasında sayar.

Şüpheli bir dosya bulduktan sonra ne yapmalı?

  • 1. Kaydedin: Dosyanın tam yolunu, boyutunu, mtime ve ctime değerlerini not edin. Dosyanın bir kopyasını incelemek için sitenin dışında, sıkıştırılmış ve çalıştırılamayacağı bir yerde saklayın.
  • 2. Aynı zamanda değişenleri arayın: Bulduğunuz tarihi referans alıp o gün ve çevresinde değişen tüm dosyaları tekrar listeleyin. Tek bir web shell bulmak, başka olmadığı anlamına gelmez.
  • 3. Erişim günlüklerine bakın: Dosyaya hangi IP'lerden ve ne zaman istek yapıldığını görmek, saldırının nereden geldiğini anlamanıza yardım eder. Panelinizde ham erişim günlükleri (cPanel'de varsa Raw Access) bulunabilir. Günlük okumanın temelleri için Linux loglarını okuma yazısına bakın. Google, saldırganların günlükleri de değiştirebileceğini hatırlatır.
  • 4. Temizleyin: Çekirdekte veya bir eklentide değişmiş dosya varsa tek dosyayı düzeltmek yerine aynı sürümün temiz kopyasıyla değiştirin. WordPress.org, /wp-admin ve /wp-includes klasörlerinin güvenle değiştirilebileceğini, yönetim panelindeki yeniden kurma seçeneği yerine FTP/SFTP ile yüklemeyi önerir; çünkü panel içi kurulumlar çoğu zaman yalnızca mevcut dosyaların üzerine yazar, saldırının eklediği yeni dosyaları bırakır. Uploads altındaki PHP dosyalarını kaldırın.
  • 5. Giriş yolunu kapatın: Tüm şifreleri (WordPress, panel, FTP/SFTP, veritabanı) değiştirin ve güvenlik anahtarlarını yenileyin (WordPress güvenlik anahtarları). Dosya izinlerini WordPress dosya izinleri rehberi ile kontrol edin. Kalıcı önlemler için hack sonrası güvenlik sertleştirme yazısına geçin.
  • 6. Tekrar tarayın: Birkaç gün boyunca aynı komutları yeniden çalıştırın. Silinen dosya geri geliyorsa hâlâ bir arka kapı veya zamanlanmış görev vardır.

Sık yapılan hatalar

  • Yalnızca bulunan ilk dosyayı silip işi bitmiş saymak.
  • Şifreleri temizlikten önce değiştirip, temizlikten sonra tekrar değiştirmemek. WordPress.org şifrelerin site temizlendikten sonra yeniden değiştirilmesini özellikle ister.
  • Yönetim panelindeki "yeniden yükle" düğmesine güvenip saldırganın eklediği yeni dosyaları yerinde bırakmak.
  • Grep'te çıkan her base64_decode satırını silerek meşru eklentileri bozmak.
  • Veritabanını ve yönlendirmeleri kontrol etmemek. Kodlar yalnızca dosyalarda değil, seçenek tablolarında ve yazı içeriklerinde de olabilir; bunun için site başka siteye yönleniyor yazısına bakın.

Sık Sorulan Sorular

Web shell her zaman uploads klasöründe mi olur?

Hayır. Uploads sık kullanılan bir yer olduğu için ilk bakılacak yerdir, ama zararlı kod tema ve eklenti klasörlerine, çekirdek dosyaların içine veya kök dizine de yerleştirilebilir. Bu yüzden yalnızca uploads'a bakmak yerine yazıdaki tüm adımları uygulayın.

wp core verify-checksums temiz sonuç verdiyse sitem temiz mi?

Yalnızca WordPress çekirdek dosyalarının orijinal olduğunu gösterir. Temalar, eklentiler, uploads ve veritabanı ayrıca kontrol edilmelidir. Eklentiler için wp plugin verify-checksums --all kullanın; WordPress.org dışındaki eklenti ve temaları temiz kopyalarıyla değiştirin.

Şüpheli dosyayı tarayıcıda açıp ne yaptığını görebilir miyim?

Bunu yapmayın. Dosyayı web üzerinden çağırmak içindeki kodu çalıştırır. Google da enfekte sayfaları doğrudan tarayıcıyla açmaktan kaçınmanızı önerir. Dosyanın içeriğine bakmanız gerekiyorsa sunucuda bir metin görüntüleyiciyle veya indirdiğiniz kopyayı bir metin düzenleyicide açarak inceleyin.

Silinen şüpheli dosya birkaç saat sonra geri geldi. Neden?

Genellikle başka bir arka kapı, değiştirilmiş bir çekirdek veya eklenti dosyası ya da zamanlanmış bir görev dosyayı yeniden oluşturuyordur. Sunucudaki cron girişlerini ve WordPress zamanlanmış görevlerini kontrol edin, tüm şifreleri yeniden değiştirin ve gerekirse temiz yedekten geri dönmeyi düşünün. Ayrıntılı akış WordPress temizleme rehberinde anlatılıyor.

Google uyarısı varsa temizlikten sonra ne yapmalıyım?

Search Console'daki Security issues raporunda listelenen tüm sorunları tüm sayfalarda düzelttikten sonra inceleme isteyin. Süreç "Bu site saldırıya uğramış olabilir" uyarısı ve tehlikeli site uyarısını kaldırma yazılarında anlatılıyor.

Yazılım, eklenti ve hizmet adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen şirketlerle bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.

İlgili içerikler: WordPress hacklendi: temizleme rehberi · Site başka siteye yönleniyor · Japon anahtar kelime hack · Hack sonrası güvenlik sertleştirme · WordPress dosya izinleri · Linux loglarını okuma