---
title: 'Tespit Mühendisliği'
source: 'https://academia.sh/tr/kurslar/guvenlik-operasyonlari/tespit-muhendisligi'
course: 'Güvenlik Operasyonları ve Olay Müdahalesi'
language: tr
updated: '2026-08-17T18:08:41+00:00'
license: 'CC BY-SA 4.0'
---

# Tespit Mühendisliği

Sekiz taktik sütunu ve 26 teknik satırı olan kurgu bir sınıflandırma matrisinde iki kural sürümü karşılaştırılır: sürüm 1'in 6 kuralı 11 tekniği kapsıyor ama yalnız 8'i ateşlenebilir, 15 teknik hiç kapsanmıyor; sürüm 2'nin 11 kuralı 24 tekniği kapsıyor, 19'u ateşlenebilir, hiç kapsanmayan 2'ye iniyor. 51 kurgu örnek üzerinde sürüm 1 10 örnek yakalıyor, sürüm 2 30; kaçırmanın nedeni ayrıştırıldığında kural yokluğu 32'den 3'e inerken kaynak yokluğu 4'ten 11'e çıkıyor. Ek 220 dakikalık yazma işi örnek başına 11 dakikaya geliyor, günlük yanlış pozitif 30'dan 27'ye düşüyor ama inceleme yükü 360 dakikadan 513 dakikaya çıkıyor.

Bir önceki derste bandı daraltan şey eşik ayarı değil, yeni bir öznitelikti — yani puanlamanın
kendisinin değişmesi. Bu, bir kuralın ayarlanması değil **yeniden yazılmasıdır** ve düzenli yapılan
bir iştir. Tespit mühendisliği o işin adıdır: kural yaz, koştur, kaçırdığını ölç, düzelt.

Döngünün ölçüsü kaç kural yazıldığı olamaz, çünkü kural sayısı ne kapsamayı ne de doğruluğu verir.
Bu ders ölçüyü bir sınıflandırma matrisi üzerinden kurar. Matris **yapısıyla** ele alınır: sütunlar
taktik, satırlar tekniktir; buradaki teknikler ve izleri **kurgudur** ve gerçek bir sınıflandırma
çalışmasının içeriğine karşılık gelmez.

- **TA28.** Matriste 8 taktik sütunu ve 26 teknik satırı vardır. Her teknik satırı, izinin hangi
  kaynağa düştüğüyle etiketlidir.
- **TA29.** Bir teknik üç durumdan birindedir: izi **toplanan** bir kaynağa düşer, izi toplanmayan
  bir kaynağa düşer, ya da **hiçbir kaynakta iz bırakmaz**. Son iki durumda kural yazılabilir ama
  ateşlenemez.
- **TA30.** Kural bir veya birkaç tekniği kapsar. Her kuralın üç sayısı vardır: yazma ve ayarlama
  dakikası, duyarlılık, günlük yanlış pozitif. Üçü de model verisidir.
- **TA31.** **Kapsanan** teknik, en az bir kuralın hedeflediği tekniktir. **Ateşlenebilir kapsama**,
  bunun kaynağı toplanan alt kümesidir. İkisi arasındaki fark kağıt üstünde kalan kapsamadır.
- **TA32.** Örnek kümesi tekniklerin kurgu örneklerinden oluşur ve iki sürüm için **aynıdır**;
  karşılaştırmanın anlamı buna bağlıdır.

## Matriste Kapsama ve İki Sürüm

