Dosya tara
Platform Fidye Kuralı Tarayıcı İstatistikler Wiki Hikaye GitHub Dosya tara
VIRUSKOV / WIKI / TESPİT KURALLARI / MLE_RANSOM_BEHAVIOR

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

MLE_RANSOM_BEHAVIOR, bir dosyanın hash'ine, derleyicisine ya da paketleyicisine bakmaz. Çekirdekte gördüğü tek şey davranıştır: bir süreç, kullanıcının kişisel dosyalarına 60 saniye içinde en az 3 ayrı hedefe yazıyor, yeniden adlandırıyor ya da siliyor; bu hedefler metin dosyası değil ve şifrelenmiş gibi yüksek entropili veri taşıyor. Bu üçlü — kitle × hacim × içerik — eşleştiği anda motor, saldırganın proses imajını karantinaya alır ve süreci anında öldürür. Bu sayfa, bunun her tek satırını, her tek süzgecini ve her bilinen sınırını açar.

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.

Kural Adı (policy pattern)
RANSOM_BEHAVIOR
Yayın Olayı (createEvent)
MLE_RANSOM_BEHAVIOR
baseType (eventBaseType)
1000008
Kural Tipi
DAVRANIŞ TANI / POLİTİKA (behavior)
Politika Grubu
patternsMatching
Politika Bağımlılığı
common (version 2)
Motor
PTM v2 — PatternsMatching / EVM
Kaynak Dosya
OpenEDR/edrav2/iprj/edrdata/ptm.local.src
Satır Aralığı
4636 – 5129 (toplam 16 kural maddesi)
Aşama Sayısı
5 mantıksal aşama: KAYIT → ADAY → DEĞERLENDİRME → KARAR → TEMİZLİK
Süzgeç Sayısı (aşama 4)
9 bağımsız filtre, tek AND zincirinde
Sayaç Eşiği
3 AYRI hedef dosya
Sayaç Penceresi
60000 ms (60 saniye) kayan pencere
Kaynak Olay Sayısı
10 farklı kernel dosya olayı tetikler
Beyaz Liste
8 sistem yolu kalıbı
Uzantı Gözcüsü
1479 kullanıcı dosyası uzantısı
Güvenlik Seviyesi
3 — CRITICAL (kaynak kodda sabit)
Varsayılan Yanıt
KARANTİNA + SÜRECİ ÖLDÜR + GERİ YÜKLE
16
Kural Maddesi
10
Kernel Tetikleyicisi
9
Karar Süzgütü
1479
İzlenen Uzantı
3 / 60s
Eşik / Pencere
Ring-0
Tespit Katmanı

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:

  1. 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.
  2. 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.
  3. Hedeflerin kullanıcı profilinde (C:\Users\...) ve AppData / Temp / Windows / Program Files dışında olduğunu doğrular.
  4. Tüm koşullar tutarsa MLE_RANSOM_BEHAVIOR olayı üretilir; motor sürecin imaj dosyasını karantinaya alır ve süreci Global ID ile öldürür.
  5. Kernel'in RansomShield modülü daha önce kaydettiği özgün dosya kopyalarını geri yükler.
▶ Bunun pratik anlamı
Fidye yazılımı ailesi dün ya da bugün derlenmiş olsun, paketlenmiş olsun, ismi hiç görülmemiş bir isim taşısın, farkı yoktur. Kural bir aileyi değil, bir davranışı tarif eder. Bu yüzden imza veritabanını güncellemeye gerek kalmadan sıfırıncı gün fidye yazılımı da aynı kapıdan geçer.

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.
▶ Temel fikir
Fidye yazılımının tek değişmez zorunluluğu vardır: kullanıcının dosyasını okumak ve geri döndürülemez biçimde bozmak. Kod imzası, paketleyici, dosya adı, hata mesajı, uzantı — hepsi değişebilir. Ama “onlarca kullanıcı dosyasına arka arkaya yazıp geri döndürülemez hâle getirmek” eylemi değişmez. Kural tam olarak bu eylemi imzalar.

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.

