MLE_RANSOM_BEHAVIOR
Fidye Yazılımı Tespit Kuralının Tam Anatomisi
OpenEDR × Hydra Dragon çekirdeği • PTM / PatternsMatching v2 politika motoru
Kural Kimliği: RANSOM_BEHAVIOR | Yayın Olay Tipi: MLE_RANSOM_BEHAVIOR | baseType: 1000008
Politika Kaynağı: OpenEDR/edrav2/iprj/edrdata/ptm.local.src • Satır 4636 – 5129
01 Künye
Aşağıdaki tablo, kuralın kimlik bilgilerini ve teknik parametrelerini tek yerde toplar. Bu değerlerin tamamı depodaki kaynak koddan birebir alınmıştır; hiçbiri tahmin değildir. Kaynak satırları ve dosya yolları her hücrede verilmiştir.
02 Bir Cümlede
Yeni veya imzası bilinmeyen bir fidye yazılımı, sisteme indirilip çalıştırıldığı andan itibaren derlenmiş kod imzasına bakılmadan tespit edilir. Çünkü kural, kodun ne yaptığına bakar:
- Kernel dosya sistemi süzgeci (minifilter), 60 saniye içinde 3 veya daha fazla ayrı kullanıcı dosyasına yazma / yeniden adlandırma / silme işlemi yapan bir süreci kayda geçirir.
- Politika motoru o dosyaların metin olmadığını (ilk 8 KiB'lık ASCII taramasıyla) ve şifreli veri gibi yüksek entropili olduğunu doğrular.
- Hedeflerin kullanıcı profilinde (
C:\Users\...) ve AppData / Temp / Windows / Program Files dışında olduğunu doğrular. - Tüm koşullar tutarsa
MLE_RANSOM_BEHAVIORolayı üretilir; motor sürecin imaj dosyasını karantinaya alır ve süreci Global ID ile öldürür. - Kernel'in RansomShield modülü daha önce kaydettiği özgün dosya kopyalarını geri yükler.
03 Neden Bu Kural Bir İmza Değil, Bir Davranış Kuralı?
Klasik antivirüs düşüncesi şöyledir: “Bu dosyayı daha önce gördüm, SHA-256'sı listede var, zararlı.” Bu yöntem iki yerde kırılır.
| Yaklaşım | Ne yapıyor | Kırılma noktası |
|---|---|---|
| Hash imzası | Dosyanın özetini sabit bir listede arar | Tek bir bayt değişse hash değişir. Atlatma: 1 saniye. |
| YARA / bayt imzası | İçerikte sabit dizi arar | Polimorfik kod, XOR şifreleme, UPX/Themida paketleme. Atlatma: dakikalar. |
| Paketleyici tanıma | Derleyicinin bıraktığı imzayı okur | Yeni sürüm derleyici imzayı değiştirir. Atlatma: tek güncelleme. |
| Yapay zekâ destekli statik ML | PE başlıklarından sapma skorlar | İyi yazılmış zararlı, meşru PE başlığını taklit eder. Zayıf ayrım. |
| MLE_RANSOM_BEHAVIOR | Dosya sistemi I/O akışını izler, şifreleme işlemini kendi hâlinde tanır | Kod değişse de davranış değişmez. Şifreleme zorunlu bir adımdır. |
04 Uçtan Uca Mimari: Olayın Yolculuğu
Kuralın arkasında sekiz ayrı katman var. Olayın yolculuğunu baştan sona izleyelim.
Kritik ayrım şudur: destination: "IN" olayı motorun icine tutar
(bu bir tespit değil, bir durum makinesi adımıdır); destination: "OUT" ise
olayı motor dışına, zenginleştirme ve yanıt zincirine çıkarır.
MLE_RANSOM_BEHAVIOR OUT ile yayılır — yani gerçek
bir tespittir.
IN olayları aynı kuyruğa geri beslenir; böylece politika dosyası
olay üretip kendi kuralına geri göndererek çok aşamalı bir durum makinesi
kurabilir. Bu, tek bir dosya işlemi üzerinde “oku → yaz → say → karar ver”
zinciri kurmanın en temiz yoludur ve tam olarak MLE_RANSOM_BEHAVIOR'ın mimarisidir.
05 Altyapı: PTM (PatternsMatching) Motoru
Kural, JSON tabanlı bir politika dilinde tanımlıdır. Derlendiğinde ürüne gömülür ve
denetlenebilir kalır — yani bu sayfadaki her satır, üründe çalışan
gerçek kodun satırıdır. Motor C++ ile yazılmıştır
(libedr/src/policy_v2.cpp, policycompiler.cpp,
policyoperation.cpp, signcontext.cpp).
5.1 — Yönergeler (Directives)
Her kural maddesi, bir "rule" sözlüğü içinde yönergelerden oluşur:
| Yönerge | Ne yapar | Bu Kuralda Nerede |
|---|---|---|
condition |
Filtre. Sağlanmazsa kural her zaman eşleşir. | Aşama 1a/1b ve aşama 5'te yok; aday üretimi ve karar kurallarında var |
saveContext |
Sepet (basket) içine anahtar + veri + yaşam süresi (ms) ile kayıt yazar. |
Aşama 1a, 1b — RANSOM_FILE_READ_WRITE sepeti |
loadContext |
Sepetten okur. @context.* kullanımı bunu zorunlu kılar. |
Bu kuralda kullanılmıyor (bkz. Bölüm 16) |
deleteContext |
Sepetten anahtar veya grup siler. | Aşama 5 — süreç sonlandığında |
createEvent |
Yeni olay üretir. destination: IN / OUT / IN_OUT. clone:false ise yalnızca data'daki alanlar taşınır. |
Aşama 2, 3 ve 4 — kuralın kalbi |
distinctCounter |
Kayan pencerede ayrı değer sayar, eşik aşılınca flag alanına boolean yazar. |
Aşama 4 — ransomFileDistinct sepeti |
discard |
Olayı düşürür. | Kullanılmıyor |
conditioncondition anahtarı olabilir.
Motor yönergeleri bir unordered_map<Directive, DirectivePtr> içinde tutar;
ikinci bir condition yazılırsa ilk sessizce düşer. Bu yüzden aşama 4'teki
dokuz süzgecin tamamı tek bir "and" zincirinde birleştirilmiştir.
Bu, kuralın yazılış biçiminin bir kısıtından doğan bilinçli bir tasarım kararıdır ve
ptm.local.src içinde de açıkça belgelenmiştir.
5.2 — Operasyonlar ve Değerlendirme Semantiği
| Operasyon | Arity | Anlamı | Bu Kuralda |
|---|---|---|---|
imatch | 1 değer + pattern | Büyük/küçük harf duyarsız joker eşlemesi | *\users\* vb. |
!imatch | 1 değer + pattern | Eşleşmezse true | Beyaz liste kontrolleri |
and / or | ≥ 2 | Mantıksal birleştirme (kısa devre yok, hepsi değerlendirilir) | Süzgeç zinciri |
equal / !equal | tam 2 | Tip bazlı eşitlik | type == "OTHER", isAsciiText |
greater | tam 2 | Tam sayı karşılaştırma; null/bool/string → 0 sayılır | Entropi eşiği |
5.3 — Joker (Wildcard) Eşleme Semantiği
imatch operatörü joker kalıpları iki ayrı motora dağıtır ve
bu seçim performansı doğrudan etkiler:
| Kalıp Biçimi | Derlenen Motor | Anlam |
|---|---|---|
*\Windows\* |
StringMatcher, mod all |
“içinde \Windows\ geçiyor” — hızlı yol, regex yok |
*.docx |
StringMatcher, mod end |
“sonu .docx ile bitiyor” — 1479 uzantı bu yolda |
C:\Windows\explorer.exe |
StringMatcher, mod begin |
“ile başlıyor” (yani .exe.bak de eşleşir) |
*\*.*.* |
POSIX regex (temel) | Ortada joker varsa regex yoluna düşer; *→.*, ?→. |
* karakterleri birer “regex jokeri” değildir;
bunlar çapa (anchor) görevi görür ve begin / end /
all modlarına dönüştürülür. 1479 uzantılık liste bu yüzden regex derlenmeden,
tek bir StringMatcher tablosu olarak çalışır — bu, canlı sistemde
onlarca mikrosaniyelik maliyet demektir.
06 Kuralın Anatomisi: 16 Madde, 5 Aşama
RANSOM_BEHAVIOR deseni 16 kural maddesinden oluşur. Bu maddeler beş mantıksal
aşama hâlinde gruplanır. Aşağıda her aşama, ilgili kaynak kodla birlikte açıklanmıştır.
saveContext
İki kural maddesi, sistem dışı bir dosyanın tam olarak okunduğunu kayda geçirir. Amaç “bu süreç şu dosyayı okudu” bilgisini 120 saniye boyunca saklamaktır. Bu, ileride “okuyan → yazan” eşleşmesi kurulabilmesi için temeldir (bkz. Bölüm 16, madde 3: bu sepet şu an yalnızca yazılır, okunmaz).
Madde 1a — LLE_FILE_DATA_READ_FULL
Dosya, eksiksiz ve sıralı biçimde baştan sona okunduğunda üretilen kernel
olayını yakalar. Minifilter bunu ancak readInfo.nNextPos == nSizeAtCreation
koşulu sağlandığında yapar — yani kısmi okumalar sayılmaz.
{
"eventType": "LLE_FILE_DATA_READ_FULL",
"rule": {
"condition": {
"$operation": "!imatch",
"pattern": "@const.ransomSystemExclusions",
"args": [ "@event.file.path" ]
},
"saveContext": {
"basket": "@const.ransomBasket.readWrite", // "RANSOM_FILE_READ_WRITE"
"key": "@event.file.path",
"lifetime": 120000, // 120 saniye (ms)
"data": { "file": "@event.file" }
}
}
}
Madde 1b — LLE_FILE_MAP_READ (bellek eşleme ile okuma)
Aynı iş, haritalama (mmap) yoluyla yapılıyorsa. Birçok modern fidye yazılımı
dosyayı CreateFile + ReadFile ile değil,
NtCreateSection + NtMapViewOfSection ile belleğe eşler. Bu yol
hiç IRP_MJ_READ göndermez; dolayısıyla yukarıdaki madde 1a
onu yakalayamaz. Minifilter bu yüzden
IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION IRP'sinin
PAGE_READONLY sayfa korumasını ayrı bir olaya çevirir.
LLE_FILE_MAP_READ ve LLE_FILE_MAP_WRITE maddeleri olmasaydı,
haritalama tabanlı şifreleyiciler — Rust/Go/C++ ile yazılmış modern fidye
yazılımlarının büyük bölümü — tamamen görünmez olurdu. İki satır,
kuralı “okuma yapan herkesi yakalar” seviyesine taşıyan asıl teknik karardır.
MLE_RANSOM_CANDIDATE
On maddelik bu blok, motorun kalbidir. Sistem dışı bir dosya üzerinde
her türlü yazma, değiştirme, yeniden adlandırma veya silme eylemi
MLE_RANSOM_CANDIDATE olayına dönüştürülür. Burada hiçbir karar
verilmez; sadece olay kayda geçer.
destination: "IN" olduğu için bu olay motorun içinde kalır ve aşama 3'te
tekrar işlenmek üzere match_patterns kuyruğuna geri beslenir.
| Madde | Kaynak Olay | Ne Zaman Üretilir (Kernel) | Not |
|---|---|---|---|
| 2a | LLE_FILE_CREATE |
IRP_MJ_CREATE sonrası — dosya oluşturuldu veya kırpıldı |
Yeni şifreli dosya oluşturan modelin ilk adımı |
| 2b | LLE_FILE_DATA_WRITE_FULL |
IRP_MJ_CLEANUP sonrası — dosya baştan sona yazıldı |
Entropi yalnızca bu olayda ölçülür |
| 2c | LLE_FILE_MAP_WRITE |
ACQUIRE_FOR_SECTION_SYNC — PAGE_READWRITE / WRITECOPY / EXECUTE_READWRITE |
mmap tabanlı şifreleme |
| 2d | LLE_FILE_DATA_CHANGE |
IRP_MJ_CLEANUP — tutamaç dosyayı kirletmiş |
Kaba “dosya değişti” bayrağı |
| 2e | RF10* |
— | Derlemede düşer (Bölüm 16) |
| 2f | LLE_FILE_RENAME |
IRP_MJ_SET_INFORMATION — FileRenameInformation(Ex) |
.docx → .docx.locked hamleleri |
| 2g | LLE_FILE_DELETE |
IRP_MJ_CLEANUP — silme bayrağı ya da FileDispositionInformation |
Özgün dosyayı silip şifreli kopyayı bırakma |
| 2h | RF4* |
— | Derlemede düşer (Bölüm 16) |
| 2f′ | LLE_FILE_RENAME |
2f'in birebir kopyası — fazlalık (Bölüm 16) | |
| 2g′ | LLE_FILE_DELETE |
2g'nin birebir kopyası — fazlalık (Bölüm 16) | |
| 2h′ | RF4* |
2h'nin birebir kopyası — fazlalık | |
Sekiz gerçek madde (2a–2g) aynı kalıbı paylaşır. Tamamı aşağıdaki yapıdadır — madde 2b örneği:
{
"eventType": "LLE_FILE_DATA_WRITE_FULL",
"rule": {
"condition": {
"$operation": "!imatch",
"pattern": "@const.ransomSystemExclusions",
"args": [ "@event.file.path" ]
},
"createEvent": {
"eventType": "MLE_RANSOM_CANDIDATE",
"destination": "IN", // motorun içinde kalır
"clone": false,
"data": [
{ "name": "baseType", "value": "@const.ransomBehaviorEventBaseType.MLE_RANSOM_BEHAVIOR" },
{ "name": "process", "value": "@event.process" },
{ "name": "processes", "value": "@event.processes" },
{ "name": "destination", "value": "@event.file" },
{ "name": "time", "value": "@event.time" },
{ "name": "tickTime", "value": "@event.tickTime" },
{ "name": "quarantineTarget", "value": "@event.file.path" }
]
}
}
}
clone: false neden her yerde var?clone: true olsaydı, tetikleyen olayın tüm alanları
yeni olaya otomatik kopyalanırdı. clone: false ile motor yalnızca
data dizisinde elle listelenen alanları taşır. Bu, zincirin
her adımında hangi alanın bilinçli olarak taşındığını (ve hangisinin bilinçli
olarak taşınmadığını) görünür kılar — yani politikanın okunabilirliği ve
denetlenebilirliği kazanılır.
MLE_RANSOM_EVALUATE
MLE_RANSOM_CANDIDATE olayını alan motor, onu
MLE_RANSOM_EVALUATE olayına dönüştürür. Bu tek maddelik kural,
kararın kendisinden ayrılmış saf bir adım olarak tasarlanmıştır ve
üç şey yapar:
- Etiket değişikliği: artık bu olay “bir dosyaya dokunuldu” değil, “şüpheli dosya”dır.
- Alan normalizasyonu:
destinationalanı, aşama 2'de@event.fileiken burada@event.destinationolarak okunur — yani önceki olayın taşıdığı alan. - Zaman damgası taşıma:
timevetickTimekorunur, böylece sayaç ve analiz zaman çizelgesi doğru kalır.
{
"eventType": "MLE_RANSOM_CANDIDATE",
"rule": {
"createEvent": {
"eventType": "MLE_RANSOM_EVALUATE",
"destination": "IN",
"clone": false,
"data": [
{ "name": "baseType", "value": "@const.ransomBehaviorEventBaseType.MLE_RANSOM_BEHAVIOR" },
{ "name": "process", "value": "@event.process" },
{ "name": "processes", "value": "@event.processes" },
{ "name": "destination", "value": "@event.destination" },
{ "name": "source", "value": "@event.source" },
{ "name": "time", "value": "@event.time" },
{ "name": "tickTime", "value": "@event.tickTime" }
]
}
}
}
distinctCounter + Dokuz Süzgeç → MLE_RANSOM_BEHAVIOR
Kuralın kalbi. Burada iki şey aynı anda olur:
distinctCounterçalışır: süreç kimliği (PID) başına, son 60 saniyede kaç ayrı hedef dosyaya dokunulduğu sayılır. 3'e ulaşınca@event.RansomThresholdMet = trueyazılır.conditionçalışır: dokuz süzgecin tamamı tutmalıdır. Tutan tutarsa nihai tespit olayıOUTile dışarı çıkar.
distinctCounter → condition.
Yani her MLE_RANSOM_EVALUATE sayacı besler — koşul daha
sonra değerlendirilir. Bunun pratik sonucu Bölüm 16'da ayrıntılı olarak ele alınmıştır;
şimdilik şunu bilin: sayaç “potansiyel aday” sayar, kesin şüpheliyi değil.
"createEvent": {
"eventType": "MLE_RANSOM_BEHAVIOR",
"destination": "OUT", // TESPİT ÇIKIŞI: motoru terk eder
"clone": false,
"data": [
{ "name": "baseType", "value": "@const.ransomBehaviorEventBaseType.MLE_RANSOM_BEHAVIOR" },
{ "name": "process", "value": "@event.process" },
{ "name": "processes", "value": "@event.processes" },
{ "name": "destination", "value": "@event.destination" },
{ "name": "time", "value": "@event.time" },
{ "name": "tickTime", "value": "@event.tickTime" },
{ "name": "quarantineTarget", "value": "@event.process.imageFile.rawPath" },
{ "name": "should_trust_company_whitelist", "value": true },
{ "name": "should_trust_comodo_fls_cloud", "value": true }
]
}
quarantineTargetquarantineTarget şifrelenen dosyayı işaret
ederdi. Nihai tespitte ise @event.process.imageFile.rawPath — yani
saldırganın kendi çalıştırılabilir dosyasının yolu — atanır.
Bu, tüm kuralın en önemli mimari kararıdır: mağdur olan dosya değil, suç işleyen sürektir. Karantina, fidye yazılımının ikili dosyasına uygulanır; kullanıcının verisi
RansomShield tarafından geri yüklenir.
deleteContext
Süreç sonlandığında (LLE_PROCESS_DELETE) okuma sepeti temizlenmeye çalışılır.
Bu, uzun süre çalışan bir makinede belleğin şişmesini önleyen hijyen maddesidir.
{
"eventType": "LLE_PROCESS_DELETE",
"rule": {
"deleteContext": {
"basket": "@const.ransomBasket.readWrite",
"group": "@event.process.id"
}
}
}
group alanı olmadan yazılırken, aşama 5
group ile silmeyi dener. Motor bu eşleşmeyi kuramadığı için temizlik
pratikte 120 saniyelik TTL üzerinden gerçekleşir. Bu, işlevsel bir
sorun değildir; kuralı etkilemez, yalnızca kaydın yaşam süresi belirleyicidir.
Ayrıntı Bölüm 16'da.
07 Dokuz Süzgeç, Tek Tek
Aşama 4'ün condition alanı, tek bir "and" zincirinde
birleştirilmiş dokuz bağımsız filtredir. Kural tetiklenmesi için hepsinin
aynı anda tutması gerekir. Bu, varsayılan olarak kapalı (fail-safe) bir
tasarımdır: yanlış pozitif değil, kaçırılan tespit üzerine kuruludur.
"rule": {
"distinctCounter": {
"basket": "ransomFileDistinct",
"key": "@event.process.pid", // HER SÜREÇ AYRI SAYILIR
"values": [ "@event.destination.path" ], // sayılan değer
"threshold": 3,
"window": 60000,
"flag": "@event.RansomThresholdMet"
},
"condition": {
"$operation": "and",
"args": [
// [1] AKTÖR beyaz listede mi?
{ "$operation": "!imatch", "pattern": "@const.ransomSystemExclusions",
"args": [ "@event.process.imageFile.rawPath" ] },
// [2] HEDEF beyaz listede mi?
{ "$operation": "!imatch", "pattern": "@const.ransomSystemExclusions",
"args": [ "@event.destination.path" ] },
// [3] HEDEF kullanıcının kendi verisi mi? (zorunlu +)
{ "$operation": "imatch", "pattern": "*\\users\\*",
"args": [ "@event.destination.path" ] },
// [4] AppData hariç mi? (tarayıcı / cache FP koruması)
{ "$operation": "!imatch", "pattern": "*\\appdata\\*",
"args": [ "@event.destination.path" ] },
// [5] MOTW ADS değil mi? (indirilen dosya / FP koruması)
{ "$operation": "!imatch", "pattern": "*:Zone.Identifier*",
"args": [ "@event.destination.path" ] },
// [6] Hedef çalıştırılabilir bir dosya değil mi?
{ "$operation": "equal", "args": [ "@event.destination.type", "OTHER" ] },
// [7] UZANTILI dosya AND KULLANICI UZANTISI AND ENTROPİ
{ "$operation": "and", "args": [
{ "$operation": "or", "args": [
{ "$operation": "imatch", "pattern": "*\\*.*.*", "args": [ "@event.destination.path" ] },
{ "$operation": "imatch", "pattern": "*\\*.*.*", "args": [ "@event.source.path" ] } ] },
{ "$operation": "or", "args": [
{ "$operation": "imatch", "pattern": "@const.ransomFileExtensions", "args": [ "@event.destination.path" ] },
{ "$operation": "imatch", "pattern": "@const.ransomFileExtensions", "args": [ "@event.source.path" ] } ] },
{ "$operation": "or", "args": [
{ "$operation": "greater", "args": [ "@event.destination.owlyEntropy", 6 ] },
{ "$operation": "greater", "args": [ "@event.destination.entropy", 6 ] },
{ "$operation": "greater", "args": [ "@event.owlyEntropy", 6 ] },
{ "$operation": "greater", "args": [ "@event.entropy", 6 ] } ] }
] },
// [8] Hedef METİN DOSYASI DEĞİL mi? (asıl metin koruması)
{ "$operation": "!equal", "args": [ "@event.destination.isAsciiText", true ] },
// [9] HACİM eşiği aşıldı mı? (60 sn içinde 3+ AYRI hedef)
{ "$operation": "equal", "args": [ "@event.RansomThresholdMet", true ] }
]
}
}
C:\Windows\,
C:\Program Files\ altından çalışan meşru araçlar (güncelleyiciler, kurulum
sihirbazları, antivirüs motorları) bu süzgeçle elenir.
Neden aktör kontrolü? Bir kurulum sihirbazı
C:\Users\alice\Desktop altına da yazabilir; ama
C:\Windows\Temp\ içindeki bir setup.exe onlarca kullanıcı
dosyasına yazmaz. Aktörü elemek, hedefe bakmaktan çok daha güvenilir
bir yanlış pozitif kesicidir.
C:\Users\alice\Documents,
Desktop, Downloads, Photos gibi kişisel veri
yığınları. C:\Windows veya ağ sürücülerini şifreleyen bir araç
kural tarafından hedeflenmez. Bu tek koşul, kurumsal masaüstünde yanlış
pozitif oranını dramatik biçimde düşürür.
Not: Bu kalıp
StringMatcher “içinde geçiyor”
modunda derlenir. Kurulum adı her zaman İngilizce kalır (\Users\), bu yüzden
yerelleştirilmiş Windows kurulumlarında da çalışır.
AppData içinde Chrome, Firefox,
VS Code, Steam, Discord gibi yüzlerce uygulama sürekli olarak onlarca
dosyaya yazar. Bunlar “çok sayıda dosyaya yazan meşru süreçler”dir ve
kullanıcının asıl değerli verisi burada değildir. Bu süzgeç, en gürültülü
yanlış pozitif kaynağını kapatır.
Çelişki notu: S3
\users\ içinde \AppData\'yu
arar; S2 zaten *\AppData\* kalıbını içerir. Dolayısıyla S4, S2 ile
birebir aynı kontrolü yapar ve bugün itibarıyla ek bir filtre
değildir — savunma derinliği ve okunabilirlik için bilinçli olarak
tekrarlanmıştır.
Zone.Identifier, “bu dosya internetten indirildi” işaretidir.
Marka yöntemi (Mark of the Web) saldırıları tam olarak bu akışı kullanır:
indirilen bir dosyanın MOTW akışına dokunarak kurumsal dosyaları “internet kökenli”
hâle getirir ve kullanıcıyı uyarıyla kandırır. Bu süzgeç, bu tür teknikleri kuralın
kapsamı dışına iter.
.exe;.dll;.sys;.cpl;.mui;.tlb;.scr) girip
girmemesine göre belirlenir. Kural yalnızca "OTHER" hedefleri kabul eder,
yani belge, tablo, görsel, video, arşiv, kaynak kodu ve veritabanı.
Neden önemli? Bir zararlının kendi ikili dosyasını değiştirmesi (kalıcılık kazanmak için) bu kuralı tetiklemez — bu tür eylemler
MLE_PUA_REGISTRY_WRITE ve MLE_FILE_COPY gibi komşu kuralların
alanıdır. Kuralın tek bir amacı vardır: kullanıcı verisini imha etmek.
Tek amaç, düşük yanlış pozitif demektir.
Pratik sonuç:
C:\Users\alice\Notes.txt dosyasına düz metin
yazan bir metin editörü elenir (7b: .txt listede, ama 8. süzgeç
isAsciiText=true → elenir). Aynı dosyayı şifreleyen fidye yazılımı
geçer.
\t \n \r ve 0x20-0x7E dışındaki
baytların sayısı 8 KiB × %15 + 1 = 1229 eşiğine ulaşırsa dosya
“metin değildir” olarak işaretlenir (fail-fast).
Neyi okur, ne zaman okur? Alan, kuralın değerlendirildiği andaki diskteki güncel içeriği okur — yani saldırganın az önce yazdığı ciphertext. Uzantıya, dosya adına veya “şüpheli dosya” etiketine bakmaz. Aşama 4 çoğunlukla
LLE_FILE_DATA_WRITE_FULL üzerinde
çalıştığı için dosya bu anda şifrelenmiş hâldedir ve tarama şifre metnini
görür. Aynı süzgeç, metin editörünün aynı dosyaya yazdığı düz metni ise eler.
Ölçüm penceresi: 8 KiB, eşik %15 + 1, fail-fast. Uygulama 64 KiB'a kadar tek seferde okur, ancak analiz yalnızca ilk 8192 bayt üzerinde yapılır ve eşik dolur doldurulmaz — daha fazla bayt okunmaz:
// Content-based ASCII-text check. Exact C++ port of: // fn looks_like_ascii_text(data: &[u8]) -> bool // Empty input -> false. Samples at most the first 8192 bytes, fail-fast once // the non-printable count reaches 15% + 1. Printable set: \t \n \r 0x20..=0x7E. bool FileDataProvider::is_look_like_ascii_text(const uint8_t* data, size_t len) { if (data == nullptr || len == 0) return false; const size_t sampleLen = len < 8192 ? len : 8192; // <-- ANALİZ PENCERESİ 8 KiB const size_t threshold = sampleLen * 15 / 100 + 1; // 8192'de = 1229 bayt size_t nonPrintable = 0; for (size_t i = 0; i < sampleLen; ++i) { const uint8_t b = data[i]; const bool printable = (b == '\t' || b == '\n' || b == '\r' || (b >= 0x20 && b <= 0x7E)); if (!printable && ++nonPrintable >= threshold) return false; // <-- FAIL-FAST } return true; }
isAsciiTextFile() → dosya nesnesinde deleted işareti varsa
disk hiç okunmadan false → getFileStream() ile
dosya Read | ShareRead | ShareWrite modunda açılır (gerekirse süreç token'ı ile
impersonation denenerek ikinci kez açılır) → 64 KiB'a kadar
offset 0'dan tek seferde okunur → okunan bayt 0 ise false →
yukarıdaki 8 KiB'lık analiz.
ShareWrite bayrağı sayesinde dosya, saldırganın o anda açık
yazma tutamaçlarıyla birlikte okunabilir — yani şifreleme sürerken dosya
kilitli değildir ve tarama yine içeriği görür.
Neden 8 KiB yeterli? Bir düz metin dosyasının ilk 8 KiB'i zaten yazdırılabilir karakterlerden oluşur; şifre metninde ise 1229 bayta ulaşmak (~15%) rastgele dağılımda neredeyse garanti edilir. Bu, maliyeti 64 KiB tarama yerine 8 KiB + fail-fast'e indirir.
Neden bu kadar belirleyici? Bir JPEG, bir MP4, bir
.docx
(ZIP), bir .xlsx, bir veritabanı dosyası — hepsi metin gibi
görünür ama asla metin değildir. Kural yalnızca açıkça metin olan
dosyaları eler. Bu, “şifreleme yapmış gibi görünen ama aslında sıkıştırılmış bir
klasör kopyalama işlemi” ile “gerçek şifreleme” arasındaki ayrımı kurar.
Fail-closed davranışı: dosya silinmiş, açılamıyor ya da 0 bayt okunduysa sonuç
false— yani “metin değil”— döner. Kural, kanıt
toplayamazsa sert davranır ve dosyayı elmez. Bu bilinçli bir tercihtir:
yanlış negatif (kaçırılan gerçek şifreleme) maliyeti, yanlış pozitif (kullanıcının
meşru dosyasının karantinaya alınması) maliyetinden daha yüksektir.
Tetikleyiciye göre ince ayrıntı:
LLE_FILE_CREATE üzerinde
dosya henüz boş olduğundan 0 bayt okunur ve süzgeç geçer;
LLE_FILE_RENAME / LLE_FILE_DELETE üzerinde ise içerik
o âna kadarki hâlidir — henüz şifrelenmemiş bir dosyada süzgeç eleyebilir
(LLE_FILE_DELETE'de ayrıca deleted işareti okuma yapmadan
false döndürür). Kuralın asıl tetikleyicisi LLE_FILE_DATA_WRITE_FULL
olduğu için bu, normal şifreleme akışında bir sorun yaratmaz.
08 distinctCounter: Kayan Pencerede Ayrı Değer Sayacı
distinctCounter, motorun en özgün yönergesidir. Basit bir sayaç değildir:
aynı değerin tekrarı sayıya katkı yapmaz. Bu küçük ama kritik ayrım,
kuralın neden “3 dosya” dediğini açar.
"distinctCounter": {
"basket": "ransomFileDistinct", // ayrı sayaç alanı (konteyner)
"key": "@event.process.pid", // HER SÜREÇ AYRI SAYILIR
"values": [ "@event.destination.path" ], // sayılan değer: HEDEF YOLU
"threshold": 3, // 3 AYRI hedef
"window": 60000, // 60 saniye kayan pencere
"flag": "@event.RansomThresholdMet" // sonuç buraya yazılır
}
8.1 — Semantik: ne sayıyor, ne saymıyor?
| Özellik | Davranış | Fidye Yazılımı Açısından Anlamı |
|---|---|---|
| Sayılan | Aynı anahtar içinde birerinden FARKLI, boş olmayan değerler | “Kaç farklı dosyaya dokundu?” — doğru soru |
| Sayılmayan | Aynı dosyaya tekrar tekrar yazılması | Yedekleme aracının 500 kez aynı dosyayı yazması → sayaç = 1, eşik geçilmez ✓ |
| Anahtar | @event.process.pid — PID bazlı |
Süreç izolasyonu: iki farklı zararlı birbirinin sayacını dolduramaz; bir yedekleme aracı sayacı kirletemez |
| Pencere | 60000 ms; her çağrıda süresi dolan kayıtlar seyrek olarak temizlenir | Yavaş, dağınık şifreleme (her 40 saniyede 1 dosya) eşiği geçmez — bilinçli trade-off |
| Bayrak | Size >= threshold olduğu sürece true — kenar değil, seviye (latching) |
Pencere dolmadan tespit devam eder; her yeni dosya yeniden tetikler |
| Temizlik | Açık bir sıfırlama yolu yoktur; yalnızca pencere süresi dolar | Bkz. Bölüm 16 — kasıtlı veya kasıtsız bir sonuç |
8.2 — Somut Senaryo
60 saniyelik pencere, “sık kullanıcı eylemi” ile “makine hızıyla yapılan toplu işlem” arasındaki makul zaman farkını yakalar. Bir insan 60 saniyede 3 belgeyi şifrelemez; bir fidye yazılımı saniyeler içinde yüzlerce yapar.
Ticari bir taviz: “yavaş sürünen”, dosya başına birkaç dakika bekleyen sofistike şifreleyiciler bu pencereyi aşabilir. Bunu yakalayan başka bir kural değil, kombine edilmiş zamansal davranış olacaktır. Bu, kuralın bilinen ve dürüstçe belgelenmiş sınırıdır.
09 Dosya Nesnesi: Hangi Alana Bakılıyor?
Kuralın @event.destination.* ve @event.file.* ifadeleri,
sürücüden gelen ham bir yol değil, zenginleştirilmiş bir dosya nesnesinin
alanlarına işaret eder. Bu nesne tembel (lazy) üretilir: bir alan
gerçekten okunmadıkça diskte de okunmaz.
| Alan | Kaynağı | Kuralda Kullanımı |
|---|---|---|
path |
Normalize edilmiş, insan tarafından okunabilir yol | S1, S2, S3, S4, S5, S7, S9 — yolun kendisi |
type |
Uzantı yapılandırılmış çalıştırılabilir listesinde mi? (EXECUTABLE / OTHER) |
S6 — == "OTHER" |
isAsciiText |
Diskten 64 KiB okunur (offset 0, ShareRead|ShareWrite, gerekirse impersonation ile); metin analizi yalnızca ilk 8 KiB (8192 bayt) üzerinde yapılır, eşik %15+1 (8 KiB'de 1229 bayt), fail-fast. Okuma anı: kuralın değerlendirildiği andaki güncel içerik — yani şifrelendiyse ciphertext. |
S8 — != true |
size |
Tembel dosya boyutu | Doğrudan kullanılmıyor (kernel zaten tam-okuma / tam-yazma eşiğini uygular) |
rawHash |
Okuma/yazma dizisi boyunca xxh64 | Bu kuralda doğrudan kullanılmıyor; MLE_FILE_COPY kuralında kullanılır |
renameTarget |
Yalnızca yeniden adlandırma olaylarında yeni ad | Yok — aday olaya taşınmıyor |
volume |
{guid, type, device} — sabit / çıkarılabilir / ağ | Bu kuralda yok (USB kurallarında kullanılır) |
owlyEntropy |
Olay kök alanı — yalnızca tam yazma olayında | S7c |
isAsciiText her değerlendirmede diskten okuma demektir. Sistem bunu
tembel bir vekil nesne (lambda proxy) olarak kurar: kural o alana
gerçekten dokunmadıkça hiçbir bayt okunmaz. 10 kernel tetikleyicisinden
hiçbiri bu alanı okumuyorsa, tek bir bayt harcanmaz.
Dokunulduğunda ise iş çift katmanlı olarak ucuzdur: 64 KiB'lık I/O tek çağrıda yapılır, ama analiz ilk 8 KiB'de fail-fast tamamlanır. Yani tipik şifre metninde karar yaklaşık 1229 bayt okunduktan sonra verilir — kalan 63 KiB hiç taranmaz. Bu, bir EDR'ın canlı sistemde kullanılabilir olmasının temelidir.
10 Shannon Entropisi: Q24 Sabit Nokta ile Hesaplama
Entropi, verinin ne kadar “rastgele” olduğunun ölçüsüdür. Şifreli veri (AES, ChaCha) teorik maksimuma, yani 8 bit/byte'a yakın değerdir. Düz metin ise 3,5–5 bandındadır. Bu fark, “şifreli mi?” sorusunu sayısal bir ölçüte çevirir.
10.1 — Algoritma
// ENTROPY_ONE_Q24 = 2^24. Aralık: [0, 8 * ENTROPY_ONE_Q24] // Float'a çevirmek için: (double)sonuç / (double)ENTROPY_ONE_Q24 constexpr ULONGLONG ENTROPY_ONE_Q24 = 1ULL << 24; ULONGLONG shannonEntropyQ24(PUCHAR buffer, size_t size) { if (!buffer || size == 0) return 0; // 256 kovalı bayt histogramı ULONGLONG bkt[256] = {}; for (size_t i = 0; i < size; i++) bkt[buffer[i]]++; ULONGLONG slQ24 = OwlyLog2Q24((ULONGLONG)size); // log2(N) ULONGLONG wsum = 0; for (ULONG i = 0; i < 256; i++) if (bkt[i]) wsum += bkt[i] * OwlyLog2Q24(bkt[i]); ULONGLONG avg = wsum / (ULONGLONG)size; // (1/N) * SUM n_i*log2(n_i) ULONGLONG eQ24 = (slQ24 > avg) ? (slQ24 - avg) : 0; // H = log2(N) - (1/N)*SUM(...) if (eQ24 > c_EntMaxQ24) eQ24 = c_EntMaxQ24; // 8 ile sınırla return eQ24; }
10.2 — Neden Q24 sabit nokta?
Bu yüzden
log2 fonksiyonu atanh serisiyle tam sayı
aritmetiğinde yeniden yazılmıştır (/3, /5, /7, /9, /11, /13 terimleri),
24 kesirli bit (Q24) kullanılır ve sonuç sert biçimde
8 × 2^24 değerine kırpılır. Hassasiyet yaklaşık
6×10^-8 bit/byte'dır — bu, karar eşiği olan “6” için
fazlasıyla yeterlidir.
10.3 — Nerede ve nasıl örneklenir?
| Özellik | Değer |
|---|---|
| Örnekleme yeri | Yalnızca yazma işlemi (pre/post write, her MDL sayfası ve her doğrudan tampon) |
| Özetleme | Dizideki maksimum parça entropisi |
| Yayın | Yalnızca LLE_FILE_DATA_WRITE_FULL olayında (owlyEntropy + owlyIsEntropyCalc=1) |
| Tip | uint64 Q24 sabit nokta — ham değer, ölçeklenmemiş |
| Doğruluk notu | Seri 6 terimde kesildiği ve mantis kesildiği için IEEE kesin değildir; pratik aralıklarda birkaç ULP sapma |
10.4 — Tipik değerler
| İçerik | Teorik H (bit/byte) | Q24 Ham Değer | Kuralda Sonuç |
|---|---|---|---|
| Tamamen sabit (sıfırlar) | 0,0 | 0 | ELE |
İngilizce metin, kaynak kodu, .txt/.js/.html/.json | 3,5 – 5,0 | 58.720.256 – 83.886.080 | S8 ile elenir |
| Derlenmiş PE (kod + veri karışımı) | 6,0 – 7,2 | 100.663.296 – 120.795.955 | GEÇER |
Sıkıştırılmış arşiv (.zip/.7z/.zst) | 7,9 – 8,0 | ≈132.120.000 – 134.217.728 | GEÇER |
| Taze AES/ChaCha şifre metni | 7,9 – 8,0 | ≈132.120.000 – 134.217.728 | GEÇER |
6 ile karşılaştırır — yani
ham Q24 ile karşılaştırır. Bu, “3,6×10^-7
bit/byte'den büyükse geç” anlamına gelir; yani pratikte “bu olay bir tam yazma
olayı mıydı?” sorusuna dönüşür.
Ölçekleme
filemon.cpp yorumunda (“Rust tarafı 1<<24 ile böler”)
belirtilmiştir ve bu, OwlyShield Rust tüketicisi için geçerlidir;
PTM/C++ yolunda ölçekleme yapılmaz. Sonuç olarak gerçekten çalışan entropi
ayrımı 8. süzgeçtir (isAsciiText), 7c bloğu ise “tam yazma
olayı mıydı” filtresi olarak işlev görür. Ayrıntı ve önerilen düzeltme:
Bölüm 16.
11 Beyaz Liste ve Uzantı Gözcüsü
11.1 — Sistem İstisnaları (8 kayıt)
Bu liste, kuralın en sıkı çalışan iki süzgecini besler (S1 ve S2). Yorum satırı kaynakta açıkça belirtilmiştir: “System and browser cache paths excluded from ransomware tripping (FP reduction)” — yanlış pozitif azaltma amacıyla sistem ve tarayıcı önbellek yolları hariç tutuldu.
// System and browser cache paths excluded from ransomware tripping (FP reduction) "ransomSystemExclusions": [ "*\\Windows\\*", // mod "all" <-- içinde \Windows\ "C:\\Windows\\explorer.exe", // mod "begin" <-- İLE BAŞLIYOR "*\\Program Files\\*", // mod "all" "*\\Program Files (x86)\\*", // mod "all" "*\\ProgramData\\*", // mod "all" "*\\AppData\\*", // mod "all" (harf duyarsız) "*\\Temp\\*", // mod "all" "*:Zone.Identifier*" // mod "all" <-- NTFS ADS ],
C:\Windows\explorer.exe satırının ince ayrıntısıbegin) eşlemesine dönüşür.
Yani C:\Windows\explorer.exe ile başlayan her yol eşleşir
— C:\Windows\explorer.exe.bak gibi. Bu, bilinçli bir genişliktir: kurucu
masaüstü yedekleme aracı explorer.exe.bak oluşturduğunda da elenir.
Aynı şekilde
*\Windows\* zaten C:\Windows\ altını kapsar; bu
satır redundanttır ama explorer.exe adı özellikle
belirtildiği için, sonradan \Windows\ kalıbının daraltılması hâlinde
korunabilir bir yedek olarak bırakılmış görünür.
11.2 — Kullanıcı Dosyası Uzantı Gözcüsü (1479 kayıt)
Kaynak yorumu şunu söyler: “Extensions of user files whose encryption is treated as ransomware-relevant. Scopes the file-encryption candidate so extensionless / temp files do not FP.”
// Extensions of user files whose encryption is treated as ransomware-relevant. // Scopes the file-encryption candidate so extensionless / temp files do not FP. "ransomFileExtensions": [ "*.0", "*.0nv", "*.0rv", "*.1", "*.10", "*.10-config", "*.12", "*.13", "*.14", "*.15", "*.16", "*.17", "*.18", "*.199", "*.1cd", "*.1m", "*.20", "*.25", "*.3fr", "*.3gp", "*.3g2", "*.amr", "*.avi", "*.bak", "*.blend", "*.bmp", "*.cdr", "*.cpp", "*.cr3", "*.csv", "*.dbf", "*.dll", "*.doc", "*.docx", "*.dot", "*.dotx", "*.dwg", "*.eml", "*.enc", "*.encrypted", "*.flac", "*.gif", "*.gz", "*.htm", "*.html", "*.ico", "*.indd", "*.java", "*.jpeg", "*.jpg", "*.js", "*.json", "*.locked", "*.log", "*.mdb", "*.mdf", "*.mkv", "*.mov", "*.mp3", "*.mp4", "*.odt", "*.pdf", "*.php", "*.png", "*.ppt", "*.pptx", "*.psd", "*.py", "*.rar", "*.rb", "*.rtf", "*.sln", "*.sql", "*.tar", "*.tiff", "*.txt", "*.vhd", "*.vmdk", "*.wav", "*.webm", "*.webp", "*.wmv", "*.xls", "*.xlsx", "*.xml", "*.zip", "*.zip-o-matic", "*.zoo", "*.zst" // ... alfabetik, 1479 kayıt, *.0 -> *.zst ],
Listeyi analiz edersek
| Kategori | Örnekler | Amacı |
|---|---|---|
| Fidye yazılımı tipi kurban uzantı | *.doc *.docx *.xls *.xlsx *.ppt *.pptx *.pdf *.jpg *.png *.psd *.ai *.dwg *.mdb *.sql *.bak *.vmdk *.vhd |
Klasik “dosyası şifrelenebilir” listesi |
| Aileye özgü ekler | *.locked *.crypt *.enc *.encrypted *.ryk *.ryuk *.wcry *.wncry *.wnry *.locky *.zepto *.odin *.thor |
Görünürken çıkan özgün ekler; ikinci tur dalga tespitini güçlendirir |
| Geliştirici / veritabanı / VM | *.sln *.cs *.java *.py *.rb *.go *.rs *.sql *.mdf *.ldf *.sqlite* |
Yüksek değerli “özgün emek” dosyaları en çok kaybedilen tür |
| Medya / yaratıcı | *.blend *.psd *.indd *.cdr *.aep *.prproj *.raw |
Fotoğraf ve video arşivleri — genelde en çok foto olan dizin |
| Yapısal olarak geniş girişler | *.0 *.1 ... *.100, *.log *.tmp *.dat |
Düşük sinyal ama süzgeç 7a & 7b ile birleşince etkisiz |
ransomFileExtensions bilinçli olarak geniş bir listeye
dayanır — 1479 uzantı, tek bir StringMatcher tablosunda neredeyse maliyetsizdir.
Daraltma, sonraki süzgece bırakılmıştır (7a: nokta var mı; S8: metin mi
değil mi; S9: 3+ ayrı hedef). Bu, bir listeyi devamlı güncel tutma yükünü
kaldırırken tespit gücünü korumanın doğru mimarisidir: geniş aday havuzu +
katlı sert filtreler, dar ve güncellenmeye muhtaç bir aday havuzundan iyidir.
12 Kernel Tarafı: Hangi IRP, Hangi Olay?
Kuralın tetikleyicilerinin tamamı Ring-0'da üretilir. Minifilter, yedi IRP major fonksiyonunu kaydeder. Bu kayıt, kuralın tamamını belirler:
CONST FLT_OPERATION_REGISTRATION c_Callbacks[] =
{
{ IRP_MJ_CREATE, 0, preCreate, postCreate },
{ IRP_MJ_CLEANUP, 0, preCleanup, postCleanup },
{ IRP_MJ_SET_INFORMATION, FLTFL_OPERATION_REGISTRATION_SKIP_PAGING_IO, preSetFileInfo, postSetFileInfo },
{ IRP_MJ_WRITE, 0, preWrite, postWrite },
{ IRP_MJ_READ, 0, preRead, postRead },
{ IRP_MJ_DEVICE_CONTROL, 0, preDeviceControl, nullptr },
{ IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION, 0, preAcquireForSectionSync, nullptr },
{ IRP_MJ_OPERATION_END }
};
12.1 — Sürücü Tarafı Olay Kodları
| SysmonEvent | Kod | LLE Değeri | Üretim Yeri |
|---|---|---|---|
FileCreate | 0x0007 | LLE_FILE_CREATE = 0x0003 | postCreate |
FileDelete | 0x0008 | LLE_FILE_DELETE = 0x0004 | postCleanup / postSetFileInfo |
FileClose | 0x0009 | LLE_FILE_CLOSE = 0x0005 | postCleanup |
FileDataChange | 0x000A | LLE_FILE_DATA_CHANGE = 0x0006 | postCleanup |
FileDataReadFull | 0x000B | LLE_FILE_DATA_READ_FULL = 0x0007 | postCleanup |
FileDataWriteFull | 0x000C | LLE_FILE_DATA_WRITE_FULL = 0x0008 | postCleanup |
FileMapRead | 0x0011 | LLE_FILE_MAP_READ = 0x0034 | preAcquireForSectionSync |
FileMapWrite | 0x0012 | LLE_FILE_MAP_WRITE = 0x0035 | preAcquireForSectionSync |
FileRename | 0x0014 | LLE_FILE_RENAME = 0x0032 | postSetFileInfo |
OwlyPreImageSaved | 0x0017 | LLE_FILE_PREIMAGE_SAVED = 0x0037 | RansomShield |
12.2 — “Tam okuma” ve “tam yazma” nasıl kanıtlanır?
Bu, kuralın en sağlam mühendislik parçasıdır. Minifilter hiçbir zaman “dosyaya yazıldı” demez; bunu kanıtlar:
| Kanıt | Koşul | Neden Önemli |
|---|---|---|
| Başlangıç boyutu | postCreate anında nSizeAtCreation kaydedilir |
Tam yazma dedektörü yalnızca boyut 0 iken (yeni/kırpılmış dosya) armed edilir |
| Sıralı konum | nNextPos her yazma/okuma sonrası ilerletilir; tam okuma için nNextPos == nSizeAtCreation gerekir |
Kısmi okuma/yazma sayılmaz — rastgele erişim elenir |
| Boyut sınırları | Toplam yazılan/okunan boyut [nMinFullActFileSize, nMaxFullActFileSize] aralığında olmalı |
Log dosyaları, cache, geçici artefaktlar — devasa veya minik dosyalar elenir |
| Kırpma önleme | eCreationStatus — FILE_CREATED / FILE_OVERWRITTEN / FILE_SUPERSEDED / FILE_OPENED |
“ Aç dosya, sonra yaz” ile “oluştur ve yaz” ayırt edilir |
| Yedekleme adı istisnası | Yolu içeren HydraDragonBackups giren dosyalar atlanır |
Kendi geri yükleme mekanizması kendi kendini tetiklemez — önemli bir önlem |
12.3 — mmap yolu: görünmez olanın yakalanması
/* mmap ile yapılan okuma/yazma HİÇBİR IRP_MJ_READ / IRP_MJ_WRITE
üretmez. NtCreateSection + NtMapViewOfSection doğrudan belleğe
eşler. Bu yüzden tek görünür sinyal, section edinme IRP'sidir. */
Sürücü, PAGE_READONLY korumasını okuma niyeti, PAGE_READWRITE /
PAGE_WRITECOPY / PAGE_EXECUTE_READWRITE / PAGE_EXECUTE_WRITECOPY
korumalarını yazma niyeti olarak sınıflandırır. accessMask alanına sayfa
koruması yazılır.
mmap ile işler — çünkü bu yol daha hızlıdır
ve kullanıcı modundaki API kancalarına iz bırakmaz. LLE_FILE_MAP_READ ve
LLE_FILE_MAP_WRITE maddeleri olmasa, bu sınıf fidye yazılımı kurala tamamen
görünmez olurdu.
13 Neden İki Ara Olay Var?
MLE_RANSOM_CANDIDATE ve MLE_RANSOM_EVALUATE ara olayları
“gereksiz işlem” gibi görünebilir. Değildir. Üç somut faydaları vardır:
| Fayda | Açıklama |
|---|---|
| Sözdeşleme (decoupling) | Aşama 2 sadece toplama yapar, aşama 4 sadece karar verir. İki sorumluluk tek yerde birleştirilseydi, eşik hesabı üretim mantığının içine gömülür ve değiştirilemez hâle gelirdi. |
| Kural izlenebilirliği | Log ve debugger akışında her adım ayrı bir olay adıyla görünür. “Aday üretildi ama eşik tutmadı” ile “Aday bile üretilmedi” ayırt edilebilir — bu, üretimdeki kütüphaneler için kritik bir ayrım yeteneğidir. |
| Politika genişletilebilirliği | MLE_RANSOM_EVALUATE çıkışı herkese açık bir noktadır. Gelecekte yeni bir kural (örn. “farklı eşik, farklı pencere”) aynı aday akışına bağlanabilir; mevcut kurala hiç dokunulmadan. |
14 Yanıt Zinciri: Tespitten Sonrası Ne Olur?
Tespit üretilmesi bir son değildir. MLE_RANSOM_BEHAVIOR olayı
OUT ile zenginleştirme, güven kontrolü, öldürme, karantina ve geri yükleme
zincirinden geçer. Aşağıdaki akış DetectionNotifier::execute("put")
içindeki gerçek sıradır.
14.1 — Neden quarantineTarget sürecin imajıdır?
quarantineTarget şifrelenen dosyayı işaret
eder. Nihai tespitte ise sürecin kendi imaj dosyası atanır.
Bu, kuralın en büyük ayırt edici özelliğidir. Klasik EDR'lar genellikle mağdur dosyayı karantinaya alır — bu, kullanıcının verisini korumaz, sadece zararlı dosyayı uzaklaştırır. Viruskov ise aracı yok eder, veriyi geri yükler. İkisi arasındaki fark, bir ürünün “tespit eden” mi yoksa “kurtaran” mi olduğudur.
14.2 — Güven bayrakları: should_trust_*
| Bayrak | Değer | Etkisi |
|---|---|---|
should_trust_company_whitelist |
true | owlyshield_is_trusted_company_signer çağrısına izin verir. Güvenilir kurum imzalı bir ikili → öldürme + karantina iptal edilir (alarm kaydı yine tutulur). |
should_trust_comodo_fls_cloud |
true | FLS bulutu verdict = 1 (SAFE) dönerse veto verir. Ayrıca verdict = 4 (FAIL/ERROR) durumunda da veto verir — böylece bulut kesintisi tespit sistemini felç etmez. |
owlyshield_is_malicious_company_signer |
güven bayraklarını geçersiz kılar | Kötü / PUA üreticisi tespit edilirse verdict = 2'ye zorlanır ve sıkı uygulama devreye girer; beyaz liste devre dışı kalır. |
should_trust_* bayrakları bu kuralda açık tutulmuştur
(false değil). Bu, kurumsal güvenlikte “imzalı = güvenli”
varsayımının doğru tarafta durmasını sağlar. Aynı anda
“güvenilir imzalı → şifreleme yapan exe” senaryosu teknik olarak imkânsıza
yakın olduğu için bu ayar pratikte FP üretmez, yalnızca imzalı ancak davranışı düşürülmüş
(supply-chain) vakaları doğru muameleye alır.
put yolunda ağ engelleme (firewall / IPC block),
bootkit / sürücü temizliği veya buluta MLE gönderimi
yapılmaz. Bunlar ayrı modüllerin alanıdır. MLE_RANSOM_BEHAVIOR
tek işine odaklanır: saldırganı durdur, veriyi geri getir, analiste bildir.
15 Neden Mükemmel Bir Ransomware Kuralı?
“Mükemmel” burada şu anlama geliyor: sıfırıncı gün farkından bağımsız, hedef odaklı, kanıt temelli, ve kanıtlanabilir olarak kurtarıcı. Aşağıda on iki somut gerekçe.
NtMapViewOfSection hiçbir IRP_MJ_READ/WRITE üretmez. LLE_FILE_MAP_READ / MAP_WRITE maddeleri sayesinde haritalama tabanlı şifreleyiciler de yakalanır. Birçok EDR bu yolu tamamen kaçar.distinctCounter ayrı değer sayar. 500 kez aynı dosyaya yazan bir yedekleme aracı sayacı dolduramaz. Bu, “çok sayıda işlem" ile “çok sayıda farklı dosya" arasındaki kritik ayrımı yapar.isAsciiText dosyanın gerçek içeriğini ölçer: diskten okunan ilk 8 KiB'da %15+1 yazdırılamaz bayt arar. “Zararlı, çünkü adında .doc vardı" değil, “zararlı, çünkü bu artık düz metin değil" der. Uzantılara göre karar vermek, kurumsal e-posta şifreleme ve belge işleme yazılımlarını sürekli yanlış pozitife sokardı.15.1 — Saldırgana karşı bu kuralı nasıl atlamaya çalışırsınız?
Güvenli tarafı test etmek için, bir red team sorusunu cevaplamak gerekir:
| Saldırgan Tekniği | Kurala Etkisi | Neden |
|---|---|---|
| Paketleme / polimorfik kod | ETKİSİZ | Kural koda değil, dosya sistemi işlemine bakar |
API kancalama ile ReadFile/WriteFile atlama |
ETKİSİZ | IRP katmanı gözleniyor; usermode API görünmez değil, ilgisiz |
Doğrudan NtWriteFile / ZwWriteFile |
ETKİSİZ | Aynı IRP'ye iner |
Yerleşik dosya sistemi API'leri (SetFileInformationByHandle ile silme) |
ETKİSİZ | IRP_MJ_SET_INFORMATION izlenir |
| Dosya sistemi filtresi (minifilter) ile öndenleme | ZOR — kötü niyetli | Çalışan bir “meşru" minifilter görünür; o da tanımlanması gereken ayrı bir yazılımdır |
| WMI / uzak yönetim ile toplu şifreleme | ETKİSİZ | Yine aynı dosya sistemi işlemi |
Sadece C:\ kökünü şifreleme (kullanıcı dışı) |
KAPSAM DIŞI | S3 süzgeci \users\ zorunlu kılıyor — bu bilinçli bir sınırdır (bkz. Bölüm 16) |
| Dosya başına birkaç dakika bekleyerek yavaş şifreleme | KAÇIRILIR | 60 saniyelik pencere aşılır — bilinen sınır (bkz. Bölüm 16) |
Önce AppData altına yazıp oradan taşıma |
KAPSAM DIŞI | S2 & S4 \AppData\'yi tamamen eler |
| Yedekleri sil, sonra şifrele | ETKİSİZ | Komşu kural MLE_RANSOM_SHADOW_COPY_DELETE devreye girer (Bölüm 17) |
Düz metin hedefleme (yalnızca .txt şifrele) |
KALDIRILIR | S8 isAsciiText koruması metin dosyalarını bilerek bırakır — FP azaltma tercihi |
Aşılır: Yavaş şifreleme, disk kökü şifreleme, salt metin hedefleme.
Bu, ticari bir trade-off. Her EDR bu dengeyi yapar; Viruskov bunu gizlemez, tam olarak bu sayfada olduğu gibi belgeler.
16 Dürüst Sınırlar ve Bilinen Kusurlar
Bu bölüm bilinçli olarak yazılmıştır. Bir ürünün güçlü yanlarını anlatmak kolaydır; zayıf yanlarını aynı sayfada, aynı cesaretle anlatmak ise güveni insani kılar. Aşağıdaki maddeler, kaynak kod incelemesiyle tespit edilmiş gerçek bulgulardır — ne varsayım, ne kötü niyet, sadece açık gerçek.
16.1 — Tasarımdan kaynaklanan sınırlar
| # | Sınır | Etki | Düzeltme Yolu |
|---|---|---|---|
| 1 | 60 saniyelik pencere dosya başına birkaç dakika bekleyen sofistike şifreleyicileri kaçırır | Orta — yüksek hacimli her şifreleme yine yakalanır | Pencereyi 5-10 dakikaya çıkarmak, eşiği 5-10'a çıkarmak veya zamansal oran (dosya/sn) metriği eklemek |
| 2 | S3 *\users\* zorunluluğu disk kökünü veya ağ sürücüsünü şifreleyenleri kapsam dışı bırakır |
Düşük — bu hedefler genelde kullanıcı verisi değildir | Yeni bir kural: MLE_RANSOM_BEHAVIOR_SYSTEM (yol bağımsız, C:\Windows hariç) |
| 3 | Yalnızca tam yazma olaylarında entropi ölçülüyor — LLE_FILE_MAP_WRITE için entropi üretilmiyor |
Düşük — S8 isAsciiText bu yolu zaten kapatıyor |
preAcquireForSectionSync içinde mmap sayfası örneklemesi |
| 4 | S4, S2 ile aynı kontrol (çift denetim) | Yok — savunma derinliği, maliyeti sıfır | Korunması önerilir; okunabilirlik ve örnek olma değeri yüksek |
| 5 | ransomFileExtensions çok geniş (sayısal ve kısa uzantılar, *.0 … *.100) |
Düşük — 7a + S8 + S9 birlikte filtreliyor | Listeyi gerçek kurban uzantılarına daraltmak. Not: 165. satırdaki "*.2538)" kaydı bir yazım hatasıdır. |
16.2 — Kodda doğrudan doğrulanmış kusurlar
LLE_FILE_RENAME (2f), LLE_FILE_DELETE (2g) ve
RF4* (2h) maddeleri — her biri iki kez yazılmış.
Toplam 16 maddenin 3'ü gereksiz.
Etki: Yok. Aynı olay için aynı
MLE_RANSOM_CANDIDATE üretilir; sayaç ayrı değer saydığı için ikinci
üretim sayacı değiştirmez. Ancak politikanın okunabilirliğini zarlar
ve ileride biri düzeltilirse diğeri değişmiş olur.
Düzeltme: 2f', 2g' ve 2h' maddelerini silin. 16 madde → 13 madde.
RF10* ve RF4* derlemede düşereventType anahtarlarını
önek eşlemesiyle genişletir ve yalnızca aynı politikada
jokersiz olarak geçen olay tiplerine bakar. RF10* için önek
"RF10", RF4* için "RF4" — ikisi de
sıfır eşleşme üretir, anahtar silinir ve kural sessizce
kaybolur.
Temel neden:
RF* takma adları (v1 / eski EVM motorunun
olay sınıf adları: RF4 = LLE_FILE_DELETE, RF10 = LLE_FILE_DATA_CHANGE)
v2 motorunda tanımlı değildir. Doğru kullanılmaları gereken isimler
LLE_FILE_DELETE ve LLE_FILE_DATA_CHANGE'dir.
Etki: Fonksiyonel kayıp yok. Kastedilen iki olay (
LLE_FILE_DATA_CHANGE = madde 2d, LLE_FILE_DELETE =
madde 2g) zaten doğrudal olarak kapsanmış. Geriye yalnızca derlenmiş
çıktıda üç kuralın kaybolması ve derleyicinin uyarı üretmemesi kalıyor.
Düzeltme: 2e, 2h ve 2h' maddelerini tamamen silin; kuralın mantığını değiştirmez.
saveContext ile RANSOM_FILE_READ_WRITE
sepetine kayıt yazar. Ancak RANSOM_BEHAVIOR içinde bu sepeti okuyan
hiçbir loadContext yoktur. Aşama 2 yalnızca LLE_FILE_CREATE
ve yazma/haritalama/değiştirme/rename/delete olaylarını tetikler —
okuma olayları tetikleyici değildir.
Etki: Kuralı etkilemez (eşik kararı tamamen yazma tarafındadır). Yalnızca 120 saniye boyunca gereksiz bir bellek harcanır. Aşama 1 tamamen yasal ve gelişim için hazır bir temel olmaktadır: “okuyan → yazan” korelasyonu kurmak isteyen bir kural buraya bağlanabilir.
Düzeltme seçenekleri: (a) Aşama 1'i kaldır, (b) bir
loadContext ile “önce bu dosya okundu mu?” kontrolü ekle
(“fiziksel kopyalama + silme” modeli için gerekli), (c) olduğu gibi bırak.
group alanı olmadan yazılır; aşama 5 ise
group: "@event.process.id" ile silmeyi dener. Motor, kayıtları
boş grup işaretiyle sakladığı için grup bazlı silme hiçbir şeyi
bulamaz.
Etki: İşlevsel değil — 120 saniyelik TTL zaten bu işi doğru şekilde yapmaktadır. Yalnızca süreç daha erken bitse kayıt gereksizce 120 saniye bekler.
Düzeltme: Aşama 1a/1b'ye
"group": "@event.process.id"
eklemek.
6 ile karşılaştırır. Böylece owlyEntropy > 6, pratikte
“değer 6'dan büyük mü?” değil, “değer neredeyse sıfırdan büyük mü?”
sorusuna dönüşür.
Ayrıca şu dört dal hiçbir zaman tetiklenmez:
@event.destination.owlyEntropy (şemada yok;
alan olay kökündedir), @event.destination.entropy / @event.entropy
(hiçbir yerde tanımlı değil). Yalnızca @event.owlyEntropy
dalıdır.
Etki: Orta. 7c bloğu pratikte “bu bir
LLE_FILE_DATA_WRITE_FULL olayı mıydı?” filtresine
dönüşür. Gerçek entropi ayrımı 8. süzgece (S8) yüklenmiştir.
Düzeltme: (a) enricher'da
owlyEntropy / (1<<24) ile
ondalık dönüşüm yapıp file.entropy alanı üretmek, (b) eşiği Q24 cinsinden
yazmak: greater(@event.owlyEntropy, 100663296) (= 6 × 2^24),
(c) olmayan destination.owlyEntropy / entropy dallarını kaldırmak.
@event.source daima nullsource alanı yalnızca MLE_FILE_COPY* olaylarında doldurulur.
MLE_RANSOM_CANDIDATE ise LLE dosya olaylarından üretildiği için
source hiçbir zaman taşınmaz — aday aşamasında
zaten okunmuyor, değerlendirme aşamasında da null kalır.
Etki: Çok düşük. 7b'nin ikinci dalı (
imatch(ransomFileExtensions, @event.source.path)) kalıcı olarak
false döner; 7a'nın ikinci dalı da aynı şekilde. Yani bu iki dal
etkisiz koddır ve kaldırılabilir.
ptm.local.src içindeki aşama 4 yorumu şu ifadeleri içeriyor:
“The entropy > 6.8 clause...” ve
“plain explorer copies of text .js must never reach the
counter”.
Her iki ifade de yanlıştır: (1) kodda eşik
6,
6.8 değil; (2) sayaç condition'den önce
çalıştığı için metin kopyalamaları sayacı besler (kuralın kendi süzgeci onları
eler, ama sayaç onları görür).
Etki: Yok — yorum yanıltıcı olduğu için etkilidir. Düzeltme: Yorumu gerçek kodla hizalamak.
16.3 — Derleme ve üretim zinciri notları
- Geliştirici derleme aracı:
edrdata/compile_ptm.bat,edrcon.exe compile -o ptm.act common.src ptm.local.src. Üretilenptm.act,srcBinInstallvesrcBinUpgradedizinlerine senkronize edilir. - Ürün kendisi de derler: Servis başlangıcında politika yeniden derlenir; geliştirici betiği yalnızca kolaylıktır.
- Sınır testi:
distinctCounteriçin yalnızca eşik ve pencere belirlenir; eşik, pencere, anahtar, sayılan değer tamamen politika dosyasından gelir — motorda tek bir kurala özel sabit yoktur.
17 Komşu Kurallar: Tek Başına Yaşamaz
MLE_RANSOM_BEHAVIOR, fidye yazılımı savunmasının tek parçasıdır. Aşağıdaki komşu kurallar, ona birlikte bakan ve birbirini tamamlayan katmanlardır.
| Kural / Olay | baseType | Görevi | İlişki |
|---|---|---|---|
MLE_RANSOM_SHADOW_COPY_DELETE |
1000009 | Gölge kopya / yedekleme yok etme komutlarını izler | Önce gelir. Fidye yazılımı şifrelemeden önce yedekleri siler. Bu kural yakalarsa veri kaybı olmaz. |
RANSOM_BEHAVIOR |
1000008 | Bu sayfanın konusu | Ana tespit |
CRYPTO_API_MASS |
— | Kripto API kullanımını ölçer (CryptEncrypt vb.) |
Tamamlayıcı. Dosyaya dokunmadan önce kriptografik iş yapan zararlılar için erken sinyal. |
RANSOM_COUNTER_INIT |
— | Süreç başına işlem sayacı başlatır (TTL 24 saat) | Temel. Gelecekte süreç başına toplam işlem limitleri için. |
LLE_FILE_PREIMAGE_SAVED / RansomShield |
0x0037 | Şifrelemeden önce özgün dosyanın yedeğini alır | Bu, verinin neden kurtarıldığının cevabıdır. MLE tetiklendiğinde rollbackRansomBackups bu kopyaları geri yükler. |
MLE_FILE_COPY* |
1000001+ | USB / ağ kopyalama tespiti | Dengel. Exfiltration (çıktı) için. 1000008 iç (destruction) ile tamamlanır. |
MLE_DRIVER_INSTALL_TAMPER |
1000021 | Sürücü / özel muafiyet manipülasyonu | Ön muhafız. “Kendini devre dışı bırak” girişimini engeller. |
MLE_FLS_MALICIOUS_VERDICT |
1000010 | Bulut FLS verdict = MALWARE | Ortak güven kapısı. Aynı should_trust_comodo_fls_cloud mekanizmasını kullanır. |
"ransomShadowDeleteCmdLines": [ "*vssadmin*delete shadows*", "*wmic*shadowcopy delete*", "*wmic*shadowcopy*delete*", "*wbadmin*delete catalog*", "*bcdedit*recoveryenabled*no*", "*wbadmin*delete systemstatebackup*", "*vssadmin*resize shadowstorage*" ]
vssadmin delete shadows → MLE_RANSOM_SHADOW_COPY_DELETECryptEncrypt çağrıları → CRYPTO_API_MASSrollbackRansomBackups ile veri geri yüklenir
18 Analist El Kitabı
Bir SOC analisti veya bir güvenlik araştırmacı bu kuraldan nasıl faydalanır? Aşağıdaki yol, doğru tarafı okumanın en hızlı yoludur.
18.1 — Tespit edildiğinde ilk bakacağınız 8 alan
| Alan | Sorulacak Soru | Kritik Değer |
|---|---|---|
quarantineTarget | Hangi ikili karantinaya alındı? | Dosya adı, yolu, imzası |
process.id / process.pid | Global ID nedir? (kill hedefi) | Önemli — analiz izinde kullanılır |
process.cmdLine | Nasıl başlatıldı? | powershell -enc, mshta, wmic ipuçları |
process.imageFile.rawPath | Nerede duruyordu? | %APPDATA%, %TEMP% = yüksek öncelik |
destination.path | Hangi dosyaya dokundu? | Son vurulan hedef (tek dosya, < 3 ise eşik tutmadı) |
destination.abstractPath | Hedefin “mantıksal” adı ne? | %appdata% gibi belirteçleri çıkar; GUI'de daha okunur |
processes[] | Kim bu süreci başlattı? | Üst zincir — ilk bulunan güvenilmeyen ataya kadar in |
time / tickTime | Zaman çizelgesi nasıl? | İlk olay, 3. dosya, şifreleme süresi |
18.2 — Yanlış pozitif triage kararı
| Görünen | Değerlendirme | Karar |
|---|---|---|
Süreç C:\Windows\ veya Program Files altında |
S1 zaten elemisti — muhtemelen farklı bir alarm | Triage etmeyin |
Hedef yollar AppData altında |
S2/S4 elemisti — muhtemelen cache/uygulama işlemi | Triage etmeyin |
Hedefler C:\Users\ altında, metin dosyaları |
S8 bırakmış olabilir — belge düzenleyici / eşitleme aracı olabilir | Süreç imzası ve cmdLine'a bakın |
| Süreç güvenilir kurum imzalı, verdict SAFE | Güven kapısı kuralı zaten uyguladı (öldürme olmamalı) | Entegrasyon testi olabilir; kaydedin |
Süreç imzasız, %TEMP%'de, işlem sayacı yüksek |
Klasik ilk çalıştırma profili | Yüksek öncelik — geri yükleme doğrulayın |
processes[] zincirinde bir winword.exe / excel.exe görünüyor |
Belge makrosu veya COM hijacking olabilir | Yüksek öncelik; makro analizi yapın |
18.3 — Kuralı değiştirmek istiyorsanız
Kural hariciden değiştirilebilir değildir; kaynak kod modifikasyonları
güvenlik açığı riski taşır. En temiz yol, politika dosyasını fork edip
edrdata/ptm.local.src içinde RANSOM_BEHAVIOR bloğunu
düzenlemektir. En sık ihtiyaç duyulan değişiklikler:
// 1) Hassasiyet / tolerans ayarı (varsayılan 3/60s) "threshold": 3, // 2 yaparsanız test örnekleri de yakalanır "window": 60000, // 300000 yaparsanız yavaş şifreleyiciler de yakalanır // 2) Coğrafya ayarı (zorunlu pozitif koşul) "pattern": "*\\users\\*" // ağ sürücüleri için ayrı bir kural açın // 3) Yeni korunacak yol eklemek "ransomSystemExclusions": [ ..., "*\\OneDrive\\*", "*\\Google\\Drive\\*" ]
ransomSystemExclusions listesine geniş bir yol eklemek
(*\OneDrive\* gibi) o klasördeki gerçek fidye şifrelemesini
de gizler. Kurumsal bulut eşitleme klasörleri gerçek bir hedef olduğu için,
bu tür genişletmeler dikkatli yapılmalıdır.
19 Sık Sorulan Sorular
threshold: 1 denenebilir — ama yanlış pozitif oranı ciddi şekilde artar.
!equal(isAsciiText, true))
metin dosyalarını bilerek bırakır. Sebep: kurumsal e-posta şifreleme, belge
işleme yazılımları ve eşitleme istemcileri sürekli olarak metin dosyaları
yazar; bu dosyaları kapsama almak FP oranını kullanılamaz hâle getirirdi.
Bu, bilinçli bir FP/recall trade-off'dur.
preSetFileInfo
aşamasında orijinal içeriğin ön-image'ini %PROGRAMDATA%\HydraDragonBackups
altına kaydeder. MLE tetiklendiğinde EventEnricher::rollbackRansomBackups()
bu kopyaları geri yükler.
Önemli sınır: Geri yükleme yalnızca ön-image alınabildiği dosyalarda başarılıdır. Şifreleyici “önce oku, şifreli yeni dosya oluştur, sonra orijinali sil” modelini kullanırsa, minifilter yine ön-image'i alır (“her fidye ailesine karşı genel muhafız” yorumu kodda açıkça belirtilir), ancak diskten tamamen silinmiş veri geri getirilemez.
should_trust_company_whitelist ve
should_trust_comodo_fls_cloud güven kapısı. İkisi de geçerli ise
süreç öldürülmez ve karantinaya alınmaz; yalnızca alarm kaydedilir. Ancak
owlyshield_is_malicious_company_signer kötü/PUA üreticisi tespit ederse
güven bayrakları geçersiz kılınır ve katı uygulama devreye girer.
Önemli: Fidye yazılımı numunelerini kendi makinenizde çalıştırmayın. Bilerek bir sisteme bulaştırmak yasal sonuçlar doğurabilir. Bu projede konteyner / sanal ortam dışında numune çalıştırmak için teknik destek gerekmez — bütünleşme testi yapmayın.
20 Kaynak Haritası
Bu sayfadaki her iddianın kaynak dosyası. Politika motoru açık kaynak olduğu için, okuduğunuz her şey doğrudan doğrulanabilir.
| Dosya | İlgili Bölüm |
|---|---|
OpenEDR/edrav2/iprj/edrdata/ptm.local.src4636–5129 |
RANSOM_BEHAVIOR kuralının tamamı — 16 madde, 5 aşama |
ptm.local.src 137–1619 |
@const.ransomFileExtensions — 1479 uzantı |
ptm.local.src 1660–1670 |
@const.ransomSystemExclusions — 8 beyaz liste kalıbı |
ptm.local.src 18–36 |
ransomShadowDeleteCmdLines, ransomEventBaseType, ransomBasket |
ptm.local.src 4555–4631 |
CRYPTO_API_MASS ve RANSOM_COUNTER_INIT komşu kuralları |
edrdata/common.src 9–28, 87 |
eventBaseType: MLE_RANSOM_BEHAVIOR = 1000008 ve eventTypes kaydı |
libedr/src/policy_v2.cpp 258–1197 |
PTM v2 motoru: saveContext, distinctCounter, createEvent, yönerge sırası |
libedr/src/policyoperation.cpp 367–600 |
imatch / !imatch, joker → regex/StringMatcher dönüşümü |
libedr/src/policycompiler.cpp 262–296 |
Joker eventType genişletmesi — RF10* / RF4* kaybının nedeni |
libedr/src/signcontext.cpp 87–538 |
Sepet (basket) ve distinctCounter çalışma zamanı semantiği |
libcore/src/string.cpp 21–50 |
convertWildcardToRegex — *→.*, ?→. |
edrdrv/src/filemon.cpp 1320–1554, 2564–2661 |
Minifilter geri çağırmaları, tam okuma/yazma kanıtı, mmap sınıflandırması, entropi örnekleme |
edrdrv/src/ShanonEntropy.cpp |
Q24 Shannon entropi hesabı (tam sayı, çekirdek içi) |
libsyswin/src/filedataprovider.cpp 790–1236 |
Dosya nesnesi alanları, isAsciiTextFile (1195-1236): 64 KiB I/O, 8 KiB analiz penceresi, %15+1 eşiği, fail-fast |
libedr/src/detectionnotifier.cpp 488–2148 |
Tespit sınıflandırması, güven kapısı, GID ile öldürme, karantina, geri yükleme |
libsysmon/inc/edrdrvapi.hpp 42–307 |
Sürücü → servis telemetri şeması, SysmonEvent kodları |
libcore/inc/events.hpp 19–117 |
Event numaraları, MLE_MASK, createMle |
edrdata/compile_ptm.bat |
Politikanın ptm.act olarak derlenmesi |
edrdata/compiler.cfg 10–138, 330–477 |
Olay sınıfı şemaları, varsayılan değerler, eski RF*/RP* takma adları |
Bu wiki ve MLE_RANSOM_BEHAVIOR dokümantasyonu, projenin açık kaynak
felsefesinin bir parçasıdır: hiçbir şey gizli değildir. Bu kuralı
okudunuz, kaynak kodunu incelediniz, hatta bu sayfadaki
bilinen kusurları bile gördünüz.
Projeye katkı yapmak, ek kural yazmak, ya da sadece finansal destek
(sunucu / test ortamı / imza sertifikasyonu masrafları) göstermek isteyenler için:
[email protected]. Tüm talepler doğrudan proje liderine ulaşır —
aracı yoktur, komisyon yoktur; kutunun içinde ne olduğunu bu sayfalarda
gördüğünüz gibi, bağış akışında da görürsünüz.
Konu satırında kısa bir açıklama yazmanız yeterli: [KATKI],
[KURAL], [BİLGİ] veya [DESTEK].