113SEC  —  BLOG
X000Y000
[113SEC]EN
DESTEK ↗
← TÜM YAZILAR[ ARAŞTIRMA ] — Tehdit Araştırması

Yapay zekâ anahtarlarını da arıyor: Google Cloud'dan gelen bir gizli dosya tarama aracını altı hafta izledik

Google Cloud'daki 43 IP adresinden gelen bir araç, altı hafta boyunca koruduğumuz web uygulamalarında .env, Git ve bulut anahtarlarının yanında yapay zekâ asistanlarının ayar ve kimlik bilgisi dosyalarını aradı. Kayıtlarda ne gördüğümüzü, neyin işe yarayıp neyin yaramadığını ve kendi ortamınızı nasıl test edeceğinizi anlatıyoruz.

WAF KAYDI YOK18 EYL5 EKİ23 EKİ2 KASARAÇ A · 43 IP · 83 OTURUM

Yönetici özeti

  • Araç ve altyapısı: 18 Eylül – 2 Kasım 2026 arasında, koruduğumuz web uygulamalarını 43 farklı IP adresinden tarayan bir aracı (bu yazıda Araç A) izledik. Adreslerin hepsi Google Cloud'da; 42'si Belçika bölgesinde (europe-west1).
  • Liste: Araç 8 Ekim'den bu yana her taramada 112 yollu sabit bir çekirdek liste kullanıyor ve buna çoğu taramada değişen küçük bir "tema" ekliyor.
    • Çekirdekte .env, Git ve AWS dosyalarının yanında .claude/settings.json, .env.anthropic ve .env.openai var.
    • Temalarla birlikte yapay zekâ asistanı, LLM platformu ve MCP yollarının sayısı 32'ye çıktı (AI21, Mistral gibi başka model sağlayıcıları ve ses/görüntü API'leriyle birlikte 44). Aralarında .claude/credentials.json, .openai/credentials gibi kimlik bilgisi dosyaları ve .cursor/mcp.json, .vscode/mcp.json gibi MCP yapılandırmaları var.
  • Ortak bir merkezden yönetiliyor gibi: Aynı tema aynı günlerde farklı IP'lerden geldi (30 Ekim – 2 Kasım arasında 7 IP'den birebir aynı küme); aynı IP ise neredeyse her gelişinde başka bir tema getirdi (birden fazla gelen 22 IP'nin 21'i).
  • Hız ve geri dönüş: Taramaların yarısı 2,5 saniyeden kısa sürüyor; bu hızda IP engeli o taramayı durduramaz. Ancak adresler geri dönüyor: 83 oturumun 41'i daha önce görülmüş bir IP'den geldi.
  • Bizi koruyanlar: İsteklerin %69'unu durduran kenardaki kurallar ve web kökünde bulunacak bir şey olmaması. İncelediğimiz taramaların hiçbirinde veri sızmadı.
  • En önemli ders: SIEM'imiz bu aracın ekim–kasımdaki 42 adresinden yalnızca 11'ini gördü. Kalanını WAF kayıtlarında çekirdek listeyi arayarak bulduk.
  • Tek araç bu değil: Aynı haftalarda beş farklı tarayıcı kimliğiyle çalışan ikinci bir araç ve ağustosta 17 yapay zekâ yolunu deneyen üçüncü bir araç gördük. 30 günde 205 farklı IP sistemlerimizde gizli dosya aradı; bunların %54'ü Google Cloud'dandı.

Arka plan

Açıkta kalan dosyalardan anahtar toplamak ve bu anahtarları paraya çevirmek yeni değil:

  • Unit 42 (2024): 110.000 alan adındaki açık .env dosyalarından toplanan anahtarlarla AWS ortamlarına girilip S3 verilerinin silindiği ve fidye notu bırakıldığı bir gasp operasyonunu belgeledi.
  • Sysdig, EMERALDWHALE (2024): Açık .git/config dosyalarını tarayıp 15.000'i aşkın bulut kimlik bilgisi toplayan bir operasyonu raporladı.
  • Sysdig, "LLMjacking" (2024): Çalınan bulut anahtarlarıyla yapay zekâ modellerine erişildiğini ve faturanın hesap sahibine kaldığını gösterdi.

Gözlemlerimiz bu eğilimin sürdüğünü gösteriyor. En az iki ayrı tarama aracı, bulut anahtarlarının yanında yapay zekâ araçlarının yapılandırma ve kimlik bilgisi dosyalarını da arıyor.

Araç A'yı nasıl bulduk

İlk ipucu SIEM'den geldi. Wazuh, "kısa sürede çok sayıda 4xx" kuralıyla eylül sonundan itibaren aynı türden taramalar için alarm üretiyordu. Bu alarmların arkasında 112 yollu sabit bir liste olduğunu fark edince, aynı listeyi WAF kayıtlarımızda aradık. Ekim–kasımda alarm üreten adres sayısı 11'di; aynı listeyi deneyen adres sayısı ise 42 çıktı.

