İçeriğe geç
academia.sh

Ders 10 / 11

Saldırı Ağaçları

Hedeften geriye çözümlemenin maliyet ölçümü: 12 yaprak ve üç alt hedeften oluşan ağaçta kök maliyetinin 9 kurgu birim ve en ucuz yolun iki adım olması, 12 yaprağın 10'unu kapatmanın kök maliyetini hiç değiştirmemesi, en verimli tek kapatmanın 2 önlem birimiyle 1,22 kat getirmesi, dört önlem birimlik bir VEYA düğümünün 1,89 kat vermesi, açgözlü sıranın kökü 28 birimde kapatması ve aynı sonucun dal başına bir VEYA düğümü seçilerek 16 birimde alınması.

İçindekiler

Önceki dersin en dikkat çekici bulgusu zincir tehditleriydi: on iki kalem, hiçbir tek öğede tanımlı değil, yalnız yol üzerinde görünüyor. Ama o ders yolları yalnız saydı; beş senaryonun beşi de listede eşit ağırlıkta durdu.

Gerçekte yollar eşit değildir. Bir hedefe birden çok yoldan gidilebilir ve bunların bazıları diğerlerinden ucuzdur; savunmanın ilgilendiği şey en pahalı yol değil en ucuz yoldur. Bunu sayabilmek için senaryoyu düz bir dizi olarak değil, hedeften geriye dallanan bir yapı olarak yazmak gerekir. Saldırı ağacı bu yapıdır: kök hedef, alt hedefler ve önkoşuluyla maliyeti yazılmış yaprak adımlar.

Kök, Alt Hedef, Yaprak

Aşağıdaki ağaç bir modeldir. Yaprak düğümler yalnız önkoşulu ve kurgu maliyetiyle anılır; hiçbir yerde bir adımın nasıl yapıldığı yazılmaz — ağacın savunma tarafındaki değeri zaten adımın kendisinde değil, adımların birleşim yapısındadır. Böyle bir çözümlemenin gerçek bir sistem üzerinde yürütülmesi, yazılı yetki ve tanımlı kapsam olmadan hem yasadışı hem meslek dışıdır. Maliyet ve önlem sayıları kurgu birimdir; para birimi değildir.

TD17: her düğüm ya VEYA (çocuklardan biri yeter), ya VE (hepsi gerekir), ya da yapraktır; yaprak bir önkoşul, bir maliyet ve bir önlem bedeli taşır. TD18: VEYA düğümün maliyeti çocuklarının en küçüğü, VE düğümün maliyeti toplamıdır. TD19: kapatılan yaprağın maliyeti sonsuzdur. TD20: en ucuz yol, her VEYA düğümünde en ucuz çocuğun seçildiği yaprak kümesidir.

// tehdit/agac.mjs — saldiri agaci (model): kok hedef, alt hedefler ve yaprak adimlar.
// Yaprak adimlar YALNIZ onkosulu ve kurgu maliyetiyle yazilir; hicbir yerde bir adimin
// nasil yapildigi anlatilmaz. Maliyet ve onlem birimleri kurgudur, para birimi degildir.