[1] RING-0 — edrdrv.sys (minifilter) IRP_MJ_CREATE / CLEANUP / WRITE / READ / SET_INFORMATION IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION (mmap yakalama) | | LLE_FILE_CREATE / LLE_FILE_DATA_READ_FULL / LLE_FILE_DATA_WRITE_FULL | LLE_FILE_MAP_READ / LLE_FILE_MAP_WRITE / LLE_FILE_DATA_CHANGE | LLE_FILE_RENAME / LLE_FILE_DELETE v [2] LBVS WIRE PROTOCOL (libsysmon/inc/edrdrvapi.hpp) Sema tabanlı, çözümlenmiş adlandırılmış byte akışı | v [3] libsysmon CONTROLLER (controller.cpp) SysmonEvent -> Event enum eşlemesi, "type" etiketi | v [4] EventEnricher (eventenricher.cpp) Süreç zenginleştirme, processes[] zinciri, dosya nesnesi -> file alanları TAMBEL PROXY (64KB okuma sadece istendiğinde) | v [5] KUYRUK: match_patterns (qsc/match_patterns.qsc) | v [6] PTM POLİTİKA MOTORU (ptm.local.src / RANSOM_BEHAVIOR) | | destination "IN" -> geri dönüş match_patterns (durum makinesi) | destination "OUT" -> enrich_mle kuyruğu (tespit çıkışı) v [7] enrich_mle -> check_for_valkyrie -> transform_for_cloud -> output | v [8] DetectionNotifier (detectionnotifier.cpp) Güven kontrolü -> GID ile ÖLDÜR -> KARANTİNA -> GERİ YÜKLE -> GUI

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.

▶ Neden iki kuyruk?
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önergeNe yaparBu 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
▶ Kritik motor kısıtı: kural başına tek condition
Bir kural sözlüğünde yalnızca bir condition 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

OperasyonArityAnlamıBu Kuralda
imatch1 değer + patternBüyük/küçük harf duyarsız joker eşlemesi*\users\* vb.
!imatch1 değer + patternEşleşmezse trueBeyaz liste kontrolleri
and / or≥ 2Mantıksal birleştirme (kısa devre yok, hepsi değerlendirilir)Süzgeç zinciri
equal / !equaltam 2Tip bazlı eşitliktype == "OTHER", isAsciiText
greatertam 2Tam sayı karşılaştırma; null/bool/string → 0 sayılırEntropi 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çimiDerlenen MotorAnlam
*\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; *→.*, ?→.
▶ Önemli ayrım
Baştaki ve sondaki * 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.

AŞAMA 1 Okuma Tarafının Kaydedilmesi — 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.

ptm.local.src — AŞAMA 1asaveContext / 120000 ms
{
  "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.

▶ Neden bu ayrı madde önemli?
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.
AŞAMA 2 Aday Olayın Üretimi — 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.

MaddeKaynak OlayNe Zaman Üretilir (Kernel)Not
2aLLE_FILE_CREATE IRP_MJ_CREATE sonrası — dosya oluşturuldu veya kırpıldı Yeni şifreli dosya oluşturan modelin ilk adımı
2bLLE_FILE_DATA_WRITE_FULL IRP_MJ_CLEANUP sonrası — dosya baştan sona yazıldı Entropi yalnızca bu olayda ölçülür
2cLLE_FILE_MAP_WRITE ACQUIRE_FOR_SECTION_SYNC — PAGE_READWRITE / WRITECOPY / EXECUTE_READWRITE mmap tabanlı şifreleme
2dLLE_FILE_DATA_CHANGE IRP_MJ_CLEANUP — tutamaç dosyayı kirletmiş Kaba “dosya değişti” bayrağı
2eRF10* — Derlemede düşer (Bölüm 16)
2fLLE_FILE_RENAME IRP_MJ_SET_INFORMATION — FileRenameInformation(Ex) .docx → .docx.locked hamleleri
2gLLE_FILE_DELETE IRP_MJ_CLEANUP — silme bayrağı ya da FileDispositionInformation Özgün dosyayı silip şifreli kopyayı bırakma
2hRF4* — 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:

ptm.local.src — AŞAMA 2b (tüm aday üreticileri bu kalıbı paylaşır)createEvent / IN
{
  "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?
Varsayılan 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.
AŞAMA 3 Adaydan Değerlendirmeye — 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: destination alanı, aşama 2'de @event.file iken burada @event.destination olarak okunur — yani önceki olayın taşıdığı alan.
  • Zaman damgası taşıma: time ve tickTime korunur, böylece sayaç ve analiz zaman çizelgesi doğru kalır.
ptm.local.src — AŞAMA 3createEvent / IN
{
  "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" }
      ]
    }
  }
}
AŞAMA 4 Karar — distinctCounter + Dokuz Süzgeç → MLE_RANSOM_BEHAVIOR