Dönem IP Kaynak
18 Eylül 2 Alarm satırları ve o günün trafik inceleme notu: 35.205.254[.]119 Araç A'nın kesik tarayıcı kimliğiyle geldi; 34.38.113[.]44 .claude, .anthropic ve gcloud dosyalarını aradı
24 Eylül 1 34.62.82[.]165: çok daha büyük bir liste (inceleme notuna göre 283 istek; 111 farklı yolda 4xx; yapay zekâ yolları dahil)
26 Eylül 1 34.38.113[.]44: ekim çekirdeğine çok yakın bir liste (4xx alan 30 yolun 24'ü çekirdekte)
5 Ekim – 2 Kasım 42 WAF kayıtları: 20 günde 83 oturum, 100 hedef taraması

18 Eylül satırındaki iki adres ekimde de çekirdek listeyle taradı: 35.205.254[.]119 12 ve 19 Ekim'de, 34.38.113[.]44 10 ve 20 Ekim'de. 34.62.82[.]165'i ise yalnızca 24 Eylül'de gördük.

Araç A nasıl çalışıyor

Sabit çekirdek, dönen tema.

  • 8 Ekim – 2 Kasım arasındaki 93 hedef taramasının hepsinde çekirdeğin ana sayfa dışındaki 111 yolu eksiksiz vardı.
  • Çoğu taramaya ayrıca 0–10 yollu, çoğunlukla birbiriyle ilgili bir küme eklendi; en sık 6 yol.
  • 23 Ekim öğleden sonrasına kadar tema içeren 66 taramada 51 farklı küme gördük. Bir oturumun ikinci hedefine giden aynı küme dışında, yalnızca 3 küme başka bir oturumda yeniden görüldü.
  • 23 Ekim öğleden sonra durum değişti: o gün ilk kez gelen /.cursor/mcp.json ve /.netrc, sonraki 24 taramanın 24'ünde de vardı. Deneme olarak eklenen yollar kalıcı listeye geçmiş görünüyor.
İlk görüldüğü gün Tema Örnek yollar
5 Ekim sosyal medya ve muhasebe API anahtarları, Vault, CI iş akışları /.env.facebook, /xero.json, /.vault.json, /.github/workflows/production.yml
8 Ekim yapay zekâ ve medya API'leri, mobil uygulama klasörleri /.env.claude, /.env.elevenlabs, /.env.stability, /flutter/.env
9 Ekim izleme ve e-posta hizmetleri /.env.betterstack, /.env.uptimerobot, /.env.brevo
10 Ekim kendi sunucusunda barındırılan CI, barındırma platformları /.drone.yaml, /.woodpecker.yaml, /.netlify/.env, /.vercel/.env
11 Ekim yapay zekâ kimlik bilgileri; ödeme, kimlik doğrulama, e-posta pazarlama /.claude/credentials.json, /.openai/credentials, /openai.key, /.env.mercadopago, /.env.frontegg
12 Ekim yapay zekâ ve gözlemlenebilirlik platformları /.env.ai21, /.env.writer, /grafana.json, /dynatrace.json
13 Ekim yapay zekâ asistanları ve LLM platformları, Azure /.claude/auth.json, /.anthropic/credentials.json, /.gemini/settings.json, /langsmith.json, /portkey.json, /.azure/credentials.json
16 Ekim API anahtar dosyaları, GitHub / GitLab token'ları /.api-keys, /.github/token, /.gitlab/credentials
17 Ekim Elasticsearch / Solr, iş uygulamaları ve içerik yönetim sistemleri /_cat/indices, /odoo.conf, /owncloud/config/config.php, /strapi/.env
18 Ekim bulut geliştirme ortamları, Matrix, Zabbix /.config/gitpod/credentials, /.coder/credentials, /matrix/homeserver.yaml, /zabbix/conf/zabbix.conf.php
19 Ekim barındırma ve finans teknolojisi platformları /.env.kinsta, /.env.qovery, /.env.lithic
22 Ekim MCP, gcloud /.continue/config.json, /mcp.json, /.config/gcloud/application_default_credentials.json
23 Ekim MCP ve kimlik dosyaları /.cursor/mcp.json, /.vscode/mcp.json, /.netrc, /.composer/auth.json
30 Ekim sunucu yönetim uçları /actuator/env, /server-info, /.htaccess

Temalar hedefin kullandığı teknolojiyle ilgili görünmüyor. Örneğin ödeme sağlayıcısı teması ödeme almayan bir uygulamada, LLM platformu teması yapay zekâ kullanmayan bir uygulamada denendi.

Tema IP'ye değil, göreve bağlı.

  • Birden fazla kez gelen 22 IP'nin 21'i farklı gelişlerinde farklı temalar getirdi. Örneğin 34.53.184[.]30, 10 hedef taramasında 8 farklı tema denedi.
  • Aynı tema ise farklı IP'lerden geldi:
    • 23–28 Ekim arasında 6 IP birebir aynı üç yollu ek kümeyle geldi (/.cursor/mcp.json, /.netrc, /sentry.properties); 4 IP daha bu üçlüye birkaç yol ekledi.
    • 30 Ekim – 2 Kasım arasında 7 IP birebir aynı ek kümeyle geldi.

Bu örüntü, işçi makinelerin ortak bir merkezden görev ya da liste güncellemesi aldığını düşündürüyor.

Hız.

  • Bir IP'nin bir saat içindeki taraması (bu yazıda "oturum"; 83 oturum) ortanca 2,5 saniye sürdü.
  • Oturumların 29'u 2 saniyenin, 63'ü 10 saniyenin altında kaldı. En uzunu 41 saniye.
  • Hedef başına 111–128 yol denendi.

Kimlik.

  • İsteklerin %97'si sonu kesik şu tarayıcı kimliğiyle (User-Agent) ve Accept-Encoding: gzip, deflate başlığıyla geldi: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
  • Gerçek bir Chrome bu dizgiyi (KHTML, like Gecko) Chrome/… Safari/… ile bitirir.
  • Kalan istekler tam bir tarayıcı kimliği kullandı; en sık iki yıllık Chrome 128. Bunlar ana sayfa ve sayfa kaynaklarıydı.
  • Aynı kesik kimliği ekim–kasımda Google Cloud dışından gelen 53 adres de kullandı; bunların hiçbiri çekirdeğin üçte ikisinden fazlasını denemedi. Kimlik tek başına yeterli bir imza değil.

Önce sayfayı okuyor. 100 hedef taramasının 83'ünde ana sayfa, 22'sinde sayfanın yüklediği JavaScript paketleri de istendi. Araç muhtemelen bu dosyaların içinde unutulmuş anahtar arıyor.

Hedefler. Alan adlarının hem www'li hem www'siz hâline, yük dengeleyicilerin ham IP adreslerine de geldi; toplam 13 farklı ad ve adres. Hedeflerin nasıl seçildiğini bilmiyoruz.

Ne arıyor

112 yollu çekirdeğin dağılımı:

Kategori Yol Örnekler
.env dosyaları 49 /.env, /.env.production, /api/.env, /laravel/.env
Uygulama yapılandırması 22 /appsettings.Production.json, /secrets.json, /config.php, /phpinfo.php
Bulut kimlik bilgileri 12 /.aws/credentials, /.boto, /.s3cfg, /aws-exports.js
Git 8 /.git/config, /.git-credentials, /.github/workflows/deploy.yml
Docker ve dağıtım 7 /docker-compose.yml, /.docker/config.json, /Dockerfile
Yedek ve veritabanı 6 /database.sql, /.env.bak, /wp-config.php.bak
Yapay zekâ araçları 4 /.claude/settings.json, /.claude/settings.local.json, /.env.anthropic, /.env.openai
Diğer 4 ana sayfa, /phpinfo, /_profiler/phpinfo, /wp-content/debug.log

Araç A'nın 5 Ekim – 2 Kasım arasında denediği yolların listesi yazının ekinde: sitelerimize özgü 21 yol çıkarıldıktan sonra 411 yol; bunların 32'si yapay zekâ asistanlarına, LLM platformlarına ve MCP'ye ait (diğer yapay zekâ API'leriyle birlikte 44).