// TD17: dugum ya VEYA (cocuklardan biri yeter) ya VE (hepsi gerekir) ya da yapraktir.
// Yaprak "ad onkosul maliyet onlem" tasir: onlem, o yapragi kapatmanin kurgu bedelidir.
export const AGAC = {
  ad: "fatura-kaydinin-degistirilmesi", tip: "VEYA", cocuk: [
    { ad: "depoya-dogrudan-yazma", tip: "VE", cocuk: [
      { ad: "veri-bolgesine-erisim", tip: "VEYA", cocuk: [
        { ad: "yonetim-agindan-erisim", onkosul: "ic-ag-erisimi", maliyet: 8, onlem: 4 },
        { ad: "yedek-kanalindan-erisim", onkosul: "yedek-ucu-acik", maliyet: 12, onlem: 3 }] },
      { ad: "depo-yazma-yetkisi", tip: "VEYA", cocuk: [
        { ad: "servis-kimligi-elde", onkosul: "kimlik-deposu-okunur", maliyet: 15, onlem: 6 },
        { ad: "yetki-atamasi-degisimi", onkosul: "yonetim-yetkisi", maliyet: 20, onlem: 5 }] }] },
    { ad: "faturalama-uzerinden", tip: "VE", cocuk: [
      { ad: "gecerli-abone-oturumu", tip: "VEYA", cocuk: [
        { ad: "abone-kimligini-elde", onkosul: "portal-disa-acik", maliyet: 6, onlem: 7 },
        { ad: "oturum-devralma", onkosul: "belirtec-gorunur", maliyet: 9, onlem: 5 }] },
      { ad: "yetki-denetimini-asma", tip: "VEYA", cocuk: [
        { ad: "nesne-kimligi-degisimi", onkosul: "yetki-karari-istemcide", maliyet: 3, onlem: 2 },
        { ad: "rol-alani-degisimi", onkosul: "rol-istemciden", maliyet: 5, onlem: 2 }] }] },
    { ad: "dogrulayici-cikisi-degisimi", tip: "VE", cocuk: [
      { ad: "olcum-akisina-girme", tip: "VEYA", cocuk: [
        { ad: "sayac-kimligi-taklidi", onkosul: "sayac-kimligi-dogrulanmiyor",
          maliyet: 10, onlem: 9 },
        { ad: "toplama-ucuna-erisim", onkosul: "toplama-ucu-disa-acik",
          maliyet: 14, onlem: 4 }] },
      { ad: "dogrulama-kuralini-asma", tip: "VEYA", cocuk: [
        { ad: "ayar-degisimi", onkosul: "yonetim-akisi-dogrulanmiyor", maliyet: 11, onlem: 3 },
        { ad: "esik-degerini-asma", onkosul: "esik-sabit", maliyet: 7, onlem: 2 }] }] }] };

export const YAPRAK = (d = AGAC) => d.cocuk ? d.cocuk.flatMap((c) => YAPRAK(c)) : [d];

// TD18: VEYA dugumun maliyeti cocuklarinin en kucugu, VE dugumun maliyeti toplamidir.
// TD19: kapatilan yapragin maliyeti sonsuzdur; kapatilan yapraktan gecen her yol kapanir.
export function maliyet(d = AGAC, kapali = []) {
  if (!d.cocuk) return kapali.includes(d.ad) ? Infinity : d.maliyet;
  const c = d.cocuk.map((x) => maliyet(x, kapali));
  return d.tip === "VEYA" ? Math.min(...c) : c.reduce((a, b) => a + b, 0);
}

// TD20: en ucuz yol, her VEYA dugumunde en ucuz cocugun secildigi yaprak kumesidir.
export function enUcuzYol(d = AGAC, kapali = []) {
  if (!d.cocuk) return maliyet(d, kapali) === Infinity ? [] : [d.ad];
  if (d.tip === "VEYA") {
    const en = d.cocuk.reduce((a, b) => maliyet(a, kapali) <= maliyet(b, kapali) ? a : b);
    return maliyet(en, kapali) === Infinity ? [] : enUcuzYol(en, kapali);
  }
  return d.cocuk.flatMap((c) => enUcuzYol(c, kapali));
}
// tehdit/kapatma.mjs — en ucuz yolun maliyeti ve bir dugumu kapatmanin koku kac kat
// pahalilastirdigi.
import { AGAC, YAPRAK, maliyet, enUcuzYol } from "./agac.mjs";

const yaz = (g, ...s) => console.log(s.map((v, i) =>
  (g[i] < 0 ? String(v).padEnd(-g[i]) : String(v).padStart(g[i]))).join(""));
const bicim = (x) => (x === Infinity ? "kapali" : String(x));
const kat = (x) => (x === Infinity ? "kapali" : (x / TABAN).toFixed(2));
const yapraklar = YAPRAK();
const TABAN = maliyet();

console.log(`${yapraklar.length} yaprak, ${AGAC.cocuk.length} alt hedef; kok maliyeti ` +
  `${TABAN} birim, en ucuz yol ${enUcuzYol().join(" + ")}`);

