İçeriğe geç
academia.sh

Ders 16 / 16

Günlük Bütünlüğü

1.200 kayıtlık bir günlük zinciri dört kurcalama biçimine karşı sınanır: silme 744. sırada ve 11 sıra boşluğuyla, özeti tazelenmiş değişiklik 839. sırada yakalanıyor, zincir yeniden hesaplandığında yalnız sıra boşluğu kalıyor, sıra da yeniden verildiğinde yerel doğrulama temiz diyor. Merkezdeki kopya 13 kurcalanan kaydın günlük aktarımda 0'ını, saat başı aktarımda 11'ini, beş saniyelik gönderimde 13'ünü gösteriyor; filoda pencere hiçbir aralıkta kapanmıyor, çünkü 130 makine çevrimdışı kalıyor.

İçindekiler

Bir önceki ders süreç oluşturma kaydını açtı ve üst süreç bağlamının 1.702 işareti 40’a indirdiğini gösterdi. Bu konunun üç dersi de aynı sessiz varsayımı taşıdı: kayıt orada duruyor ve doğru. Oysa sayılan kayıtların tamamı, üzerinde kalem çalıştıran makinenin kendi diskinde üretiliyor ve bu kursun başlangıç varsayımı koda bir kez uçta çalışma izni veriyordu. Kayıt da o kodun erişebildiği yerdedir.

Bu ders o varsayımı sınar. Bir karma zinciri (hash chain) kaydın kendi içinde tutarlı olduğunu gösterir: her kaydın özeti sırayı, bir önceki özeti ve gövdeyi kapsar, dolayısıyla ortadan bir kaydı çıkarmak ya da değiştirmek zinciri kırar. Sorulacak soru bunun neye karşı işe yaradığıdır. Ölçüm bir modeldir, bölgesel ölçüm ağı kurgudur ve kurcalamanın yöntemi yazılmaz, yalnız sonucu modellenir. Başkasına ait bir sistemde kayıt üzerinde işlem yapmak — silmek, değiştirmek, taşımak — yazılı yetki ve tanımlı kapsam olmadan hem yasadışı hem meslek dışıdır.

  • SG16. Bir uçta bir günün günlüğü 1.200 kayıttır. Her kayıt sıra numarası, gövde ve özet taşır; özet node:crypto ile sıra, bir önceki özet ve gövdeden hesaplanır. Yapı Backend Üretim kursundaki zincirleme özetle aynıdır, ölçülen soru farklıdır.
  • SG17. Kurcalama anı 61.550. saniyedir ve kurcalanan aralık 54.000. saniyeden başlar. Aralıktan 11 kayıt siliniyor, 2 kaydın gövdesi değişiyor.
  • SG18. Dört kurcalama biçimi ayrılır: A silme, zincire dokunmadan; B değiştirme, yalnız o kaydın özetini tazeleyerek; C silme, zinciri yeniden hesaplayarak; D silme, sıra numaralarını da yeniden vererek.
  • SG19. Merkezî toplayıcı kaydın bir kopyasını tutar ve karşılaştırma kaydın değişmeyen kalem kimliği üzerinden yapılır. Merkeze ulaşmamış kayıt karşılaştırılamaz.
  • SG20. Filo dört gruptur ve saha dizüstüleri günde 23.400 saniye çevrimdışıdır. Gönderim başına ek yük 8 KiB’dir; bütün sayılar kurgudur.

Zincirin Gördüğü Dört Biçim

// zincir.mjs — uc noktada uretilen gunluk zinciri, dort kurcalama bicimi ve yerel dogrulama.
// MODELDIR; kurcalama YONTEMI yazilmaz, yalnizca sonucu modellenir.
import { createHash } from "node:crypto";

export const TOHUM = 20260515, N = 1200, T = 61550;   // kurcalama ani (saniye)
const uretec = (t) => { let s = t >>> 0;
  return () => (s = (s * 1664525 + 1013904223) >>> 0) / 4294967296; };