Kuralın kalbi. Burada iki şey aynı anda olur:

  1. 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 = true yazılır.
  2. condition çalışır: dokuz süzgecin tamamı tutmalıdır. Tutan tutarsa nihai tespit olayı OUT ile dışarı çıkar.
▶ Değerlendirme sırası: sayaç ÖNCE, koşul SONRA
Derleyici yönergeleri sabit bir sırada üretir: 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.
ptm.local.src — AŞAMA 4, createEvent (5100-5116)createEvent / OUT — GERÇEK TESPİT
"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 }
  ]
}
▶ En kritik satır: quarantineTarget
Aday aşamasında quarantineTarget ş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.
AŞAMA 5 Bağlam Temizliği — 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.

ptm.local.src — AŞAMA 5deleteContext
{
  "eventType": "LLE_PROCESS_DELETE",
  "rule": {
    "deleteContext": {
      "basket": "@const.ransomBasket.readWrite",
      "group":  "@event.process.id"
    }
  }
}
▶ Dürüst not
Aşama 1a/1b kayıtları 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.

ptm.local.src — AŞAMA 4: distinctCounter + CONDITION (4991-5099)9 FİLTRE
"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 ] }
    ]
  }
}
S1 !imatch(ransomSystemExclusions, @event.process.imageFile.rawPath)
Aktör beyaz listesi. “Şifreleyen süreç” kontrol edilir, “şifrelenen dosya” değil. 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.
S2 !imatch(ransomSystemExclusions, @event.destination.path)
Hedef beyaz listesi. Hedef yolun kendisi 8 sistem kalıbından birine benzememeli. Bkz. Bölüm 11. Bu süzgeç olmadan güncelleme motorları, tarayıcı önbellekleri ve kurulum önbellekleri kuralı periyodik olarak tetiklerdi.
S3 imatch("*\\users\\*", @event.destination.path) — ZORUNLU (+)
Coğrafya daraltması. Tek zorunlu pozitif koşul budur: hedef bir kullanıcı profilinin içinde olmak zorundadır. Fidye yazılımının neden şifrelediği bellidir — 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.
S4 !imatch("*\\appdata\\*", @event.destination.path)
Uygulama verisi koruması. 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.
S5 !imatch("*:Zone.Identifier*", @event.destination.path)
Mark-of-the-Web koruması. NTFS alternatif veri akışlarındaki 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.
S6 equal(@event.destination.type, "OTHER")
Hedef bir çalıştırılabilir değil. Dosya tipi, uzantının yapılandırılmış çalıştırılabilir listesine (.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.
S7 uzantı var AND kullanıcı dosyası uzantısı AND entropi > 6
Üç alt koşulun AND&OR yapısıdır. 7a: hedefte (veya kaynakta) bir nokta bulunmalı — uzantısız geçici dosyalar elenir. 7b: uzantı 1479 kalıplı kullanıcı verisi listesinden biri olmalı. 7c: Shannon entropisi eşiği aşmalı. Bu üçlü, kuralın “bu bir veri dosyası mı, bu şifrelenmiş mi?” sorusuna cevap verir.
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.
S8 !equal(@event.destination.isAsciiText, true) — ASIL METİN KORUMASI
En güçlü tek süzgeç. Dosyanın diskteki güncel ilk 64 KiB'ı okunur, ancak metin olup olmadığına yalnızca ilk 8192 bayta (8 KiB) bakılarak karar verilir: \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:
libsyswin/src/filedataprovider.cpp (1195-1210) — birebirSADECE İLK 8 KiB
// 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;
}
Akış (1217-1236). 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.
S9 equal(@event.RansomThresholdMet, true) — KÜTLE EŞİĞİ
Kuralın can damarı. Diğer sekiz süzgeç tek başına bir dosya işlemini tanımlar; bu süzgeç onu bir saldırıya çevirir. 60 saniye içinde 3 veya daha fazla AYRI hedef dosyaya dokunulmuş olması gerekir. Bkz. Bölüm 8. Tek bir dosyaya yapılan işlem, ne kadar şüpheli olursa olsun asla tetiklemez. Bu, “bir kullanıcı bir fotoğrafını düzenledi” ile “birisi diski şifreliyor” arasındaki farkı kuran şeydir.

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.