Neden yapay zekâ dosyaları

Kod asistanları ve LLM platformları ayarlarını, bazen de anahtarlarını, proje klasöründeki düz metin dosyalarda tutar:

  • .claude/settings.json, .gemini/settings.json: Asistanın ayarları, izin verilen komutlar, bazen ortam değişkenleri.
  • .claude/credentials.json, .anthropic/credentials.json, .openai/credentials, openai.key: Adlarından anlaşıldığı gibi doğrudan anahtar ya da oturum bilgisi için kullanılan dosyalar.
  • .cursor/mcp.json, .vscode/mcp.json, mcp.json, .continue/config.json: MCP sunucularının tanımları. Bu dosyalarda veritabanı, GitHub ya da bulut hesaplarına bağlanmak için kullanılan token'lar bulunabilir; tek bir dosya birkaç sisteme birden giden anahtarları taşıyabilir.
  • .env.anthropic, .env.openai, langsmith.json, portkey.json, helicone.json: Model sağlayıcılarının ve LLM gözlemlenebilirlik platformlarının anahtarları.

Bu dosyalar proje klasörüyle birlikte yanlışlıkla web köküne kopyalanırsa, tek bir GET isteği yapay zekâ hesabınızın anahtarını da (faturası size kalır), MCP üzerinden bağlı sistemlerinize giden token'ları da başkasının eline verebilir. Yapay zekâ yollarının sabit çekirdekte durması ve yenilerinin düzenli olarak denenmesi, saldırganların bu dosyaları aramaya değer bulduğunu gösteriyor. Gerçekten bulup bulmadıklarını bilmiyoruz.

Aynı haftalarda ikinci bir araç

22 Eylül – 7 Ekim arasında Araç A'nın da taradığı uygulamalardan birine, yine Google Cloud'dan başka bir araç geldi (Araç B):

  • 12 IP, hepsi ABD Doğu (us-east1) ve Tayvan (asia-east1) bölgelerinde. Araç A'nın kullandığı Belçika bölgesinden hiç gelmedi.
  • Beş tam tarayıcı kimliği: Chrome 131, Edge 130, Firefox 133, Safari/macOS ve Safari/iPhone. Aynı hedefe birkaç saniye içinde bu beş kimlikle istek gönderildi; yolların çoğu ikişer üçer kez tekrar istendi.
  • Her dönemde birebir aynı liste:
    • Aynı dönemdeki IP'lerin 4xx alan yol listeleri birebir aynı: 22–24 Eylül 18 yol, 25–29 Eylül 44 yol, 2–7 Ekim 74 yol.
    • Dönemler arasındaki farkın en azından bir kısmı bizden kaynaklanıyor. 24 Eylül'de uzantılı yollar için de 404 döndürmeye başladık; 25 Eylül'den sonra eklenen 26 yolun hiçbiri nokta ile başlamıyor.
    • Ekimde WAF'ta tam listesini gördüğümüz iki IP 132 farklı yol denedi. Bu liste Araç A'nın 112 yollu çekirdeğinin yalnızca 36'sını (%32) içeriyordu.
  • Yapay zekâ yolu yok. Listesi daha çok .bash_history, .pgpass, .pypirc, .vault-token, .kube/config gibi geliştirici ve sunucu dosyalarından oluşuyor.