const r = uretec(TOHUM);
const KAYNAK = ["surec-olusturma", "kimlik-dogrulama", "sistem-olay", "zamanlayici"];

export const ozet = (sira, once, govde) =>
  createHash("sha256").update(`${sira}|${once}|${govde}`).digest("hex").slice(0, 16);

// Zincir: her kaydin ozeti sira, bir onceki ozet ve govdeden hesaplanir.
export function zincirle(kayitlar) {
  let once = "baslangic";
  return kayitlar.map((k) => { once = ozet(k.sira, once, k.govde); return { ...k, ozet: once }; });
}
const zamanlar = Array.from({ length: N }, () => Math.floor(r() * 86400)).sort((a, b) => a - b);
export const GUNLUK = zincirle(zamanlar.map((t, i) => ({
  sira: i + 1, t,
  govde: JSON.stringify({ t, kaynak: KAYNAK[Math.floor(r() * 4)], kalem: 100 + i }),
})));

// Kurcalama araligi: son etkinlik penceresi. Bu araliktan bir bolum kayit siliniyor,
// son iki kayit degisiyor.
const aralik = GUNLUK.filter((k) => k.t >= 54000 && k.t <= T);
export const SILINEN = aralik.filter((_, i) => i % 9 === 0).slice(0, 12).map((k) => k.sira);
export const DEGISEN = aralik.filter((k) => !SILINEN.includes(k.sira)).slice(-2)
  .map((k) => k.sira);
// Degistirme kaydin zamanini kaydiriyor; kalem kimligi degismiyor.
const bozuk = (k) => JSON.stringify({ ...JSON.parse(k.govde), t: JSON.parse(k.govde).t + 900 });

// A: silindi, zincire dokunulmadi. B: degisti, yalniz o kaydin ozeti tazelendi.
// C: silindi, zincir yeniden hesaplandi. D: silindi, sira da yeniden verildi.
export const BICIM = {
  A: () => GUNLUK.filter((k) => !SILINEN.includes(k.sira)),
  B: () => GUNLUK.map((k) => (DEGISEN.includes(k.sira)
    ? { ...k, govde: bozuk(k), ozet: ozet(k.sira, GUNLUK[k.sira - 2].ozet, bozuk(k)) } : k)),
  C: () => zincirle(GUNLUK.filter((k) => !SILINEN.includes(k.sira))
    .map((k) => (DEGISEN.includes(k.sira) ? { ...k, govde: bozuk(k) } : k))),
  D: () => zincirle(GUNLUK.filter((k) => !SILINEN.includes(k.sira))
    .map((k, i) => ({ ...k, sira: i + 1,
      govde: DEGISEN.includes(k.sira) ? bozuk(k) : k.govde }))),
};

// Yerel dogrulama: zincir bastan yurutulur, ilk uyusmazligin sirasi dondurulur (yoksa 0).
export function dogrula(kayitlar) {
  let once = "baslangic";
  for (const k of kayitlar) {
    once = ozet(k.sira, once, k.govde);
    if (once !== k.ozet) return k.sira;
  }
  return 0;
}
// Sira bosluklari: silinen kayitlarin birakabilecegi tek yerel iz.
export const bosluk = (kayitlar) => kayitlar.reduce((a, k, i) =>
  (i && k.sira !== kayitlar[i - 1].sira + 1 ? a + k.sira - kayitlar[i - 1].sira - 1 : a), 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 yz = gen([42, 8, 16, 14, 15]);
  console.log(`model (tohum ${TOHUM}): ${N} kayitlik gunluk zinciri, kurcalama ani ${T}. saniye`);
  console.log(`kurcalanan aralik ${SILINEN.length} silinen, ${DEGISEN.length} degisen kayit ` +
    `(sira ${SILINEN[0]}-${SILINEN.at(-1)} arasi ve ${DEGISEN.join(", ")})`);
  console.log("\n" + yz(["kurcalama bicimi", "kayit", "ilk uyusmazlik", "sira bosluk",
    "yerel sonuc"]));
  for (const [ad, aciklama] of [["A", "kayit silindi, zincire dokunulmadi"],
    ["B", "kayit degisti, ozeti tazelendi"],
    ["C", "kayit silindi, zincir yeniden hesaplandi"],
    ["D", "silindi, sira ve zincir yeniden verildi"]]) {
    const l = BICIM[ad]();
    const u = dogrula(l), b = bosluk(l);
    console.log(yz([`${ad}: ${aciklama}`, l.length, u || "-", b || "-",
      u || b ? "kurcalanmis" : "temiz"]));
  }
}
model (tohum 20260515): 1200 kayitlik gunluk zinciri, kurcalama ani 61550. saniye
kurcalanan aralik 11 silinen, 2 degisen kayit (sira 743-833 arasi ve 838, 839)