```js
// kapsam.mjs — taktik ve teknik matrisinde iki kural surumunun kapsamasi. MODELDIR.
// Matris yapisiyla ele alinir: sutunlar taktik, satirlar teknik. Teknikler kurgudur.
export const TAKTIK = [["ilk erisim", 3], ["calistirma", 4], ["kalicilik", 4],
  ["yetki yukseltme", 3], ["kimlik bilgisi elde etme", 4], ["kesif", 3],
  ["yanal hareket", 3], ["sizdirma", 2]];

// Her teknigin izi hangi kaynakta duser: K kimlik, U uc nokta, A ag akisi,
// Y yonetim duzlemi, S toplanMAYAN sunucu uygulama gunlugu, - hicbir kaynakta iz yok.
const IZ = "KUS UAUY U-UA KYS K-UY AAU S-K AA".replace(/ /g, "").split("");
export const TEKNIK = [];
for (const [taktik, n] of TAKTIK)
  for (let k = 0; k < n; k++) {
    const i = TEKNIK.length;
    TEKNIK.push({ id: `t${String(i + 1).padStart(2, "0")}`, taktik, iz: IZ[i] });
  }
// Hatta toplanan kaynaklar (model verisi). S kaynagi vardir ama toplanmamaktadir.
export const TOPLANAN = new Set(["K", "U", "Y", "A"]);

// Kural: [ad, kapsadigi teknik indeksleri, yazma+ayarlama dakikasi, duyarlilik, gunluk yanlis poz.]
export const SURUM1 = [["s1", [0, 2], 90, 0.8, 3], ["s2", [6, 8], 120, 0.7, 5],
  ["s3", [12, 16], 150, 0.6, 4], ["s4", [20, 23], 90, 0.75, 2],
  ["s5", [1, 13], 180, 0.5, 9], ["s6", [4], 240, 0.4, 7]];
export const SURUM2 = [["s1", [0, 2], 30, 0.85, 2], ["s2", [6, 8], 40, 0.8, 2],
  ["s3", [12, 16], 40, 0.7, 2], ["s4", [20, 23], 20, 0.8, 1],
  ["s5", [1, 13, 17], 60, 0.6, 3], ["s7", [3, 9], 150, 0.7, 3],
  ["s8", [5, 10, 14], 210, 0.65, 4], ["s9", [18, 21], 180, 0.55, 3],
  ["s10", [7, 11], 120, 0.5, 2], ["s11", [24, 25], 90, 0.6, 2],
  ["s12", [15, 19], 150, 0.45, 3]];

export function kapsama(kurallar) {
  const kapsanan = new Set(kurallar.flatMap(([, l]) => l));
  const say = (f) => [...kapsanan].filter((i) => f(TEKNIK[i].iz)).length;
  return { kapsanan, atesle: new Set([...kapsanan].filter((i) => TOPLANAN.has(TEKNIK[i].iz))),
    toplanmayan: say((z) => z === "S"), izsiz: say((z) => z === "-"),
    hic: TEKNIK.length - kapsanan.size,
    dakika: kurallar.reduce((a, k) => a + k[2], 0),
    yp: kurallar.reduce((a, k) => a + k[4], 0) };
}

if (import.meta.url === `file://${process.argv[1]}`) {
  const gen = (B) => (h) => h.map((v, j) => (j ? String(v).padStart(B[j])
    : String(v).padEnd(B[0]))).join("");
  const yt = gen([26, 8, 10, 12, 12]);
  const k1 = kapsama(SURUM1), k2 = kapsama(SURUM2);
  console.log(`matris: ${TAKTIK.length} taktik sutunu, ${TEKNIK.length} teknik satiri; ` +
    `${TEKNIK.filter((t) => t.iz === "S").length} teknigin kaynagi toplanmiyor, ` +
    `${TEKNIK.filter((t) => t.iz === "-").length} teknigin hicbir kaynakta izi yok`);
  console.log();
  console.log(yt(["taktik", "teknik", "surum 1", "surum 2", "izi olmayan"]));
  for (const [taktik] of TAKTIK) {
    const l = TEKNIK.filter((t) => t.taktik === taktik);
    const say = (s) => l.filter((t) => s.has(TEKNIK.indexOf(t))).length;
    console.log(yt([taktik, l.length, say(k1.kapsanan), say(k2.kapsanan),
      l.filter((t) => !TOPLANAN.has(t.iz)).length]));
  }
  const yk = gen([10, 8, 12, 15, 14, 10, 16, 11]);
  console.log();
  console.log(yk(["surum", "kural", "kapsanan", "ateslenebilir", "kaynagi yok",
    "izi yok", "hic kapsanmaz", "yazma dk"]));
  for (const [ad, k, l] of [["surum 1", k1, SURUM1], ["surum 2", k2, SURUM2]])
    console.log(yk([ad, l.length, `${k.kapsanan.size}/${TEKNIK.length}`,
      `${k.atesle.size}/${TEKNIK.length}`, k.toplanmayan, k.izsiz, k.hic, k.dakika]));
}
```

```
matris: 8 taktik sutunu, 26 teknik satiri; 3 teknigin kaynagi toplanmiyor, 3 teknigin hicbir kaynakta izi yok

taktik                      teknik   surum 1     surum 2 izi olmayan
ilk erisim                       3         3           3           1
calistirma                       4         2           3           0
kalicilik                        4         1           4           1
yetki yukseltme                  3         2           3           1
kimlik bilgisi elde etme         4         1           4           1
kesif                            3         1           3           0
yanal hareket                    3         1           2           2
sizdirma                         2         0           2           0