const A = [-28, 7, 10, 10, 13];
console.log("\n1. alt hedefler ve maliyetleri");
yaz(A, "alt hedef", "tip", "maliyet", "yaprak", "en ucuz yol");
for (const c of AGAC.cocuk)
  yaz(A, c.ad, c.tip, maliyet(c), YAPRAK(c).length, enUcuzYol(c).length + " adim");

const B = [-24, -28, 9, 8, 10, 7, 11];
console.log("\n2. her yapragi tek tek kapatmak");
yaz(B, "yaprak", "onkosul", "maliyet", "onlem", "yeni kok", "kat", "kat/onlem");
const olcum = yapraklar.map((y) => ({ y, kok: maliyet(AGAC, [y.ad]) }))
  .sort((a, b) => b.kok - a.kok || a.y.onlem - b.y.onlem);
for (const { y, kok } of olcum)
  yaz(B, y.ad, y.onkosul, y.maliyet, y.onlem, kok, kat(kok),
    ((kok - TABAN) / y.onlem).toFixed(2));

const C = [-24, 8, 10, 10, 10, 12];
console.log("\n3. acgozlu kapatma: her turda koku en cok yukselten yaprak");
yaz(C, "kapatilan yaprak", "onlem", "biriken", "yeni kok", "adim kat", "toplam kat");
const kapali = [];
let onlem = 0;
while (maliyet(AGAC, kapali) !== Infinity) {
  const aday = yapraklar.filter((y) => !kapali.includes(y.ad))
    .map((y) => ({ y, kok: maliyet(AGAC, [...kapali, y.ad]) }))
    .sort((a, b) => b.kok - a.kok || a.y.onlem - b.y.onlem)[0];
  const onceki = maliyet(AGAC, kapali);
  kapali.push(aday.y.ad);
  onlem += aday.y.onlem;
  yaz(C, aday.y.ad, aday.y.onlem, onlem, bicim(aday.kok),
    aday.kok === Infinity ? "kapali" : (aday.kok / onceki).toFixed(2), kat(aday.kok));
}
console.log(`koku tamamen kapatmak ${kapali.length} yaprak ve ${onlem} onlem birimi istiyor; ` +
  `kalan ${yapraklar.length - kapali.length} yaprak hicbir acik yolun uzerinde degil`);

// Bir VEYA dugumunun butun yapraklarini kapatmak, o dugumu ve onu iceren VE dalini kapatir.
const veyaDugum = (d = AGAC) => (d.cocuk
  ? [...(d.tip === "VEYA" && d !== AGAC ? [d] : []), ...d.cocuk.flatMap((c) => veyaDugum(c))]
  : []);
const D = [-24, 8, 8, 10, 9, 14];
console.log("\n4. bir VEYA dugumunun tamamini kapatmak");
yaz(D, "VEYA dugumu", "yaprak", "onlem", "yeni kok", "kat", "birim basina");
for (const d of veyaDugum()) {
  const ler = YAPRAK(d), o = ler.reduce((a, y) => a + y.onlem, 0);
  const kok = maliyet(AGAC, ler.map((y) => y.ad));
  yaz(D, d.ad, ler.length, o, bicim(kok), kat(kok),
    kok === Infinity ? "-" : ((kok - TABAN) / o).toFixed(2));
}
const yol = yapraklar.filter((y) => enUcuzYol().includes(y.ad));
console.log(`karsilastirma: en ucuz yolun ${yol.length} yapragini kapatmak ` +
  `${yol.reduce((a, y) => a + y.onlem, 0)} onlem birimi harcar ve koku ` +
  `${maliyet(AGAC, yol.map((y) => y.ad))} birime cikarir`);

// Koku kapatmanin en ucuz yolu: her VE dalindan bir VEYA dugumu secilir, butun bilesimler
// denenir ve toplam onlemi en kucuk olan alinir.
const dalSecenek = AGAC.cocuk.map((dal) => veyaDugum(dal)
  .map((d) => ({ ad: d.ad, ler: YAPRAK(d) })));