kurcalama bicimi                             kayit  ilk uyusmazlik   sira bosluk    yerel sonuc
A: kayit silindi, zincire dokunulmadi         1189             744            11    kurcalanmis
B: kayit degisti, ozeti tazelendi             1200             839             -    kurcalanmis
C: kayit silindi, zincir yeniden hesaplandi    1189               -            11    kurcalanmis
D: silindi, sira ve zincir yeniden verildi    1189               -             -          temiz

Dört satır bir merdiven kuruyor. İlk biçimde kayıtlar silinmiş ve zincire dokunulmamıştır; iki bağımsız işaret birden çıkıyor — doğrulama 744. sırada duruyor ve 11 sıra boşluğu sayılıyor. İkincisinde bir kaydın gövdesi değişmiş ve yalnız o kaydın özeti yeniden hesaplanmıştır; uyuşmazlık değişen kayıtta değil, ondan sonrakinde çıkıyor. Zincirin kazandırdığı tam olarak budur: bir kaydı tutarlı kılmak, ondan sonraki bütün kayıtları da yeniden yazmayı gerektirir.

Üçüncü biçimde zincirin tamamı yeniden hesaplanmıştır ve doğrulama hiçbir uyuşmazlık bulmuyor. Geriye tek iz kalıyor: 11 sıra boşluğu. Dördüncü biçimde sıra numaraları da yeniden verilmiştir ve o iz de kayboluyor — yerel doğrulama temiz diyor. On bir kayıt silinmiş, iki kaydın zamanı kaydırılmıştır ve makinenin üzerinde bunu gösteren hiçbir şey yoktur.

Sonuç bir cümleye iniyor: aynı makinede üretilip aynı makinede doğrulanan bir zincir, o makineyi elinde tutana karşı bütünlük kanıtı değil, yalnız tutarlılık kanıtıdır. Gerçek katkısı kısmi kurcalamayı olanaksız kılmasıdır: kurcalayan ya hiç dokunmayacak ya da kaydın tamamını yeniden üretecektir.

Merkezdeki Kopya ve Aktarım Penceresi

// merkez.mjs — merkezdeki kopya ile karsilastirma ve aktarim penceresinin filo bedeli.
import { GUNLUK, BICIM, SILINEN, DEGISEN, T } from "./zincir.mjs";

const yerel = BICIM.D();                            // yerel dogrulamanin temiz gordugu kume
const kalem = (k) => JSON.parse(k.govde).kalem;     // kayitin degismeyen kimligi
const ARALIK = [["gunde bir", 86400], ["4 saat", 14400], ["saat basi", 3600],
  ["5 dakika", 300], ["5 saniye", 5]];

const gen = (B) => (h) => h.map((v, j) => (j ? String(v).padStart(B[j])
  : String(v).padEnd(B[0]))).join("");
const y1 = gen([13, 11, 13, 15, 19, 15]);
const y2 = gen([17, 10, 11, 13, 16, 16, 13]);