İki aracın aynı kişi ya da gruba ait olup olmadığını bilmiyoruz.

Tek araç bu değil

İki araç, kayıtlarımızda görünen çok daha geniş bir taramanın parçası:

  • 3 Ekim – 2 Kasım arasında 205 farklı IP, sistemlerimizde en az 10 farklı hassas yol denedi. Bunların 110'u (%54) Google Cloud adreslerindendi; 42'si Araç A'ydı. Bu IP'lerin aşağıdaki sorgudaki yollara gönderdiği isteklerin %92'si WAF'ta durdu.
  • Ağustosta üçüncü bir araç, yine Google Cloud adreslerinden, yol kodlama hileleriyle (/%2eenv, ..%252F..%252F.env, /proc/self/environ) aynı işi yaptı:
    • Kendini 20'den fazla farklı bot olarak tanıttı; aralarında ChatGPT-User, GPTBot, OAI-SearchBot, ClaudeBot, Claude-User, PerplexityBot, Amazonbot ve Meta'nın tarayıcısı vardı.
    • Google-Extended kimliğini bile kullandı. Oysa bu yalnızca robots.txt'te kullanılan bir belirteç; hiçbir gerçek istek bu kimlikle gelmez.
    • Beş IP'nin her biri aynı 17 yapay zekâ yolunu denedi: /.cursor/mcp.json, /.mcp.json, /.claude.json, /claude_desktop_config.json, /.codex/config.toml, /.aider.conf.yml, /.continue/config.json ve diğerleri.
  • 2 Kasım'da gelen başka bir araç neredeyse her istekte kimlik değiştirdi (187 istekte 158 farklı kimlik). Bunların bir kısmı Censys, LeakIX, ZoomEye, Shodan ve Palo Alto Expanse gibi internet tarama hizmetlerini taklit ediyordu.

Ders: Gerçek botlar yüzlerce gizli dosya yolunu art arda denemez. Bir bot kimliğine güvenmeden önce, sağlayıcının yayımladığı IP listeleriyle ya da ters DNS ile doğrulayın.

Bizde ne işe yaradı, ne yaramadı

İşe yaradı:

  1. Kenarda kurallar.
    • Araç A'nın 42 IP'si ekim–kasımda 11.962 istek gönderdi; bunların 8.274'ü (%69) WAF'ta durdu.
    • Engellenen isteklerin 4.191'ini, nokta ile başlayan yol bölümlerini ve bilinen gizli dosya yollarını engelleyen kendi kuralımız durdurdu.
  2. Bulunacak bir şey olmaması.
    • WAF'tan geçen istekler 404 ya da uygulamanın boş kabuğunu aldı.
    • Olay incelemelerinde, 200 dönen yanıtların ana sayfa olduğunu boyut ve MD5 özetiyle doğruladık.
    • JavaScript paketlerimizde anahtar olmadığını ayrıca taradık.