let enUcuzKapatma = null;
const dolas = (i, secim) => {
  if (i === dalSecenek.length) {
    const ler = secim.flatMap((s) => s.ler), o = ler.reduce((a, y) => a + y.onlem, 0);
    if (maliyet(AGAC, ler.map((y) => y.ad)) === Infinity &&
      (!enUcuzKapatma || o < enUcuzKapatma.o)) enUcuzKapatma = { secim, o, n: ler.length };
    return;
  }
  for (const s of dalSecenek[i]) dolas(i + 1, [...secim, s]);
};
dolas(0, []);
console.log(`\nen ucuz tam kapatma ${enUcuzKapatma.n} yaprak ve ${enUcuzKapatma.o} onlem ` +
  `birimi (${enUcuzKapatma.secim.map((s) => s.ad).join(", ")}); acgozlu sira ayni sonucu ` +
  `${onlem} birimle veriyor, yani ${(onlem / enUcuzKapatma.o).toFixed(2)} kat pahaliya`);
12 yaprak, 3 alt hedef; kok maliyeti 9 birim, en ucuz yol abone-kimligini-elde + nesne-kimligi-degisimi

1. alt hedefler ve maliyetleri
alt hedef                       tip   maliyet    yaprak  en ucuz yol
depoya-dogrudan-yazma            VE        23         4       2 adim
faturalama-uzerinden             VE         9         4       2 adim
dogrulayici-cikisi-degisimi      VE        17         4       2 adim

2. her yapragi tek tek kapatmak
yaprak                  onkosul                       maliyet   onlem  yeni kok    kat  kat/onlem
abone-kimligini-elde    portal-disa-acik                    6       7        12   1.33       0.43
nesne-kimligi-degisimi  yetki-karari-istemcide              3       2        11   1.22       1.00
rol-alani-degisimi      rol-istemciden                      5       2         9   1.00       0.00
esik-degerini-asma      esik-sabit                          7       2         9   1.00       0.00
yedek-kanalindan-erisim yedek-ucu-acik                     12       3         9   1.00       0.00
ayar-degisimi           yonetim-akisi-dogrulanmiyor        11       3         9   1.00       0.00
yonetim-agindan-erisim  ic-ag-erisimi                       8       4         9   1.00       0.00
toplama-ucuna-erisim    toplama-ucu-disa-acik              14       4         9   1.00       0.00
yetki-atamasi-degisimi  yonetim-yetkisi                    20       5         9   1.00       0.00
oturum-devralma         belirtec-gorunur                    9       5         9   1.00       0.00
servis-kimligi-elde     kimlik-deposu-okunur               15       6         9   1.00       0.00
sayac-kimligi-taklidi   sayac-kimligi-dogrulanmiyor        10       9         9   1.00       0.00

3. acgozlu kapatma: her turda koku en cok yukselten yaprak
kapatilan yaprak           onlem   biriken  yeni kok  adim kat  toplam kat
abone-kimligini-elde           7         7        12      1.33        1.33
oturum-devralma                5        12        17      1.42        1.89
esik-degerini-asma             2        14        21      1.24        2.33
ayar-degisimi                  3        17        23      1.10        2.56
servis-kimligi-elde            6        23        28      1.22        3.11
yetki-atamasi-degisimi         5        28    kapali    kapali      kapali
koku tamamen kapatmak 6 yaprak ve 28 onlem birimi istiyor; kalan 6 yaprak hicbir acik yolun uzerinde degil

4. bir VEYA dugumunun tamamini kapatmak
VEYA dugumu               yaprak   onlem  yeni kok      kat  birim basina
veri-bolgesine-erisim          2       7         9     1.00          0.00
depo-yazma-yetkisi             2      11         9     1.00          0.00
gecerli-abone-oturumu          2      12        17     1.89          0.67
yetki-denetimini-asma          2       4        17     1.89          2.00
olcum-akisina-girme            2      13         9     1.00          0.00
dogrulama-kuralini-asma        2       5         9     1.00          0.00
karsilastirma: en ucuz yolun 2 yapragini kapatmak 9 onlem birimi harcar ve koku 14 birime cikarir