console.log(`kurcalama ani ${T}. saniye; ${SILINEN.length} silinen ve ${DEGISEN.length} ` +
  `degisen kayit var, yerel zincir bunlarin hicbirini gostermiyor`);
console.log(y1(["aralik", "merkezde", "pencerede", "tespit silme", "tespit degisiklik",
  "gorunmeyen"]));
for (const [ad, w] of ARALIK) {
  const sonAktarim = Math.floor(T / w) * w;
  const merkez = GUNLUK.filter((k) => k.t <= sonAktarim);
  const yerelKalem = new Map(yerel.map((k) => [kalem(k), k.govde]));
  const silme = merkez.filter((k) => !yerelKalem.has(kalem(k))).length;
  const degis = merkez.filter((k) => yerelKalem.has(kalem(k)) &&
    yerelKalem.get(kalem(k)) !== k.govde).length;
  console.log(y1([ad, merkez.length, GUNLUK.length - merkez.length,
    `${silme}/${SILINEN.length}`, `${degis}/${DEGISEN.length}`,
    SILINEN.length + DEGISEN.length - silme - degis]));
}

// Filo: aktarim araligini kisaltmanin bedeli ve kapatilamayan pencere.
const GRUP = [["saha dizustu", 84, 41000, 23400], ["sube ucu", 46, 39000, 3600],
  ["sayac toplayici", 120, 44000, 0], ["merkezi isleme", 18, 52000, 0]];
const EK = 8192;                                    // gonderim basina ek yuk (bayt)
console.log("\n" + y2(["aktarim araligi", "gonderim", "filo/gun", "ek yuk MiB",
  "saha penceresi", "riskteki kayit", "kapanmayan"]));
for (const [ad, w] of ARALIK) {
  const bag = Math.round(86400 / w);
  const filo = GRUP.reduce((a, g) => a + g[1] * bag, 0);
  const risk = GRUP.reduce((a, g) => a + g[1] * g[2] * Math.max(w, g[3]) / 86400, 0);
  const kapanmayan = GRUP.filter((g) => g[3] > w).reduce((a, g) => a + g[1], 0);
  console.log(y2([ad, bag, filo.toLocaleString("tr-TR"), Math.round(filo * EK / 1048576),
    `${Math.max(w, GRUP[0][3])} sn`, Math.round(risk).toLocaleString("tr-TR"), kapanmayan]));
}
console.log(`\naraligi gunde birden 5 dakikaya cekmek gonderim sayisini 288 katina cikariyor; ` +
  `saha dizustulerinde etkin pencere ${GRUP[0][3]} saniyenin altina inmiyor`);
kurcalama ani 61550. saniye; 11 silinen ve 2 degisen kayit var, yerel zincir bunlarin hicbirini gostermiyor
aralik          merkezde    pencerede   tespit silme  tespit degisiklik     gorunmeyen
gunde bir              0         1200           0/11                0/2             13
4 saat               789          411           6/11                0/2              7
saat basi            834          366          11/11                0/2              2
5 dakika             837          363          11/11                0/2              2
5 saniye             839          361          11/11                2/2              0

aktarim araligi    gonderim   filo/gun   ek yuk MiB  saha penceresi  riskteki kayit   kapanmayan
gunde bir                 1        268            2        86400 sn      11.454.000            0
4 saat                    6      1.608           13        23400 sn       2.267.750           84
saat basi                24      6.432           50        23400 sn       1.266.500           84
5 dakika                288     77.184          603        23400 sn       1.029.083          130
5 saniye              17280  4.631.040        36180        23400 sn       1.007.860          130

araligi gunde birden 5 dakikaya cekmek gonderim sayisini 288 katina cikariyor; saha dizustulerinde etkin pencere 23400 saniyenin altina inmiyor