İşe yaramadı ya da geç kaldı:

  1. SIEM görünürlüğü.
    • Ekim–kasımdaki 83 oturumun yalnızca 12'si Wazuh'ta alarm üretti. Aracın 42 adresinden 31'i ekim–kasımda SIEM'e hiç düşmedi.
    • Bu oturumlar ya web kaydını o tarihte SIEM'e almadığımız hedeflere geldi ya da WAF bütün isteklerini durdurduğu için sunucuya hiç ulaşmadı.
    • Ders: WAF kayıtlarını da SIEM'e alın.
  2. IP engelleme.
    • Taramaların yarısı 2,5 saniyeden önce bitiyor; alarm, karar ve engel zinciri ne kadar hızlı olursa olsun o tarama çoğu zaman çoktan bitmiş oluyor.
    • ALB gibi uygulama katmanında çalışan bir yük dengeleyicinin arkasında, sunucudaki yerel güvenlik duvarı kuralı trafiği durdurmaz: paketler istemciden değil, yük dengeleyiciden gelir. Sunucunuz gerçek istemci IP'sini kaydetmiyorsa daha da kötüsü olur: otomatik engel yük dengeleyicinin kendi adresini engelleyip kesintiye yol açabilir.
    • Engel o taramayı durdurmaz ama geri dönüşleri durdurabilir: 83 oturumun 41'i daha önce görülmüş bir IP'den geldi.
    • Her taramadan sonra IP'yi engellediğimizi varsayarsak:
      • 30 dakikalık engel (bizim sunucu kuralımızın süresi) bunların hiçbirini durdurmazdı.
      • 24 saatlik bir engel 16'sını keserdi.
      • 7 günlük bir WAF IP listesi 31'ini keserdi.
    • Engeli yalnızca SIEM alarmına bağlasaydık, 7 günlük liste 31 değil 7 oturumu keserdi. Engeli WAF kayıtlarından tetikleyin.
  3. IP itibar listeleri, kısmen. AWS'nin yönetilen IP itibar listesi aracın 42 adresinden yalnızca 16'sını tanıdı (engellenen isteklerin %26'sı). Yeni kiralanan bulut IP'leri bu listelere geç girebiliyor.
  4. "Her şeye 200" (SPA tuzağı).
    • Eylül ortasında bilinmeyen her yol için 200 koduyla ana sayfayı döndürüyorduk.
    • Bu durumda tarama aracı "buldum" sanabilir, SIEM ise hiç hata görmediği için alarm üretmez.
    • Uzantılı ve nokta ile başlayan yollar için 404 döndürmeye başladıktan sonra taramalar SIEM'de görünür oldu.

Kendi ortamınızda ne yapabilirsiniz

30 saniyelik kendi kendine test

SITE=https://siteniz.com
for yol in / /bu-yol-kesin-yok /.env /.git/config /.aws/credentials /.claude/settings.json /.cursor/mcp.json /docker-compose.yml /Dockerfile; do
  printf '%-26s %s\n' "$yol" "$(curl -s -o /dev/null -w '%{http_code} %{size_download} bayt' "$SITE$yol")"
done
  • İlk iki satır referanstır: ana sayfa ve var olmayan bir yol. Hassas yolların hepsi 404 (ya da 403) döndürmeli. 200 alıyorsanız boyutu ilk iki satırla karşılaştırın: aynıysa SPA tuzağındasınız; farklıysa dosya gerçekten yayında olabilir, hemen kaldırın ve içindeki anahtarları değiştirin.
  • Testi sunucunuzun ham IP adresine (curl -k ile) ve varsayılan sanal sunucuya karşı da çalıştırın. Araç A bunları da taradı.

nginx

Aşağıdaki yapılandırmayı nginx 1.27.5 üzerinde test ettik. Denediğimiz 24 hassas yolun hepsi 404 aldı. Uygulamanın kendi sayfaları ve API'si etkilenmedi.

server {
    # ...

    # ACME doğrulaması: dosya yoksa 404 (SPA'ya düşmesin)
    location ^~ /.well-known/acme-challenge/ { try_files $uri =404; }

    # API: ^~ öneki aşağıdaki düzenli ifade kurallarının denenmesini engeller; hassas yollar burada ayrıca engellenir
    location ^~ /api/ {
        location ~ /\. { return 404; }
        location ~* "^/api/(.*/)?(actuator|_profiler|phpinfo|server-info|server-status)" { return 404; }
        proxy_pass http://uygulama;
    }

    # Nokta ile başlayan bir yol bölümü içeren bütün istekler 404 (yalnız /.well-known/ serbest)
    location ~ /\.(?!well-known/) { return 404; }

    # Uzantısız ama bilinen hassas adlar ve yönetim uçları
    location ~* "^/(dockerfile|jenkinsfile|procfile|makefile|credentials|env|id_rsa|id_ed25519|kubeconfig|phpinfo|server-info|server-status|actuator|_profiler|_cat|_cluster|_nodes|_users|_config|solr)(/|$)" { return 404; }

    # Uzantılı yollar: dosya gerçekten varsa sunulur, yoksa 404 (index.html'e düşmez)
    location ~* "\.[a-z0-9]{1,8}$" { try_files $uri =404; }

    # Geri kalan her şey SPA'ya
    location / { try_files $uri /index.html; }
}

Kullanmadan önce:

  • Bu yapılandırma, dosyaları diskten sunulan bir SPA içindir. Uygulamanın tamamı bir arka uca yönlendiriliyorsa (Next.js, .NET, Node), uzantı kuralı statik dosyaları bozabilir; o durumda yalnızca nokta ve hassas ad kurallarını kullanın.
  • İçinde nokta geçen SPA yolları (/kullanici/ali.veli, /belge/v1.2) da 404 alır.
  • Yük dengeleyicinizin sağlık denetimi /actuator/health gibi bu kuralların engellediği bir uca gidiyorsa, o yolu önce location = /actuator/health { … } ile açın; tam eşleşme düzenli ifadelerden önce gelir. server-status gibi izleme uçları için de aynısı geçerli.
  • Süslü parantez ya da noktalı virgül içeren düzenli ifadeleri tırnak içine alın; almazsanız nginx yapılandırmayı yüklemez (nginx -t hata verir).

AWS WAF

Nokta ile başlayan bir yol bölümü içeren istekleri kenarda yakalayan kural (/.well-known/ hariç). AWS'nin kapasite denetiminden geçti (32 WCU).

{
  "Name": "gizli-dosya-yollari",
  "Priority": 10,
  "Statement": { "AndStatement": { "Statements": [
    { "ByteMatchStatement": { "SearchString": "/.", "FieldToMatch": { "UriPath": {} },
        "TextTransformations": [ { "Priority": 0, "Type": "URL_DECODE" }, { "Priority": 1, "Type": "NORMALIZE_PATH" } ],
        "PositionalConstraint": "CONTAINS" } },
    { "NotStatement": { "Statement": { "ByteMatchStatement": { "SearchString": "/.well-known/", "FieldToMatch": { "UriPath": {} },
        "TextTransformations": [ { "Priority": 0, "Type": "URL_DECODE" }, { "Priority": 1, "Type": "NORMALIZE_PATH" } ],
        "PositionalConstraint": "STARTS_WITH" } } } }
  ] } },
  "Action": { "Count": {} },
  "VisibilityConfig": { "SampledRequestsEnabled": true, "CloudWatchMetricsEnabled": true, "MetricName": "gizli-dosya-yollari" }
}
  • Önce Count modunda birkaç gün izleyin; meşru bir yolu yakalamadığından emin olunca Block'a alın.
  • update-web-acl bütün kural listesini değiştirir. Önce get-web-acl ile mevcut kuralları alın, bu kuralı ekleyin ve LockToken ile gönderin. Priority değeri mevcut bir kuralla çakışmasın.
  • SearchString bir ikili (blob) alandır; AWS CLI v2'ye düz metin vermek için --cli-binary-format raw-in-base64-out parametresini ekleyin.

WAF kayıtlarınızda Araç A'yı arayın (CloudWatch Logs Insights)

Bu sorgu, çekirdek listeden seçtiğimiz ve başka tarama araçlarında nadir görülen 10 yolu kullanıyor. Kendi kayıtlarımızda bir aylık trafikte yalnızca Araç A'nın 42 IP'sini buldu: bu IP'lerin her biri 10 yolun hepsini denedi, başka hiçbir IP 6'ya ulaşmadı.

fields httpRequest.clientIp as ip, httpRequest.uri as uri
| filter uri in ["/.claude/settings.local.json", "/.env.anthropic", "/.env.openai", "/.amplifyrc", "/aws-exports.js", "/sendgrid.env", "/runtime-config.js", "/env-config.js", "/.docker/laravel/app/.env", "/config/aws.yml"]
| stats count_distinct(uri) as imza_yolu, count(*) as istek, min(@timestamp) as ilk, max(@timestamp) as son by ip
| filter imza_yolu >= 6
| sort ilk asc

Genel gizli dosya taramalarını görmek için ikinci bir sorgu. Bizde 205 IP döndürdü: Araç A'nın 42'si, Araç B'nin WAF kaydı olan 2'si ve 161 başka adres.

fields @timestamp, httpRequest.clientIp as ip, httpRequest.uri as uri, action
| filter uri like /(?i)\/(\.|%2e)env|\/(\.|%2e)git\/config|\/(\.|%2e)aws\/credentials|\/(\.|%2e)claude\/settings|\/(\.|%2e)cursor\/mcp\.json/
| stats count_distinct(uri) as farkli_yol, count(*) as istek, sum(action = "BLOCK") as engellenen, min(@timestamp) as ilk, max(@timestamp) as son by ip
| filter farkli_yol >= 10
| sort istek desc
  • engellenen sütunu istek'ten küçükse, o IP'nin bazı istekleri uygulamanıza kadar ulaşmış demektir; bu isteklere hangi yanıtın döndürüldüğünü uygulama kayıtlarından kontrol edin.
  • Sorgular, WAF kayıtları CloudWatch Logs'a gidiyorsa çalışır; kayıtlar S3'e gidiyorsa aynı mantığı Athena'da kurun. Kayıtları yalnızca engellenen isteklerle sınırlayan bir filtre varsa sayılar eksik çıkar.

Wazuh

  • Wazuh'un hazır 31151 kuralı (aynı kaynaktan kısa sürede çok sayıda 4xx; kural tanımında 90 saniye içinde frequency="14") bu taramaları yakalıyor, ama ancak web sunucunuz bilinmeyen yollar için gerçekten 404 döndürüyorsa (bkz. SPA tuzağı).
  • Engeli bütün web ACL'lerinizin paylaştığı bir WAF IP kümesine yazın ve en az birkaç gün tutun. Tetikleyiciyi WAF kayıtlarından alın, çünkü her tarama SIEM'e düşmüyor.

Geliştirme tarafında

  1. Web köküne proje klasörünü değil, yalnızca derleme çıktısını (dist/, public/) koyun. .claude/, .cursor/, .vscode/, .gemini/, .git/ ve .env* dağıtım paketine hiç girmesin.
  2. .env* dosyalarını ve .claude/settings.local.json gibi kişisel ayar dosyalarını .gitignore'a ekleyin. Paylaşılan .claude/settings.json depoda kalabilir, ama içinde anahtar olmamalı.
  3. Anahtarları yapılandırma dosyalarına değil, bir gizli anahtar yöneticisine koyun. MCP yapılandırmalarında token'ı dosyaya yazmak yerine ortam değişkeniyle verin.
  4. Derleme sırasında ön yüz paketlerinde anahtar taraması yapın.
  5. Bir anahtarın açığa çıktığından şüpheleniyorsanız önce anahtarı değiştirin, sonra kayıtlara bakın.

Göstergeler

Bulut IP'leri sık el değiştirir. Bu adresleri kalıcı olarak engellemek yerine, aşağıdaki davranış imzasını WAF ya da kenar kayıtlarında çalışan bir tespit kuralına çevirmenizi öneririz.

Araç A'nın davranış imzası:

  • Aynı kaynaktan bir dakikadan kısa sürede 110'dan fazla farklı gizli dosya yolu; aralarında yukarıdaki imza sorgusunun 10 yolu.
  • Gizli dosya isteklerinde kesik kimlik Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ve Accept-Encoding: gzip, deflate. Bu kimliği başka araçlar da kullandığı için tek başına yeterli değil.

Araç A'nın IP adresleri (43 adres; adresler tıklanamaz biçimde [.] ile yazıldı; tarihler UTC'ye göre; bölgeler, Google'ın yayımladığı IP aralıklarından 2 Kasım 2026'da doğrulandı):