surum        kural    kapsanan  ateslenebilir   kaynagi yok   izi yok   hic kapsanmaz   yazma dk
surum 1          6       11/26           8/26             2         1              15        870
surum 2         11       24/26          19/26             3         2               2       1090
```

Taktik tablosu ilk bulguyu veriyor: sürüm 1'in kapsaması **eşit dağılmamıştır**. İlk erişim satırının
üçü de kapsanıyor, sızdırma satırının hiçbiri kapsanmıyor. Bu, tespit yazımının doğal eğilimidir —
kolay kural, alanları ayırt edici olan kaynakta yazılır ve o kaynak genellikle zincirin başındadır.
Sonuç bir kapsama haritasında değil, **kaçırılan kalemlerde** görünür. Sızdırma satırının boş
kalması, o taktiğin önemsiz görülmesinden değil, izinin ağ akış verisinde bulunmasından ve o
kaynakta ayırt edici bir kural yazmanın dördüncü derste ölçülmüş güçlüğünden gelir.

Alt tablodaki iki sütun arasındaki fark dersin ana kavramıdır. Sürüm 1 on bir tekniği kapsıyor ama
yalnız sekizi ateşlenebilir: üç teknikte kural vardır ve hiçbir zaman tetiklenmez. Bunların ikisinde
kaynak vardır ama hatta toplanmıyor, birinde teknik hiçbir kaynakta iz bırakmıyor. "Yirmi altı
tekniğin on birini kapsıyoruz" cümlesi bu ayrım yazılmadığında **yanlış bir cümledir**.

Sürüm 2 kapsamayı 24'e, ateşlenebilir kapsamayı 19'a çıkarıyor ve hiç kapsanmayanı 15'ten 2'ye
indiriyor. Kalan iki tekniğin biri hiçbir kaynakta iz bırakmadığı için kapsanamaz; öteki
kapsanabilirdi ama sürüm 1'deki bir kural döngüde **kaldırıldı**. Yazma işi 870 dakikadan 1.090
dakikaya çıktı; bu sayı yeni kuralların yanı sıra eski kuralların ayarlanmasını da içerir ve ilk
dört kuralın ikinci sürümdeki dakikaları belirgin biçimde düşüktür, çünkü ayarlamak yazmaktan
ucuzdur.

## Sürümleri Aynı Örnek Kümesinde Koşturmak

```js
// dongu.mjs — iki kural surumu kurgu ornek kumesinde kosturulur; kacirmanin nedeni ayrilir.
import { TEKNIK, TOPLANAN, SURUM1, SURUM2, kapsama } from "./kapsam.mjs";

const uretec = (t) => { let s = t >>> 0;
  return () => (s = (s * 1664525 + 1013904223) >>> 0) / 4294967296; };
const INCELEME = 9;
// Kurgu ornek kumesi: her teknikten 0-4 ornek. Ornek sayisi VERIDIR.
const ORNEK = [];
{
  const r = uretec(20260406);
  for (const [i] of TEKNIK.entries())
    for (let k = 0, n = Math.floor(r() * 5); k < n; k++) ORNEK.push({ teknik: i, z: r() });
}

function kostur(kurallar) {
  const k = kapsama(kurallar);
  const sonuc = { yakalanan: 0, kuralYok: 0, kaynakYok: 0, duyarlilik: 0 };
  const atesleyen = new Set(), pay = new Map(kurallar.map(([ad]) => [ad, 0]));
  for (const o of ORNEK) {
    const kapsayan = kurallar.filter(([, l]) => l.includes(o.teknik));
    if (kapsayan.length === 0) { sonuc.kuralYok++; continue; }
    if (!TOPLANAN.has(TEKNIK[o.teknik].iz)) { sonuc.kaynakYok++; continue; }
    const en = Math.max(...kapsayan.map(([, , , d]) => d));
    if (o.z < en) {
      sonuc.yakalanan++;
      kapsayan.forEach(([ad]) => { atesleyen.add(ad); pay.set(ad, pay.get(ad) + 1); });
    } else sonuc.duyarlilik++;
  }
  const olu = kurallar.filter(([ad]) => !atesleyen.has(ad)).map(([ad, l]) => {
    const tk = l.filter((i) => !TOPLANAN.has(TEKNIK[i].iz)).length;
    const orn = ORNEK.filter((o) => l.includes(o.teknik)).length;
    return `${ad} (${l.length} teknik, ${tk} tanesinin kaynagi yok, ${orn} ornek)`;
  });
  return { ...sonuc, yp: k.yp, dakika: k.dakika, olu, pay,
    inceleme: (sonuc.yakalanan + k.yp) * INCELEME };
}

const gen = (B) => (h) => h.map((v, j) => (j ? String(v).padStart(B[j])
  : String(v).padEnd(B[0]))).join("");