ptm.local.src — distinctCounter yapılandırmasıTHRESHOLD 3 / WINDOW 60000ms
"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?

ÖzellikDavranış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

PID 4711 — suspect.exe (0. saniye) yaz C:\Users\alice\Documents\sozlesme.docx -> AYRI #1 sayaç = 1 yaz C:\Users\alice\Photos\tatil.jpg -> AYRI #2 sayaç = 2 yaz C:\Users\alice\Desktop\butce.xlsx -> AYRI #3 RansomThresholdMet = TRUE | +--> S1..S8 doğrulanır ==> MLE_RANSOM_BEHAVIOR | +--> yaz C:\Users\alice\Videos\dogum.mov -> AYRI #4 bayrak HALA TRUE ==> ikinci MLE_RANSOM_BEHAVIOR 60 saniye sonra: tüm kayıtlar bayatlanır, pencere temizlenir 61. saniye: yeni bir yazma -> sayaç yeniden 1'den başlar
▶ Neden 3 ve neden 60 saniye?
3 eşiği, üç sayıyı birden dengeler: (a) tek dosyaya müdahale etmeyen meşru yazılımları eler, (b) iki dosyalık örnek fidye yazılımı numunelerini (test numunelerinde sık görülür) engeller, (c) gerçek şifreleme turlarında dosya sayısı hızla onlara çıktığı için tespiti ertelemez.
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.

AlanKaynağı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
▶ Tembel değerlendirmenin güvenlik ve performans değeri
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

edrdrv/src/ShanonEntropy.cpp + ShanonEntropy.hRING-0 — FLOAT YOK
// 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?

▶ Kernel içinde kayan nokta yasak
Bu hesap Ring-0'da, her yazma işleminin post-operasyonunda çalışır. Kayan nokta işlemleri (SSE/MMX) Windows çekirdeğinde kesin olarak yasaktır — bir istisna, işlem iptaline ve sistem kararsızlığına yol açar.

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?

ÖzellikDeğer
Örnekleme yeriYalnızca yazma işlemi (pre/post write, her MDL sayfası ve her doğrudan tampon)
ÖzetlemeDizideki maksimum parça entropisi
YayınYalnızca LLE_FILE_DATA_WRITE_FULL olayında (owlyEntropy + owlyIsEntropyCalc=1)
Tipuint64 Q24 sabit nokta — ham değer, ölçeklenmemiş
Doğruluk notuSeri 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

İçerikTeorik H (bit/byte)Q24 Ham DeğerKuralda Sonuç
Tamamen sabit (sıfırlar)0,00ELE
İngilizce metin, kaynak kodu, .txt/.js/.html/.json3,5 – 5,058.720.256 – 83.886.080S8 ile elenir
Derlenmiş PE (kod + veri karışımı)6,0 – 7,2100.663.296 – 120.795.955GEÇER
Sıkıştırılmış arşiv (.zip/.7z/.zst)7,9 – 8,0≈132.120.000 – 134.217.728GEÇER
Taze AES/ChaCha şifre metni7,9 – 8,0≈132.120.000 – 134.217.728GEÇER
▶ Ölçekleme kusuru (bilinen sınır)
Sürücü entropiyi ham Q24 tam sayısı olarak yazar (0 … 134.217.728), ancak politika kuralı bunu 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.