IP                  ilk görülme  son görülme  bölge
35.205.254[.]119    2026-09-18   2026-10-19   europe-west1
34.38.113[.]44      2026-09-18   2026-10-20   europe-west1
34.62.82[.]165      2026-09-24   2026-09-24   europe-west1
34.52.229[.]253     2026-10-05   2026-10-05   europe-west1
34.77.137[.]207     2026-10-05   2026-10-05   europe-west1
34.78.213[.]249     2026-10-05   2026-10-05   europe-west1
34.140.234[.]80     2026-10-05   2026-10-08   europe-west1
35.189.229[.]134    2026-10-05   2026-10-13   europe-west1
34.140.132[.]132    2026-10-08   2026-10-11   europe-west1
34.79.51[.]100      2026-10-08   2026-10-22   europe-west1
34.52.133[.]111     2026-10-09   2026-10-09   europe-west1
35.205.88[.]64      2026-10-09   2026-10-24   europe-west1
34.156.249[.]47     2026-10-10   2026-10-10   europe-west1
34.52.150[.]124     2026-10-10   2026-10-10   europe-west1
34.62.189[.]80      2026-10-10   2026-10-20   europe-west1
35.241.178[.]74     2026-10-11   2026-10-11   europe-west1
207.175.194[.]102   2026-10-11   2026-10-18   europe-west1
207.175.220[.]59    2026-10-11   2026-10-24   europe-west1
34.53.184[.]30      2026-10-12   2026-10-30   europe-west1
34.79.12[.]228      2026-10-13   2026-10-23   europe-west1
35.240.100[.]200    2026-10-13   2026-10-24   europe-west1
34.156.22[.]151     2026-10-16   2026-10-17   europe-west1
34.62.250[.]35      2026-10-16   2026-10-17   europe-west1
136.65.74[.]74      2026-10-17   2026-10-17   us-central1
34.14.99[.]143      2026-10-17   2026-10-24   europe-west1
35.241.239[.]86     2026-10-18   2026-10-23   europe-west1
34.62.25[.]61       2026-10-18   2026-10-27   europe-west1
34.22.126[.]178     2026-10-19   2026-10-19   europe-west1
34.34.160[.]116     2026-10-19   2026-10-19   europe-west1
34.53.212[.]113     2026-10-19   2026-10-27   europe-west1
35.241.202[.]92     2026-10-20   2026-10-20   europe-west1
34.79.59[.]9        2026-10-20   2026-10-22   europe-west1
207.175.98[.]108    2026-10-22   2026-10-22   europe-west1
34.62.18[.]205      2026-10-22   2026-10-22   europe-west1
34.53.227[.]51      2026-10-22   2026-10-23   europe-west1
34.140.179[.]23     2026-10-23   2026-10-23   europe-west1
104.199.36[.]53     2026-10-28   2026-10-28   europe-west1
34.62.116[.]145     2026-10-30   2026-10-30   europe-west1
34.52.234[.]95      2026-11-01   2026-11-01   europe-west1
34.77.241[.]117     2026-11-01   2026-11-01   europe-west1
23.251.135[.]142    2026-11-02   2026-11-02   europe-west1
34.62.246[.]24      2026-11-02   2026-11-02   europe-west1
34.76.27[.]30       2026-11-02   2026-11-02   europe-west1