Üstteki tablo merkezdeki kopyanın neyi kapattığını sayıyor ve kapattığı miktar tam olarak aktarım penceresinin dışında kalan kayıt sayısıdır. Günde bir aktarımda merkezde o günden hiç kayıt yoktur ve 13 kurcalanan kalemin 13’ü görünmez kalır. Dört saatlik aralıkta 11 silmenin altısı çıkıyor; saat başı aktarımda 11’i de çıkıyor. Değiştirilen iki kayıt yalnız beş saniyelik gönderimde görünüyor, çünkü ikisi de son gönderimden sonraya düşüyor.

Bu satırların hepsi yerel zincirin temiz dediği kümede duruyor. Karşılaştırmayı mümkün kılan ikinci bir kopyadır, zincir değil.

Alttaki tablo pencereyi kısaltmanın faturasını yazıyor. Günde bir gönderimden beş dakikaya inmek gönderim sayısını 288 katına çıkarıyor — filoda 268’den 77.184’e — ve gönderim ek yükü günde 603 MiB tutuyor. Beş saniyelik gönderimde aynı ek yük 36 GiB olur.

Son iki sütun asıl sınırı gösteriyor. Riskteki kayıt sayısı 11,45 milyondan 1,03 milyona iniyor ve orada duruyor: aralığı beş dakikadan beş saniyeye çekmek bu sayıyı yalnız yüzde iki azaltıyor. Nedeni dördüncü sütundur — saha dizüstülerinin etkin penceresi hiçbir aralıkta 23.400 saniyenin altına inmiyor, çünkü o makineler günün altı buçuk saatini çevrimdışı geçiriyor. Beş dakikalık aralıkta 130 makinede pencere hiç kapanmıyor. Merkezîleştirmenin kapattığı pencere bir yapılandırma değil, bir bağlanabilirlik sınırıdır.

Pencerenin içinde kalan kayıt için elde tek bir seçenek kalıyor ve o da bir mimari kalemidir: kaydı, üreten makinenin değiştiremeyeceği bir yere yazmak — yalnız ekleme yapılabilen bir ortama ya da anahtarı uçta bulunmayan bir imzayla. Bu, pencereyi kapatmaz; pencere içindeki kaydın sessizce değişmesini engeller.

Özet

  • Karma zinciri üç kurcalama biçimini yakalıyor: silme 744. sırada ve 11 sıra boşluğuyla, özeti tazelenmiş değişiklik 839. sırada, zincir yeniden hesaplandığında yalnız sıra boşluğuyla.
  • Sıra numaraları da yeniden verildiğinde yerel doğrulama temiz diyor: aynı makinede üretilip aynı makinede doğrulanan bir zincir, o makineyi elinde tutana karşı tutarlılık kanıtıdır, bütünlük kanıtı değil.
  • Merkezdeki kopya 13 kurcalanan kaydın günde bir aktarımda 0’ını, saat başı aktarımda 11’ini, beş saniyelik gönderimde 13’ünü gösteriyor; kapattığı miktar aktarım penceresinin dışında kalan kayıt sayısıdır.
  • Aralığı günde birden beş dakikaya çekmek gönderimi 288 katına ve ek yükü günde 603 MiB’ye çıkarıyor; beş saniyede ek yük 36 GiB olur.
  • Riskteki kayıt 11,45 milyondan 1,03 milyona iniyor ve orada kalıyor: 130 makinede pencere hiçbir aralıkta kapanmıyor, çünkü etkin pencereyi ayar değil çevrimdışı kalma süresi belirliyor.

Kurs Kapanışı