ptm.local.src — @const.ransomSystemExclusions (satır 1660-1670)8 KAYIT
// 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ı
Bu kalıp joker içermediği için önek (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.”

ptm.local.src — @const.ransomFileExtensions (satır 137-1619)1479 KAYIT
// 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ÖrneklerAmacı
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
▶ Listeyi daraltan tasarım: iki katmanlı koruma
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:

edrdrv/src/filemon.cpp (2645-2661)MINIFILTER KAYDI
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ı

SysmonEventKodLLE DeğeriÜretim Yeri
FileCreate0x0007LLE_FILE_CREATE = 0x0003postCreate
FileDelete0x0008LLE_FILE_DELETE = 0x0004postCleanup / postSetFileInfo
FileClose0x0009LLE_FILE_CLOSE = 0x0005postCleanup
FileDataChange0x000ALLE_FILE_DATA_CHANGE = 0x0006postCleanup
FileDataReadFull0x000BLLE_FILE_DATA_READ_FULL = 0x0007postCleanup
FileDataWriteFull0x000CLLE_FILE_DATA_WRITE_FULL = 0x0008postCleanup
FileMapRead0x0011LLE_FILE_MAP_READ = 0x0034preAcquireForSectionSync
FileMapWrite0x0012LLE_FILE_MAP_WRITE = 0x0035preAcquireForSectionSync
FileRename0x0014LLE_FILE_RENAME = 0x0032postSetFileInfo
OwlyPreImageSaved0x0017LLE_FILE_PREIMAGE_SAVED = 0x0037RansomShield

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ıtKoşulNeden Ö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
▶ Önemli: bu teknik, BYOVD ve anti-EDR atlatmaya dayanık
Biçim yazılımında yazan zarilı, özgün dosyanın üzerine in-place yazar, çift dosya üretir ya da yeni dosya oluşturup orijinali siler. Bu üç modelin üçü de “IRP_MJ_CREATE + WRITE/CLEANUP + SET_INFORMATION” izi bırakır — API hooking yapmadan yakalanır. Klasik kancalama tabanlı AV'ler (usermode) bunu görmez; Ring-0 minifilter görür.

12.3 — mmap yolu: görünmez olanın yakalanması

edrdrv/src/filemon.cpp (2564-2573) — sürücü yorumu, birebirNEDEN AYRI BİR IRP?
/*  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.

▶ Modern şifreleyicilerin tercihi
Rust (özgür yazılım dili), Go ve C++ ile yazılan profesyonel fidye yazılımlarının belirgin bir bölümü dosyaları 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:

FaydaAçı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.
▶ Kurumsal mimari dersi
Toplama ile karar ayrımı, büyük olay işleme sistemlerinde standart bir kalıptır. Kural bu kalibi veritabanında değil, dosya sistemi gözleminde uygular. Ucuz, denetlenebilir ve üzerine inşa edilebilir.

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.

MLE_RANSOM_BEHAVIOR (baseType 1000008, OUT) | |--> [1] severity = 3 (CRITICAL) + alert_kind = "critical" <-- her tespitte sabit | |--> [2] Başlık sentezi + quarantineTarget kilidi | <- @event.process.imageFile.rawPath (SALDIRGANIN İKİLİSİ) | |--> [3] OwlyShield verdict senkronizasyonu (owlyshield_update_process_verdict) | |--> [4] GÜVEN KONTROLÜ (aşağıda ayrıntılı) | should_trust_company_whitelist = true | should_trust_comodo_fls_cloud = true | -> güvenilir imzalı / FLS SAFE ==> öldürme + karantina İPTAL | -> kötü / PUA üreticisi ==> sıkı uygulama (strict enforcement) | |--> [5] SÜRECİ ÖLDÜR — edrdrv IOCTL | DeviceIoControl(\\.\\{157980D8-09B4-4580-B8B6-D32971D056DA}) | msgType = 6 (MESSAGE_KILL_ONLY_GID), hedef = Global ID | |--> [6] KARANTİNA — owlyshield_ransom.dll | owlyshield_dll_quarantine_file(dosyaYolu) | + recordMalwareDetection() (kalıcı veritabanı kaydı) | hata hâlinde: \\.\pipe\HydraHipEvent üzerinden | "Malicious file locked! Please restart your computer..." | |--> [7] GERİ YÜKLE — EventEnricher::rollbackRansomBackups() | Süreç, kök süreç, sadece GID — üçü için ön-image geri yükleme | (RansomShield'in %PROGRAMDATA%\HydraDragonBackups altına | kaydettiği özgün kopyalar) | +--> [8] GUI bildirimi + 1000 kayıtlı halka tamponuna ekleme

14.1 — Neden quarantineTarget sürecin imajıdır?

▶ Kritik mimari karar
Aday aşamasında 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_*

BayrakDeğerEtkisi
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.
▶ Bu seçim bilinçli ve doğru
Fidye yazılımının “çalıştırılan dosyası” çoğu zaman imzasız bir ara binary olabilir (LiveWire, PowerShell, script host, imza çalıntısı kod). Bu yüzden 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.
▶ Zararsızlaştırmada yapılmayanlar
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.

R01 • BAĞIMSIZLIK
Koddan tamamen bağımsız
Kural, dosyanın içeriğine, hash'ine, derleyicisine, paketleyicisine ve boyutuna bile bakmaz. Zararlı kodu tamamen değiştirilse, yeniden paketlense, yeni bir dilde yeniden yazılsa — kural aynen çalışır. Bu, tek başına sıfırıncı gün kapsamıdır.
R02 • ZORUNLULUK
Şifreleme zorunlu bir adımdır
Fidye yazılımının amacını yerine getirmesi için dosyayı geri döndürülemez şekilde bozması şarttır. “Yok et", “şifrele", “uzaktan sil" — üçü de aynı dosya sistemi izini bırakır. Bu, kuralı zorunlu bir davranışa bağlar: atlanması mümkün değildir.
R03 • ADLIMSIZ
Şifreleme çift taraflıdır
Aile, varyant, derleme tarihi, dil, paketleyici — hiçbiri önemsizdir. Kural “bu bir LockBit” değil, “bu bir şifreleme” der. Bu yüzden yeni varyantlar ayrı iş değildir.
R04 • RING-0
Çekirdekte gözlem
Tespit usermode kancalarına değil, IRP'lere bakar. Bu, iki kritik avantaj sağlar: (a) usermode API kaçakları çalışmaz, (b) BYOVD ile antivirüsün bellekten silinmesi tespiti engellemez — motor çoktan çalışıyordur.
R05 • MMAP
Görünmeyi izlemeyi yakalar
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.
R06 • KÜTLE
Tek işlem yeterli değil
60 saniyede 3 ayrı hedef eşiği, tek dosya işlemlerini tamamen devre dışı bırakır. Bu, kuralın en önemli FP güvenlik ağıdır: “bir kullanıcı bir dosyasıyla uğraştı” ile “birisi toplu şifreliyor” birbirinden matematiksel olarak ayrılır.
R07 • AYRIK SAYIM
Tekrarlar sayılmaz
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.
R08 • SÜREÇ İZOLASYONU
Anahtar = PID
Sayaç süreç başına tutulur. İki farklı uygulama birbirinin sayacını dolduramaz; bir tarayıcı eklentisi başka bir sürecin başarısını “miras" alamaz. Bu, kurumsal ortamda yanlış pozitif zincirini kırar.
R09 • İÇERİK KANITI
İçerik, dosya adına değil
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ı.
R10 • KONTROL MEKANİZMASI
Tembel değerlendirme
İçerik taraması yalnızca kural o alana gerçekten dokunduğunda çalışır. Dokunulduğunda 64 KiB'lık I/O yapılır ama karar ilk 8 KiB'de fail-fast verilir. Aynı kural, hem canlı bir sistemde kullanılabilir hem de ispatlanabilir bir FP oranına sahiptir. “Sıkışık ama yavaş" değil.
R11 • KURTARMA
Sadece tespit değil, kurtarma
Karantina saldırganın ikilisine uygulanır, kullanıcının verisi geri yüklenir (RansomShield ön-image). Tespit edilen ama verisi kaybedilen bir sistem, kurtarılmış sayılmaz. Bu kural, tespit ile eylemi birleştirir.
R12 • DENETLENEBİLİRLİK
Kapalı kutu değil, okunabilir politika
Kural JSON'da, 16 madde hâlinde, her hâliyle duruyor. Şu an okuduğunuz her şey ürünün içinde birebir var. “Neden bu alarmı attı?” sorusunun cevabı bir destek talebine değil, bir ekran görüntüsüne gelir. Bu, projenin temel felsefesidir: Security by Obscurity değil, Security by Legibility.

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ğiKurala EtkisiNeden
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
▶ Matematiksel özet
Korunan: İmza değişimi, paketleme, API kaçakları, kod tamamen yeniden yazımı, mmap, yerleşik API'ler, yeni dil, yeni derleyici, uzaktan çalıştırma.
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ırEtkiDü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

▶ KUSUR 1 — Üç kural maddesi birebir tekrar ediyor
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.
▶ KUSUR 2 — RF10* ve RF4* derlemede düşer
Politika derleyicisi, joker içeren eventType 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.
▶ KUSUR 3 — Okuma sepeti yazılıyor ama okunmuyor
Aşama 1a ve 1b, 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.
▶ KUSUR 4 — Aşama 5 temizliği eşleşmiyor
Aşama 1 kayıtları 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.
▶ KUSUR 5 — Entropi ölçeklenmemiş
Sürücü entropiyi ham Q24 tam sayısı yazar; politika ise onu 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.
▶ KUSUR 6 — @event.source daima null
source 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.
▶ KUSUR 7 — Yorum dosyası ile kod uyuşmuyor
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ı

▶ Bu sayfa neden var?
Bir EDR'in kalitesi, hata oranından çok, hatalarını ne kadar hızlı ve dürüstçe kabul ettiğiyle ölçülür. Yukarıdaki yedi kusur, kapatılmamış olabilir; ama bilinmektedir. Bu, projenin “Security by Obscurity yerine Security by Legibility” felsefesinin somut uygulamasıdır.

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 / OlaybaseTypeGö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.
ptm.local.src — @const.ransomShadowDeleteCmdLines7 KOMUT KALIBI
"ransomShadowDeleteCmdLines": [
  "*vssadmin*delete shadows*",
  "*wmic*shadowcopy delete*",
  "*wmic*shadowcopy*delete*",
  "*wbadmin*delete catalog*",
  "*bcdedit*recoveryenabled*no*",
  "*wbadmin*delete systemstatebackup*",
  "*vssadmin*resize shadowstorage*"
]
▶ Birlikte çalışma sırası
1. vssadmin delete shadows → MLE_RANSOM_SHADOW_COPY_DELETE
2. CryptEncrypt çağrıları → CRYPTO_API_MASS
3. Kullanıcı dosyaları okunur → RansomShield ön-image yedek alır
4. Dosyalar şifrelenir → MLE_RANSOM_BEHAVIOR (3. dosyada tetikler)
5. Süreç öldürülür, ikili karantinaya alınır
6. rollbackRansomBackups 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

AlanSorulacak SoruKritik Değer
quarantineTargetHangi ikili karantinaya alındı?Dosya adı, yolu, imzası
process.id / process.pidGlobal ID nedir? (kill hedefi)Önemli — analiz izinde kullanılır
process.cmdLineNasıl başlatıldı?powershell -enc, mshta, wmic ipuçları
process.imageFile.rawPathNerede duruyordu?%APPDATA%, %TEMP% = yüksek öncelik
destination.pathHangi dosyaya dokundu?Son vurulan hedef (tek dosya, < 3 ise eşik tutmadı)
destination.abstractPathHedefin “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 / tickTimeZaman çizelgesi nasıl?İlk olay, 3. dosya, şifreleme süresi

18.2 — Yanlış pozitif triage kararı

GörünenDeğerlendirmeKarar
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:

SIK KULLANILACAK AYAR NOKTALARI4 SATIR
// 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\\*" ]
▶ Uyarı
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

01Bu kural bir YARA kuralı mı?
Hayır. Bu bir PTM v2 politika kuralıdır (JSON), C++ motorunda değerlendirilir. YARA × Viruskov projesinde ayrıca ve birbirini tamamlayıcı olarak çalışır: YARA dosyanın içeriğine bakar, MLE_RANSOM_BEHAVIOR ise eyleme. İkisi birlikte hem statik hem dinamik kapsama sahiptir.
02Tek bir dosyayı şifreleyen zararlı yakalanır mı?
Hayır. S9 süzgeci 60 saniyede en az 3 ayrı hedef ister. Bu bilinçli bir tasarım kararıdır: tek dosya şifrelemek çoğu zaman kullanıcı ya da yedekleme yazılımı davranışıdır. Kuralı tek dosyada çalıştırmak isteyenler için threshold: 1 denenebilir — ama yanlış pozitif oranı ciddi şekilde artar.
03Sadece metin dosyalarını şifreleyen zararlı?
Hayır, bu kapsam dışıdır. S8 (!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.
04Antivirüsüm zaten var, bu neden gerekli?
Üç somut neden: (1) Ticari AV'ler kullanıcı modunda çalışır; BYOVD ile bir kerede bellekten silinebilirler — bu kural zaten çalışırken tespit yapar. (2) Güç veya ağ bağlantısı durumunda beyaz listeler güncellenemez; bu kural harici imza istemez. (3) Sigorta, denetim ve olay tespiti (DFIR) için kanıt niteliğinde bir zaman çizelgesi üretir.
05Verilerim ne olacak, gerçekten geri yükleniyor mu?
Evet, dosya sistemi diskinin zaten orijinal verisini koruyorsa. Minifilter, bir dosyaya in-place yazmadan önce 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.
06Kural güvenilir bir yazılım tarafından tetiklenirse?
İki katmanlı koruma var. (1) S1/S2 beyaz listesi, (2) 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.
07Gerçek bir numune ile örneklenebilir mi?
Evet — YouTube'daki sıfırıncı gün örneği ile kuralın canlı bir tespit görüntüsü paylaşılmıştır.
Ö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.
08Bu kuralı kim, hangi süreç için yazdı?
Kural, OpenEDR (COMODO tarafından açık kaynak yayımlanmış EDR çekirdeği) fork'u üzerinde, VIRUSKOV / Hydra Dragon projesi kapsamında geliştirilmiştir. Proje lideri: Emirhan Uçan. Tüm kaynak kod açık depoda durur; bu sayfadaki her iddia doğrudan o koddan alınmıştır.

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.src
4636–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ı
Kural Kimliği
RANSOM_BEHAVIOR / MLE_RANSOM_BEHAVIOR
baseType
1000008
Motor
PTM v2 (PatternsMatching / EVM)
Tespit Katmanı
Ring-0 (edrdrv.sys minifilter) + User-mode politika motoru
Kural Maddesi
16 (3 tanesi tekrarlı / ölü kod — Bkz. Bölüm 16)
Eşik
3 ayrı hedef / 60000 ms kayan pencere
Güven Seviyesi
3 — CRITICAL
Yanıt
Karantina (saldırgan ikilisi) + GID ile öldürme + ön-image geri yükleme
Lisans
Açık kaynak (OpenEDR fork: BSD-3 / VirusKat katkıları)
RANSOM_BEHAVIOR
MLE_RANSOM_CANDIDATE
MLE_RANSOM_EVALUATE
distinctCounter
saveContext
createEvent
imatch
StringMatcher
Shannon Entropy Q24
minifilter
IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION
isAsciiText
RansomShield
OwlyShield
Ring-0
PTM v2
EDR
anti-ransomware
✦ Destek, Katkı ve Bağış

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.

✉ [email protected]

Konu satırında kısa bir açıklama yazmanız yeterli: [KATKI], [KURAL], [BİLGİ] veya [DESTEK].

← VIRUSKOV ANA SAYFA BAŞLIĞA DÖN ↑