Araç B'nin IP adresleri (22 Eylül – 7 Ekim; hepsi SIEM kaydından, ikisinin WAF kaydı da var):

Dönem IP Bölge
22–24 Eylül 34.75.172[.]231 · 34.80.89[.]28 · 104.155.231[.]26 us-east1, asia-east1
25–29 Eylül 35.231.170[.]94 · 34.81.122[.]163 · 34.138.59[.]13 · 34.23.9[.]107 · 35.201.136[.]76 us-east1, asia-east1
2–7 Ekim 35.190.129[.]55 · 34.80.69[.]73 · 34.138.20[.]242 · 136.108.44[.]83 us-east1, asia-east1

İndirilebilir dosyalar:

MITRE ATT&CK eşlemesi

Teknik Gözlem
T1595.003 — Active Scanning: Wordlist Scanning sabit çekirdek + dönen tema ile gizli dosya taraması
T1594 — Search Victim-Owned Websites ana sayfanın ve JavaScript paketlerinin indirilmesi
T1589.001 — Gather Victim Identity Information: Credentials açıkta kalmış kimlik bilgilerini toplama girişimi
T1552.001 — Unsecured Credentials: Credentials In Files hedeflenen dosyalar; bir dosya bulunsaydı bu tekniğe geçilirdi