Ders Tutunma noktası Kapanan / görünen Meşru işe bedel
Sertleştirme İlkeleri 101 kalem, 84 nokta 40 kapanıyor, 44 görünür 41 elle adım
Yama Yönetimi 1.038 nokta, 12 duyuru 0 kapanıyor, pencere 10,8’den 2,3 güne 939 plan dışı kesinti
Yapılandırma Kıyaslamaları 26 madde, 104 karar 0 kapanıyor, 588 nokta daralıyor 48 elle adım, 53 istisna
Uygulama İzin Listeleri 1.038 nokta, 25 kalem 972 kapanıyor, 66 açık 7 kalem 208 makinede
Sanal Alan Kullanımı 15 kalem, 4 yapılandırma 0 kapanıyor, 8 kötüden 4’ü duruyor 2 yanlış engel, 275 dakika
Disk Şifreleme 1.038 nokta tanımı, 18 kalem 936 kapanıyor, 102 açık 204 anahtar kopyası, 14.112 dakika
Kötü Amaçlı Yazılım Türleri 8 nokta türü, 10 tür 8 tür duruyor, 2’si kalıyor 130 meşru kalem
Kötü Amaçlı Yazılım Karşıtı 20 kalem, 6 kötü 7 nokta kapanıyor, uyarı kipinde görünür 3 meşru iş, 7 uyarı
Uç Nokta Tespit ve Yanıt 8 nokta türü, 7 kaynak 0 kapanıyor, 6 görünür, 2 kör 19,5 gün pencere, 2 yeni nokta
Konak Tabanlı Güvenlik Duvarı 729.252 yol, 290.772 bölge içi 158.100 yol kapanıyor, 60 tür kayıtta 2 meşru akış kesiliyor
Yaşayan Toprakta Saldırı 14 araç, 7 yetenek 0 kapanıyor, 6 koşumun 5’i ayrılıyor 3 yanlış pozitif
Kalıcılık Mekanizmaları 10 tür, 161 meşru kalem 7,1 kapalı, 1,8 görünür, 1,2 karanlık 36 kalem, 52 elle onay
Olay Günlükleri 3.078 makine-tür çifti 0 kapanıyor, 2.356 görünür, 250 kör günde 10,2 milyon kayıt
Kimlik Doğrulama Günlükleri 916 başarısızlık, 0 nokta 0 kapanıyor, 216 olayın 10’u görünür 5 yanlış pozitif, 9 giriş
Komut Satırı Denetimi 8 tür adıyla, 5 şüpheli 0 kapanıyor, 5’i ayrılıyor, 3’ü tek kaynakta 90 günde 410 GiB
Günlük Bütünlüğü 13 kurcalanan kayıt 0 kapanıyor, 13’ü merkezde görünür 1,03 milyon kayıt pencerede

Üçüncü sütunu boş kalan tek bir satır yok ve ikinci sütunda “0 kapanıyor” yazan dokuz satır var. Kursun kuralı bu iki gözlemden çıkıyor: uç nokta güvenliği bir ürün listesi değil, otomatik çalıştırılan kalemlerin sayısıdır; kapatılamayan her nokta en azından görünür kılınmalıdır, çünkü görünmeyen nokta yok sayılmış noktadır. Kapatma ile görünür kılmayı aynı sütuna yazan her ölçüm, kendi kapsamını olduğundan geniş gösterir.

On altı ders boyunca ikinci sütun tek yönde ilerledi: sertleştirme kalem sayısını düşürdü, izin listesi ve disk şifreleme büyük blokları kapattı, koruma katmanları kapatamadıklarını görünür kılmaya başladı, son dört ders yalnız görünürlüğü ölçtü. Kalan sayı hep aynı biçimdeydi.

Bütün bu ölçüm boyunca sorulmamış bir soru var. Beş kurs boyunca hep savunma tarafından bakıldı ve her denetimin neyi kaçırdığı tek tek sayıldı — kaçan yol, geçen iddia, açık kalan nokta, kör kalan kayıt. Ama kaçırılan bu yolları kimin, hangi sırayla ve neden kullandığı hiç ele alınmadı. Bir saldırgan neden bir noktayı seçip ötekini bırakır, hangi adımdan sonra hangisine geçer, ne zaman durur? M24/K06 Saldırı Teknikleri ve Tehdit Ortamı kursu tam olarak bu soruyla başlar.

İ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