const yz = gen([10, 8, 11, 11, 12, 13, 13, 13]);
console.log(`kurgu ornek kumesi: ${ORNEK.length} ornek, ${TEKNIK.length} teknige dagilmis`);
console.log();
console.log(yz(["surum", "ornek", "yakalanan", "kural yok", "kaynak yok", "duyarlilik",
  "yanlis poz.", "inceleme dk"]));
const [a, b] = [SURUM1, SURUM2].map(kostur);
for (const [ad, s] of [["surum 1", a], ["surum 2", b]])
  console.log(yz([ad, ORNEK.length, s.yakalanan, s.kuralYok, s.kaynakYok, s.duyarlilik,
    s.yp, s.inceleme]));
console.log(`\nhic ateslenmeyen kural — surum 1: ${a.olu.join(", ") || "yok"}; ` +
  `surum 2: ${b.olu.join(", ") || "yok"}`);
console.log(`surum 2 ek ${b.dakika - a.dakika} dakika yazma isiyle ` +
  `${b.yakalanan - a.yakalanan} ek ornek yakaliyor: ornek basina ` +
  `${Math.round((b.dakika - a.dakika) / (b.yakalanan - a.yakalanan))} dakika`);
console.log(`gunluk yanlis pozitif ${a.yp} -> ${b.yp}, gunluk inceleme ` +
  `${a.inceleme} -> ${b.inceleme} dakika`);

const yp = gen([8, 9, 13, 12, 12, 11, 17]);
console.log("\nsurum 2 kural bazinda:");
console.log(yp(["kural", "teknik", "kaynagi yok", "yakaladigi", "gunluk yp", "yazma dk",
  "ornek basina dk"]));
for (const [ad, l, dk, , fp] of SURUM2) {
  const n = b.pay.get(ad);
  console.log(yp([ad, l.length, l.filter((i) => !TOPLANAN.has(TEKNIK[i].iz)).length, n, fp, dk,
    n ? Math.round(dk / n) : "-"]));
}
```

```
kurgu ornek kumesi: 51 ornek, 26 teknige dagilmis

surum        ornek  yakalanan  kural yok  kaynak yok   duyarlilik  yanlis poz.  inceleme dk
surum 1         51         10         32           4            5           30          360
surum 2         51         30          3          11            7           27          513

hic ateslenmeyen kural — surum 1: s6 (1 teknik, 0 tanesinin kaynagi yok, 1 ornek); surum 2: s9 (2 teknik, 1 tanesinin kaynagi yok, 3 ornek)
surum 2 ek 220 dakika yazma isiyle 20 ek ornek yakaliyor: ornek basina 11 dakika
gunluk yanlis pozitif 30 -> 27, gunluk inceleme 360 -> 513 dakika