Gözlediğimiz bütün taramalar girişim aşamasında kaldı. Wazuh, 31151 kuralını T1595.002 ile etiketliyor.

Yöntem, veri kaynakları ve sınırlar

Tanımlar:

  • Oturum: Bir IP'nin bir saat içindeki istekleri.
  • Hedef taraması: Bir oturumun tek bir ada ya da adrese giden kısmı. 83 oturumdan 100 hedef taraması çıkıyor.

Veri kaynakları:

  • AWS WAF kayıtları, 3 Ekim – 2 Kasım 2026 (22:40 UTC'ye kadar). Uygulamalardan biri için ayrıca 4 Ağustos – 3 Eylül.
  • SOC veri gölümüzdeki Wazuh alarmları, ağustos – kasım. Bu alarmlar 4xx alan isteklerin ham kayıt satırlarını (yol ve tarayıcı kimliği dahil) içeriyor.
  • Olay inceleme notlarımız.
  • 3 Eylül – 3 Ekim arasında WAF kaydımız yok. Eylül ayrıntıları alarm satırlarından ve inceleme notlarından geliyor.

Bir IP'yi hangi araca bağladık:

  • Araç A:
    • WAF kaydı olan dönemde, çekirdeğin ana sayfa dışındaki 111 yolundan en az 105'ini denemesi. Kesik kimliği kullanan 95 adresten 42'si bunu karşıladı; bir sonraki adres yalnızca 70 yolu denedi.
    • Eylülde (WAF kaydı yokken) alarm satırlarında yalnızca kesik kimliği kullanması ve ekim çekirdeğinin sunucuya ulaşan yollarını büyük ölçüde içermesi: 34.38.113[.]44'ün 26 Eylül taraması %83, 34.62.82[.]165 %69.
  • Araç B:
    • Aynı beş tam kimliği kullanması.
    • Aynı dönemdeki IP'lerin 4xx yol listelerinin birebir aynı olması.
  • Ayrı tuttuklarımız: Benzer görünen ama bu ölçütleri karşılamayan adresler, örneğin 31 Ekim ve 2 Kasım'daki iki tarama (çekirdeğin %42–43'ü).

Çekirdeğin tanımı: Araç A'nın 100 hedef taramasının en az %70'inde görülen yollar. Eşik %50 ile %80 arasında nereye konursa konsun liste değişmiyor.

Okurken dikkat edilecekler:

  • Alarm sayıları yalnızca WAF'tan geçip 4xx alan istekleri sayar; bu yüzden hedefe ve WAF ayarına göre değişir.
  • "İlk görüldüğü gün", bir yolun Araç A'nın kayıtlarında ilk göründüğü gündür. Başka araçlar aynı yolu daha önce denemiş olabilir; örneğin /.cursor/mcp.json ağustosta üçüncü araçta da vardı.
  • 22 Ağustos'ta, gerçek istemcisini bilmediğimiz bir iç adresten gelen tek bir satırda da aynı kesik kimlik var. Bu yüzden 18 Eylül, bir IP adresine bağlayabildiğimiz ilk iz; kesin bir başlangıç değil.
  • Taramaların kime ait olduğunu bilmiyoruz; bu yazı bir atıf iddiası taşımaz. Bu adresler saldırganın kiraladığı sanal makinelere ait olabilir. Bu bir Google Cloud açığı değildir.

Kaynaklar


Bu yazı, 113SEC'in yönettiği SOC'ta gerçek trafik üzerinde yapılan gözlemlere dayanır. Sorularınız ve kendi kayıtlarınızda gördüklerinizi paylaşmak için: info@113sec.com

Sık Sorulan Sorular

Bu tarama aracı hangi dosyaları arıyor?

Her taramada 112 yollu sabit bir çekirdek liste kullanıyor: .env dosyaları, Git ve AWS kimlik bilgileri, Docker ve yedek dosyaları, ayrıca .claude/settings.json, .env.anthropic ve .env.openai gibi yapay zekâ dosyaları. Çoğu taramada buna değişen küçük bir tema ekleniyor; temalarla birlikte 32 yapay zekâ asistanı, LLM platformu ve MCP yolu denendi.

Sitemin bu taramalara açık olup olmadığını nasıl anlarım?

Yazıdaki 30 saniyelik testi çalıştırın: hassas yolların hepsi 404 ya da 403 döndürmeli. 200 alıyorsanız yanıt boyutunu ana sayfayla karşılaştırın. Boyut aynıysa SPA tuzağındasınız; farklıysa dosya gerçekten yayında olabilir, hemen kaldırın ve içindeki anahtarları değiştirin.

IP adreslerini engellemek yeterli mi?

Hayır. Taramaların yarısı 2,5 saniyeden kısa sürüyor ve bulut IP adresleri sık el değiştiriyor. Kenarda nokta ile başlayan yolları engelleyen bir WAF kuralı, WAF kayıtlarında davranış imzasını arayan bir tespit kuralı ve en az 7 gün tutulan bir WAF IP listesi birlikte daha etkili. Bizde 7 günlük liste, geri dönen 41 oturumun 31'ini keserdi.