Selman Bilal Sivri — L2/L3 MDR Analyst, InfinitumIT
Giriş
Daha önceki bir yazımda (Trusted Process Suistimali: MDE, vmtoolsd'nin Arkasına Saklanan Komutu Neden Görmüyor?) EDR'ların “imzalı ebeveyn = güvenli” varsayımının nasıl istismar edilebileceğini ele almıştım. Orada kaçırılan şey yeni bir process'in doğuşuydu; vmtoolsd altında başlayan bir PowerShell süreci, hiçbir üründe alarm üretmemişti.
Bu yazıda farklı bir kör noktaya bakıyoruz: hiçbir yeni process doğmadığında ne oluyor? Klasik process injection; bir sürecin, zaten çalışan başka bir sürecin belleğine yazıp orada kod/DLL çalıştırması… MITRE ATT&CK'te T1055 olarak tanımlanan, saldırganların onlarca yıldır kullandığı bir teknik. Burada davranışsal tespitin dayandığı en temel korelasyon kaynağı (parent-child ilişkisi) baştan devre dışı, çünkü ortada yeni bir “child” yok.
Bunu laboratuvar ortamında test ettik, ardından MDE ajanı yüklü gerçek bir kurumsal ortamda (binlerce uç nokta) 30 günlük pencerede doğruladık. Sonuç, vmtoolsd bulgumuzla aynı başlığı taşıyor ama farklı bir mekanizmadan geliyor: kayıt var, alarm yok.
Vaka: Klasik LoadLibrary Injection
Test PowerShell scripti şu adımları izliyor:
notepad.exebaşlatılıyor.OpenProcessilePROCESS_ALL_ACCESShandle'ı alınıyor.VirtualAllocExile notepad'in belleğindePAGE_READWRITE(execute değil) izinli bir alan ayrılıyor.- Bu alana bir DLL yolunun string hâli (
C:\Windows\System32\amsi.dll— meşru, sistemin kendi imzalı DLL'i)WriteProcessMemoryile yazılıyor. CreateRemoteThread, notepad içindeLoadLibraryW'yi bu string parametresiyle çağırıyor.
Bu, “klasik DLL injection” olarak bilinen, shellcode gerektirmeyen, sadece işletim sisteminin kendi LoadLibraryW fonksiyonunu uzaktan tetikleyen bir teknik. Kritik ayrıntı şu: bellek hiçbir zaman çalıştırılabilir (execute) olarak işaretlenmiyor; sadece bir string parametresi taşıyor. Yani birçok EDR'ın güvendiği “şüpheli RWX bellek bölgesi” sezgiselini baştan devre dışı bırakıyor. Hedef DLL de zararlı değil, sistemin kendi imzalı bileşeni.
Bu script, MDE ajanı yüklü bir test makinesinde çalıştırıldı. Timeline'da hareket görüldü. Hiçbir alarm/incident üretilmedi.
Bu Neden Kaçırılıyor: Cross-Process Bellek Erişimi Başlı Başına Anormal Değil
vmtoolsd yazısındaki gibi burada da tek bir nedene indirgemek yanıltıcı olur. Aynı test makinesinde, aynı 24 saatlik pencerede topladığımız telemetri şunu gösterdi:
msedgewebview2.exe, kendi sibling render süreçlerine sürekliVirtualAllocExbenzeri uzak bellek operasyonları yapıyor; modern tarayıcıların multi-process sandbox mimarisinin normal, yüksek hacimli davranışı.- MDE'nin kendi sensörü (
SenseIR.exe),lsass.exe'den bellek okuyor; bu, ürünün kendi credential-scan/incident-response mekanizması.
Yani cross-process bellek erişimi, tek başına ele alındığında zaten çok yaygın ve çoğunlukla meşru bir davranış sınıfı. Asıl ayırt edici sinyal ne yapıldığı değil, kimin başlattığı: bir tarayıcının kendi render process'ine yazması ile bir script motorunun (powershell.exe, cmd.exe, wscript.exe…) ilgisiz bir kullanıcı uygulamasına yazması arasında büyük fark var. Davranışsal motorlar bu ayrımı varsayılan politikada yeterince keskin çizmiyor.
MDE Özelinde: Kayıt Var, Alarm Yok
MDE'nin süreç/bellek telemetrisi DeviceEvents tablosuna, ActionType alanıyla düşüyor. Test sırasında şu ActionType'lar tam çözünürlükte, kaynak/hedef/PID/integrity level bilgisiyle kayıt altına alınmıştı:
NtAllocateVirtualMemoryRemoteApiCall—VirtualAllocEx'in karşılığıCreateRemoteThreadApiCall—CreateRemoteThread'in karşılığıReadProcessMemoryApiCall,NtProtectVirtualMemoryApiCall
Daha da çarpıcısı: gerçek ortam doğrulamasında, MDE'nin kendi davranış sınıflandırıcısının bir olayı RemoteCreateThreadProcessHollowing ActionType'ıyla etiketlediğini gördük; yani MDE bu tekniğe zaten bir isim veriyor, onu “process hollowing” olarak tanıyor. Buna rağmen varsayılan politika bunu bir alarma çevirmiyor.
T1055.001 — Dynamic-link Library Injection olarak etiketliyor; yine de bir alarm/incident üretilmiyor.Bu, vmtoolsd bulgumuzla aynı tasarım felsefesinin bir başka yüzü: MDE'nin bulut tarafındaki davranışsal modelleri, tek başına cross-process bellek operasyonunu düşük öncelikli/gürültü ağırlığında değerlendiriyor çünkü (yukarıda gösterdiğim gibi) bu davranış sınıfının meşru kaynakları var. Görünürlük kaybolmuyor; karar müşteriye bırakılıyor.
Advanced Hunting Sorgusu
DeviceEvents
| where ActionType in ("CreateRemoteThreadApiCall",
"RemoteCreateThreadProcessHollowing")
| where InitiatingProcessFileName in~ ("powershell.exe","pwsh.exe","cmd.exe",
"wscript.exe","cscript.exe","mshta.exe","rundll32.exe")
| where isnotempty(FileName)
| project Timestamp, ReportId, DeviceId, DeviceName, ActionType,
InitiatingProcessFileName, InitiatingProcessId, InitiatingProcessAccountName,
InitiatingProcessCommandLine, InitiatingProcessParentFileName,
FileName, FolderPath, ProcessId, AdditionalFields
| order by Timestamp desc
Sorgu kasıtlı olarak initiator tarafını script/yorumlayıcı motorlarıyla sınırlıyor. Tarayıcıların ve MDE'nin kendi sensörünün ürettiği meşru gürültüyü baştan dışarıda bırakmak için. Hedefin (FileName) boş olmaması şartı da, çözülemeyen/korumalı process'lere yönelik gürültüyü eliyor.
Gerçek Ortamda Doğrulama: Gürültüden Sinyale
Laboratuvar bulgusunun bir kural olarak işe yarayıp yaramayacağını anlamanın tek yolu, onu gerçek ölçekte çalıştırmak. Sorguyu binlerce uç noktalı bir kurumsal ortamda 30 günlük pencerede çalıştırdık. İlk sonuç 160'tan fazla olay döndürdü ama neredeyse tamamı tek bir kaynaktan geliyordu: bir donanım üreticisinin (dizüstü bilgisayar) System Tray Icon, rundll32.exe üzerinden kendi eklentisini explorer.exe'den her gün rutin olarak kaldırıyordu (UnloadBatteryGaugeFromExplorer). Tamamen zararsız, ama sorguyu ayarlamadan canlıya almak, tam da Microsoft'un varsayılan alarm üretmeme kararının arkasındaki gerekçeyi kanıtlıyor: bu davranış sınıfı, kurumsal filoda organik olarak sık üretiliyor.
Bu vendor-spesifik gürültüyü sorgudan çıkardıktan ve bilinen güvenlik test altyapısı cihazlarını hariç tuttuktan sonra, 30 günlük pencerede geriye tek bir olay kaldı. O tek olay, bir WinRM oturumu üzerinden gelen, powershell.exe'nin dinamik olarak derlenmiş bir P/Invoke bileşeni üzerinden başka bir powershell.exe sürecine CreateRemoteThread ile enjekte olduğu ve MDE'nin bunu RemoteCreateThreadProcessHollowing olarak etiketlediği bir zincirdi. Bu olay, aylardır hiçbir alarm üretmeden ortamda durmuş bir kayıttı, yalnızca özel bir sorguyla geriye dönük olarak yüzeye çıktı.
Bu tek bulgu, yazının tezini net bir şekilde doğruluyor: gürültü ayarlandığında bu sorgu hem düşük hacimli hem de gerçek sinyal taşıyabilen bir tespit yüzeyi sunuyor.
Tespit Yaklaşımı: Custom Detection Rule
Sorgu doğrulandıktan sonra MDE'de Custom Detection Rules > Create detection rule adımlarıyla kalıcı bir kurala çevirebilirsiniz:
Severity: High ve MITRE ATT&CK tarafında T1055 — Process Injection seçimi.- Detection name: Suspicious Cross-Process Thread Creation from Scripting Host (T1055)
- Rule query: yukarıdaki Advanced Hunting sorgusu (ortamınıza özgü bilinen-benign gürültü kaynaklarını
where not(...)ile hariç tutarak) - Frequency: Continuous (NRT)
- Severity: High
- Category: Defense Evasion / Privilege Escalation
- MITRE techniques: T1055 (Process Injection), T1055.001 (Dynamic-link Library Injection), T1055.012 (Process Hollowing)
Device, related evidence olarak InitiatingProcessId ve InitiatingProcessCommandLine.- Entity mapping: Impacted asset olarak Device (
DeviceId/DeviceName), ayrıcaInitiatingProcessIdüzerinden process
- Automated actions: İlk etapta bir aksiyon (izolasyon, dosya karantinası vb.) atamamanızı öneririz; önce bir gözlem periyodunda gürültü profilini kendi ortamınızda çıkarın, sonra aksiyon ekleyin
- Scope: All devices (veya kapsamınıza göre belirli cihaz grupları)
Microsoft Bu Konuyu Nasıl Ele Alıyor?
Microsoft'un process injection'a yaklaşımını en net gördüğümüz yer, Attack Surface Reduction (ASR) kural setinde: “Block Office applications from injecting code into other processes” kuralı, tam olarak burada test ettiğimiz deseni (bir sürecin başka bir sürece kod enjekte etmesi) hedefliyor ama kapsamı yalnızca Office uygulamalarıyla sınırlı. PowerShell, cmd.exe, wscript.exe gibi genel amaçlı script motorlarının aynı davranışı sergilemesine karşılık gelen, varsayılanda açık, genel bir ASR kuralı yok.
Bu, üreticinin felsefesiyle tutarlı: dar kapsamlı, yüksek-güven senaryolarda (Office belgesi → makro → injection zinciri, bilinen bir saldırı yolu) sıkılaştırma varsayılan olarak açılıyor; genel amaçlı script motorları için ise false-positive riski çok daha yüksek olduğundan karar müşteriye, custom detection rule üzerinden bırakılıyor.
Kapanış
vmtoolsd bulgumuz “imzalı ebeveyn = güvenli” varsayımının nasıl kırıldığını gösteriyordu. Bu yazı, aynı ürünün farklı bir varsayımını sorguluyor: “yeni bir process yoksa, tehdit yüzeyi de yok” değil; sadece görünürlük katmanı değişiyor. MDE, process injection'ı DeviceEvents içinde tam çözünürlükte kaydediyor, hatta bazı durumlarda tekniği isimlendiriyor bile (RemoteCreateThreadProcessHollowing); ama bunu varsayılan bir alarma çevirmiyor, çünkü aynı davranış sınıfının kurumsal ortamlarda çok sayıda meşru kaynağı var.
Gerçek ölçekte doğruladığımız gibi, doğru sınırlarla ayarlanmış bir Advanced Hunting sorgusu bu gürültüyü aşağı çekip gerçek sinyali yüzeye çıkarabiliyor. Custom detection rule'u yazıp yazmamak, burada da aynı soruya dönüyor: görünürlüğü bir karara çevirmek, önceden verilmiş bir tercih.
Selman Bilal Sivri — L2/L3 MDR Analyst, InfinitumIT
Bu yazı, gerçek bir Microsoft Defender for Endpoint ortamında yürütülen kontrollü test ve büyük ölçekli bir kurumsal ortamda gerçekleştirilen 30 günlük doğrulama sonuçlarına dayanmaktadır. Doğrulama sürecinde karşılaşılan gerçek olaya ait kurum, cihaz ve kullanıcı bilgileri gizlilik gereği paylaşılmamıştır.