surum 2 kural bazinda:
kural      teknik  kaynagi yok  yakaladigi   gunluk yp   yazma dk  ornek basina dk
s1              2            1           1           2         30               30
s2              2            1           4           2         40               10
s3              2            0           3           2         40               13
s4              2            0           3           1         20                7
s5              3            1           4           3         60               15
s7              2            0           5           3        150               30
s8              3            0           1           4        210              210
s9              2            1           0           3        180                -
s10             2            0           3           2        120               40
s11             2            0           5           2         90               18
s12             2            1           1           3        150              150
```

Kaçırmanın üç nedeni ayrı sütunlarda duruyor ve döngünün ne yaptığını tam olarak bu ayrım gösteriyor.
Sürüm 1'de 41 kaçırmanın 32'si kural yokluğundandır; sürüm 2'de bu sayı 3'e iner. Buna karşılık
kaynak yokluğu 4'ten 11'e **çıkar**. Bu artış bir gerileme değildir: kural yazıldıkça, kaçırmanın
nedeni kural eksikliğinden kaynak eksikliğine kayar. İkinci sütun tükendiğinde geriye kalan sayı
kural yazarak azaltılamaz; toplama kararı gerektirir.

Duyarlılık sütunu üçüncü nedeni tutuyor: kural var, kaynak var, ama örnek kuralın eşiğini geçmedi.
Bu sayı 5'ten 7'ye çıkıyor, çünkü sürüm 2 daha çok tekniği kapsıyor ve yeni kuralların duyarlılığı
düşüktür. Bir kural kümesini büyütmek, kaçırmanın **dağılımını** değiştirir; her nedeni birden
küçültmez. Üç sütunun üçü de ayrı bir işe karşılık gelir: birincisi kural yazmayı, ikincisi toplama
kararını, üçüncüsü bir önceki dersteki eşik ve öznitelik çalışmasını gerektirir. Aynı sayıyı
"kaçırılan" diye tek sütunda toplamak, hangi işin yapılacağını belirsiz bırakır.

Ölü kural satırı bakımın gizli kalemidir. Sürüm 1'de s6 hiç ateşlenmedi ve o kural 240 dakika yazma
işi tüketmişti; sürüm 2'de s9 hiç ateşlenmedi ve kapsadığı iki teknikten birinin kaynağı zaten
toplanmıyor. Ölü kural bir kapsama tablosunda **kapsanan** olarak görünür, bir uyarı listesinde hiç
görünmez ve her sürüm yükseltmesinde yeniden gözden geçirilir.

Döngünün faturası şudur: ek 220 dakikalık yazma işi 20 ek örnek yakalıyor, örnek başına 11 dakika.
Günlük yanlış pozitif 30'dan 27'ye iniyor — kural sayısı neredeyse ikiye katlandığı hâlde düşüyor,
çünkü sürüm 1'in en gürültülü kuralı kaldırıldı. Ama günlük inceleme yükü 360 dakikadan 513 dakikaya
çıkıyor: doğru tespitin de bir inceleme maliyeti vardır ve iyi bir kural kümesi vardiyayı
rahatlatmaz, **doldurur**.

Kural bazındaki son tablo ortalamanın gizlediğini açıyor. Örnek başına dakika sütunu 7 ile 210
arasında değişiyor: s4 yirmi dakikalık ayarlamayla üç örnek yakalıyor, s8 iki yüz on dakikalık
yazma işiyle bir örnek. İkisi de kapsama tablosunda birer satırdır ve orada aynı görünürler.
Kapsamayı ölçü almak bu yüzden yetmez; **kapsanan gözün kaç örnek getirdiği** ayrı bir sayıdır.

Aynı tabloda `kaynagi yok` sütunu beş kuralda sıfırdan büyüktür. Bu kurallar iki teknik kapsadıkları
hâlde yalnız birinde ateşlenebilir; kapsama sayımına iki, ateşlenebilir sayıma bir katkı verirler.
En uç örnek s9'dur: iki teknik, biri toplanmayan kaynakta, gün boyu sıfır yakalama, 180 dakika
yazma işi. Bir kuralın iyi ya da kötü olduğu ancak koşturulduktan sonra söylenebilir ve koşturmanın
kendisi bu döngünün asıl adımıdır.

## Özet

- Kapsanan teknik ile ateşlenebilir kapsama ayrı sayılır: sürüm 1 on bir tekniği kapsıyor ama
  yalnız sekizi ateşlenebilir, üçünde kural vardır ve hiçbir zaman tetiklenmez.
- Kapsama taktikler arasında eşit dağılmıyor; sürüm 1 ilk erişim satırının üçünü de kapsarken
  sızdırma satırının hiçbirini kapsamıyor.
- Sürüm 2 kapsamayı 24'e, ateşlenebilir kapsamayı 19'a çıkarıyor ve hiç kapsanmayanı 15'ten 2'ye
  indiriyor; kalan ikiden biri hiçbir kaynakta iz bırakmadığı için kapsanamaz.
- Kural yazıldıkça kaçırmanın nedeni kayıyor: kural yokluğu 32'den 3'e inerken kaynak yokluğu 4'ten
  11'e çıkıyor ve o sayı kural yazarak azaltılamaz.
- Ek 220 dakikalık yazma işi örnek başına 11 dakikaya geliyor; günlük yanlış pozitif 30'dan 27'ye
  düşerken inceleme yükü 360 dakikadan 513 dakikaya çıkıyor.
- Kural bazında verim 7 ile 210 dakika arasında değişiyor ve kapsama tablosunda bu fark görünmez;
  s9 iki tekniği kapsadığı hâlde hiç ateşlenmiyor ve 180 dakikalık yazma işi karşılıksız kalıyor.

## Sonraki Adım

Sürüm 2'den sonra 51 örneğin 21'i hâlâ kaçıyor ve bunların 11'i hiçbir kuralın ulaşamayacağı yerde:
kaynağı toplanmayan ya da hiç iz bırakmayan tekniklerde. Kural yazmak bu sayıyı azaltmaz, çünkü
kural ancak sorabildiği alanı sorar. Sonraki ders başka bir yoldan gider: kuraldan değil,
**hipotezden** başlar. Bir hipotez veri kümesine bir soru sorar ve yanıtı bir uyarı değil, elenen
kalem sayısıdır. Ölçü orada hipotez başına kaç kalemin elendiği, kaç hipotezin sıfır sonuç verdiği
ve elenen kalemlerin kaçının yeni bir kurala dönüştüğüdür.