en ucuz tam kapatma 6 yaprak ve 16 onlem birimi (veri-bolgesine-erisim, yetki-denetimini-asma, dogrulama-kuralini-asma); acgozlu sira ayni sonucu 28 birimle veriyor, yani 1.75 kat pahaliya

Sayılar ölçüm sınıfındadır; girdileri TD17–TD20’dir.

Dokuz Birim

Kök maliyeti 9 birimdir ve en ucuz yol iki adımdan oluşur. Bu tek sayı, on iki yaprağın toplam 120 birimlik maliyetiyle hiç ilgili değildir: ağaç bir toplam değil, bir en küçük seçimdir.

Birinci tablo bunu üç dala böler. Doğrudan depoya yazma 23 birim, doğrulayıcı çıkışını değiştirme 17 birim, faturalama üzerinden gitmek 9 birim. Üç dalın da dört yaprağı ve iki adımlık en ucuz yolu vardır; aradaki farkı üreten şey yaprak sayısı değil, yaprak maliyetleridir. Kök bir VEYA düğümü olduğu için üçünün en küçüğünü alır — yani ağacın maliyetini en zayıf dal belirler.

Bu, savunma tarafında sık yapılan bir hesap hatasını doğrudan gösterir. Doğrudan depoya yazmayı zorlaştırmak için harcanan çaba kök maliyetini hiç değiştirmez, çünkü o dal zaten en pahalı daldır ve saldıran taraf onu seçmez. Ağaç, hangi işin boşa gittiğini yazan bir yapıdır.

On İki Yaprağın Onu Hiçbir Şey Değiştirmiyor

İkinci tablo her yaprağı tek tek kapatır. Sonuç serttir: on iki yaprağın onunda kök maliyeti 9’da kalır, kat 1,00’dır. Yalnız iki yaprak bir şey değiştirir — abone-kimligini-elde kapatıldığında kök 12’ye çıkar (1,33 kat), nesne-kimligi-degisimi kapatıldığında 11’e (1,22 kat). İkisi de en ucuz yolun üzerindedir; geri kalan on yaprak değildir.

Son sütun önlem birimi başına getiriyi verir ve sıralamayı tersine çevirir. abone-kimligini-elde 7 önlem birimine karşılık 3 birimlik artış sağlar: birim başına 0,43. nesne-kimligi-degisimi ise 2 önlem birimine karşılık 2 birimlik artış: birim başına 1,00. Daha küçük kat veren kapatma, ödenen birim başına iki buçuk kat daha verimlidir.

En pahalı önlemler en verimsizleridir. sayac-kimligi-taklidi 9 önlem birimi ister ve kök maliyetini hiç değiştirmez; servis-kimligi-elde 6 birim ister ve yine hiçbir şey değiştirmez. Bir tehdit modelleme çıktısında bu iki satır muhtemelen “yüksek öncelikli” görünürdü — ikisi de gerçek bir açığa karşılık gelir. Ağaç üzerinde ölçüldüğünde ikisinin de kök maliyetine katkısı sıfırdır, çünkü ikisi de zaten en pahalı dalın üzerindedir.

VEYA Düğümünü Kapatmak

Dördüncü tablo kapatmayı yaprak yerine düğüm düzeyinde yapar. Bir VEYA düğümünün bütün yapraklarını kapatmak o düğümü kapatır ve onu içeren VE dalını tamamen ortadan kaldırır.

Altı VEYA düğümünden yalnız ikisi kök maliyetini değiştirir ve ikisi de faturalama dalındadır: gecerli-abone-oturumu (12 önlem birimi) ve yetki-denetimini-asma (4 önlem birimi). İkisi de kökü 17’ye çıkarır — 1,89 kat. Aynı sonuç için biri üçünün, öteki dörtte birinin bedelini ister; birim başına getiri 0,67’ye karşılık 2,00’dır.

Karşılaştırma satırı asıl kararı verir. En ucuz yolun iki yaprağını kapatmak 9 önlem birimi harcar ve kökü 14’e çıkarır. yetki-denetimini-asma düğümünün iki yaprağını kapatmak 4 birim harcar ve kökü 17’ye çıkarır. Daha az harcayan seçim daha çok kazandırır, çünkü en ucuz yolun yaprakları iki ayrı VEYA düğümüne dağılmıştır ve her birinin yerine geçecek bir kardeş yaprak vardır. Yaprak kapatmak yolu kaydırır; VEYA düğümü kapatmak dalı yok eder.

Kökü Tamamen Kapatmak

Üçüncü tablo açgözlü sırayı yürütür: her turda kökü en çok yükselten yaprak kapatılır. Altı yaprak ve 28 önlem birimi sonunda kök kapanır; kalan altı yaprak hiçbir açık yolun üzerinde değildir. Ara değerler 12, 17, 21, 23, 28 diye ilerler ve adım katları 1,33’ten 1,10’a düşer — her kapatma bir öncekinden daha az getirir.

Son satır bu sıranın verimsizliğini ölçer. Her VE dalından bir VEYA düğümü seçilerek yapılan tam kapatma da altı yaprak kapatır, ama 16 önlem birimi harcar. Açgözlü sıra aynı sonucu 1,75 kat pahalıya verir.

Sebep tablo 3’ün ilk satırındadır. Açgözlü seçim abone-kimligini-elde ile başlar çünkü kökü en çok o yükseltir — ama o yaprağın önlem bedeli 7’dir ve aynı dalı yetki-denetimini-asma üzerinden kapatmak 4 birim tutardı. Her turda en çok kazandıran hamleyi seçmek, toplam bedeli en küçük yapan seçimi vermez; ağaçta seçimlerin bedeli birbirini etkiler ve kalem kalem sıralama bunu göremez.

Özet

  • Saldırı ağacında ölçülen sayı yaprak sayısı değil kök maliyetidir: 12 yaprak ve üç alt hedeften oluşan ağaçta kök 9 kurgu birim, en ucuz yol iki adımdır. Kök bir VEYA düğümüdür, yani maliyeti en zayıf dal belirler.
  • On iki yaprağın onu tek tek kapatıldığında kök maliyeti hiç değişmez; yalnız en ucuz yolun üstündeki iki yaprak 1,33 ve 1,22 kat verir.
  • Önlem birimi başına getiri sıralamayı tersine çevirir: 1,33 kat veren kapatma birim başına 0,43, 1,22 kat veren kapatma birim başına 1,00 getirir.
  • Bir VEYA düğümünün tamamını kapatmak dalı yok eder; 4 önlem birimlik bir düğüm kökü 1,89 kata çıkarırken en ucuz yolun iki yaprağı 9 birim harcayıp yalnız 1,56 kat verir.
  • Kökü tamamen kapatmak açgözlü sırayla 28, dal başına bir VEYA düğümü seçilerek 16 önlem birimi tutar; her turda en çok kazandıran hamle toplamda 1,75 kat pahalıdır.

Sonraki Adım

Bu konu beş derste bir tehdit listesi ve bir öncelik sırası üretti: 23 sınır geçişi, 58 kalem, 108 sistematik tehdit, 12 zincir tehdidi ve kök maliyetini gerçekten değiştiren birkaç kapatma. Bütün bu sayılar modelin içinde duruyor.

Modelin içinde durdukları sürece hiçbir şey değişmez. Bir karşı önlem ancak birinin üzerine alındığı, bir kabul ölçütüne bağlandığı ve bir sürüme yazıldığı zaman koda dönüşür; bunlardan biri eksikse iş öğesi hiç açılmaz ve kalem sessizce kaybolur. Sonraki ders model çıktısını iş öğesine çevirir ve son ölçümü yapar: kaç tehdit kaç ayrı karşı önleme düşüyor, bunların kaçı gerçekten planlanıyor, kaçı hangi eksikten kayboluyor ve geriye kalan artık riskin kaç kalemi yazılı olarak kabul ediliyor.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat