Ders 19 / 22
Arabellek Taşması
Arabellek taşmasının sınırlı dizi modelinde ölçülmesi: otuz iki baytlık bir bölgede on bir kopyalama uzunluğunun otuz üç komşu alan bozması, koruma değerinin on bir durumun dördünde bozulması, bozulan dönüş etiketinin iki durumun hiçbirinde geçerli kalmaması, sınır denetiminin on bir durumun dokuzunu yakalaması ve altı bileşenin birinde hiçbir halkanın kırılamaması.
İçindekiler
Buraya kadarki dört sınıfın ortak noktası, bir değerin bir yorumlayıcıya verilmesiydi. Beşincisinde yorumlayıcı yoktur. Bir değer, kendisi için ayrılmış alandan uzun olduğu için komşu alana yazılır ve komşu alandaki kalem başka bir şey olur.
Bu ders sınıfı mantık düzeyinde ele alır. Ölçülen şey bir taşmanın nasıl yapılacağı değil, bir bölgede alanların bitişik durmasının hangi sonucu doğurduğu ve hangi denetimin hangi adımı kestiğidir. Bölge, alan düzeni ve kopyalama bu derste kendi yazılan bir veri yapısı modelidir; gerçek bir bellek düzeni, gerçek bir adres ve hiçbir makine kodu geçmez.
Bitişikliğin Sonucu
Bir bölge içindeki alanlar birbirine bitişik durur: her alanın başlangıcı bir öncekinin bitişidir. Bir alana onun boyundan uzun bir değer yazılırsa, fazla baytlar bir sonraki alanın baytlarıdır. Kopyalama işlemi bunu bilmez; ona verilen tek şey bir başlangıç ve bir uzunluktur. Sınır denetimi, kopyalamanın hedef alanın boyunu aşıp aşmadığına bakan ve aşıyorsa işlemi hiç yapmayan adımdır.
Aşağıdaki bölgede yedi alan vardır ve sıraları anlamlıdır: sayaç okuması, tarife kodu ve yetki bayrağı veri alanlarıdır; koruma değeri bilinen ve sabit bir kalemdir; dönüş etiketi ise işlevin hangi devam noktasına döneceğini adlandırır. Bu bir modeldir: gerçek bir çağrı kaydının düzeni değil, bitişikliğin sonucunu ölçmek için yazılmış bir dizidir.
TS22: bölge sabit boyutludur ve alanlar bitişiktir. TS23: sınır denetimi olmayan kopyalama hedef alanın uzunluğunu değil istenen uzunluğu yazar; bölgenin sonundan taşan bayt ayrıca sayılır. TS24: adım dizisi beş adımdır ve her denetim tek bir adımı kırar. TS25: kopyalanan değer tek bir bayt değeridir; içeriği seçilmemiştir.
// at/bolge.mjs — sinirli dizi modeli: sabit boyutlu bir bolge ve icindeki adlandirilmis // alanlar. Gercek bir bellek duzeni, gercek bir adres ve hicbir makine kodu yok; bu bir // veri yapisi modelidir. export const ALAN = [ ["ad", 0, 12], ["sayac", 12, 4], ["tarife", 16, 4], ["yetki-bayragi", 20, 1], ["dolgu", 21, 3], ["koruma-degeri", 24, 4], ["donus-etiketi", 28, 4], ]; export const BOYUT = 32; export const GECERLI_ETIKET = [7, 9, 11]; // kurgu: yalnizca bu uc etiket cagrilabilir export const DOLGU_BAYT = 65; // kopyalanan degerin tek bir bayt degeri export function tazeBolge() { const b = new Uint8Array(BOYUT); b.set([79, 76, 67, 85, 77, 45, 48, 49], 0); // ad alani: kurgu bir sayac kimligi b.set([0, 0, 4, 210], 12); // sayac okumasi b.set([0, 0, 0, 3], 16); // tarife kodu b[20] = 0; // yetki bayragi kapali b.set([222, 173, 190, 239], 24); // koruma degeri: sabit ve bilinen b.set([0, 0, 0, 7], 28); // donus etiketi: gecerli return b; } export function kopyala(b, alanAdi, uzunluk, sinirDenetimi) { const [, bas, boy] = ALAN.find((a) => a[0] === alanAdi); if (sinirDenetimi && uzunluk > boy) return { yazilan: 0, tasan: 0, reddedildi: true }; const yazilacak = Math.min(uzunluk, BOYUT - bas); for (let i = 0; i < yazilacak; i++) b[bas + i] = DOLGU_BAYT; return { yazilan: yazilacak, tasan: Math.max(0, uzunluk - (BOYUT - bas)), reddedildi: false }; } export const bozulan = (b) => { const t = tazeBolge(); return ALAN.filter(([, bas, boy]) => { for (let i = bas; i < bas + boy; i++) if (b[i] !== t[i]) return true; return false; }).map(([ad]) => ad); }; export const etiket = (b) => b[28] * 16777216 + b[29] * 65536 + b[30] * 256 + b[31]; export const korumaBozuk = (b) => bozulan(b).includes("koruma-degeri"); export const yaz = (g, ...s) => console.log(s.map((v, i) => (g[i] < 0 ? String(v).padEnd(-g[i]) : String(v).padStart(g[i]))).join(""));
// at/olcum.mjs — ayni uzunluk kumesi iki kurulusta kosturulur: sinir denetimi olmadan ve // sinir denetimiyle. Bozulan komsu alanlar sayilir. Rastgelelik yok. import { ALAN, BOYUT, GECERLI_ETIKET, tazeBolge, kopyala, bozulan, etiket, korumaBozuk, yaz } from "./bolge.mjs"; const UZUNLUK = [8, 12, 13, 16, 20, 21, 24, 25, 28, 32, 36]; const adBoyu = ALAN.find((a) => a[0] === "ad")[2]; console.log(`bolge ${BOYUT} bayt, ${ALAN.length} alan; hedef alan "ad" ${adBoyu} bayt`); console.log(`alan duzeni: ${ALAN.map(([a, b, u]) => `${a}[${b}..${b + u - 1}]`).join(" ")}\n`); const A = [-9, 9, 8, 9, 16, 10, 10]; console.log("1. sinir denetimi olmadan"); yaz(A, "uzunluk", "yazilan", "tasan", "bozulan", "en uzak bozulan", "koruma", "etiket"); let toplamKomsu = 0, korumaGoren = 0, etiketBozuk = 0, gecerliOlan = 0; for (const u of UZUNLUK) { const b = tazeBolge(); const r = kopyala(b, "ad", u, false); const komsu = bozulan(b).filter((a) => a !== "ad"); toplamKomsu += komsu.length; if (korumaBozuk(b)) korumaGoren++; const e = etiket(b); if (komsu.includes("donus-etiketi")) { etiketBozuk++; if (GECERLI_ETIKET.includes(e)) gecerliOlan++; } yaz(A, u, r.yazilan, r.tasan, komsu.length, komsu.at(-1) ?? "-", korumaBozuk(b) ? "bozuldu" : "saglam", komsu.includes("donus-etiketi") ? (GECERLI_ETIKET.includes(e) ? "gecerli" : "gecersiz") : "saglam"); } console.log(`\n${UZUNLUK.length} uzunlukta toplam ${toplamKomsu} komsu alan bozuldu; ` + `${UZUNLUK.filter((u) => u > adBoyu).length} uzunluk alan boyunu asiyor`); console.log(`koruma degerinin bozuldugu durum: ${korumaGoren}/${UZUNLUK.length}; ` + `donus etiketinin bozuldugu durum: ${etiketBozuk}, bunlarin ${gecerliOlan} tanesinde ` + `etiket gecerli kaldi`); const B = [-9, 12, 12, 16]; console.log("\n2. sinir denetimiyle ayni kume"); yaz(B, "uzunluk", "sonuc", "bozulan", "yakalanan"); let yakalanan = 0, gecen = 0; for (const u of UZUNLUK) { const b = tazeBolge(); const r = kopyala(b, "ad", u, true); if (r.reddedildi) yakalanan++; else gecen++; yaz(B, u, r.reddedildi ? "reddedildi" : "yazildi", bozulan(b).filter((a) => a !== "ad").length, r.reddedildi ? "evet" : "hayir"); } console.log(`sinir denetimi ${UZUNLUK.length} durumun ${yakalanan} tanesini yakaladi, ` + `${gecen} tanesi alan icinde kaldigi icin gecti; bozulan komsu alan: 0`); const ADIM = [ ["sinir-denetimsiz-kopyalama", "dil ya da cagri uzunlugu denetlemiyor"], ["uzunluk-disaridan", "kopyalanacak uzunluk bir girdi alanindan geliyor"], ["komsu-alan-bozulmasi", "hedefin komsusunda anlamli bir kalem var"], ["karari-belirleyen-alan", "bozulan alan bir bayrak, sayac ya da devam kaydi"], ["istenen-dala-gidis", "bozulmus deger gecerli bir dal adi olarak kabul ediliyor"], ]; const DENETIM = [ ["sinir-denetimli-dil", 1, "dil sinifi", 0], ["girdi-uzunluk-sozlesmesi", 2, "uygulama", 2], ["derleyici-sinir-denetimi", 3, "derleyici", 5], ["koruma-degeri-denetimi", 4, "derleyici", 3], ["calistirilamaz-veri-alani", 5, "isletim sistemi", 1], ["rastgele-yerlesim", 5, "isletim sistemi", 1], ]; const C = [-27, 9, 18, 8]; console.log("\n3. adim dizisi ve adim-denetim eslemesi"); ADIM.forEach(([a, o], i) => console.log(` ${i + 1}. ${a.padEnd(28)}onkosul: ${o}`)); yaz(C, "denetim", "kirdigi", "katman", "mesru"); for (const [ad, n, kat, m] of DENETIM) yaz(C, ad, `${n}. adim`, kat, m); const BILESEN = [ ["toplayici.surucu", "sinir-denetimsiz", ["derleyici-sinir-denetimi", "koruma-degeri-denetimi", "calistirilamaz-veri-alani", "rastgele-yerlesim"]], ["toplayici.cozumleyici", "sinir-denetimsiz", ["koruma-degeri-denetimi", "rastgele-yerlesim"]], ["sube-ucu.protokol-katmani", "sinir-denetimsiz", ["girdi-uzunluk-sozlesmesi", "calistirilamaz-veri-alani"]], ["saha-cihazi.gomulu-yazilim", "sinir-denetimsiz", []], ["dogrulayici.servis", "sinir-denetimli", []], ["fatura-uretimi.servis", "sinir-denetimli", []], ]; const D = [-30, -18, 9, 14, 12]; console.log("\n4. bilesen basina zincir"); yaz(D, "bilesen", "dil sinifi", "denetim", "ilk kirilan", "denetimsiz"); for (const [ad, dil, d] of BILESEN) { const kume = dil === "sinir-denetimli" ? ["sinir-denetimli-dil", ...d] : d; const kirar = DENETIM.filter(([a]) => kume.includes(a)).map(([, n]) => n); const h = kirar.length ? Math.min(...kirar) : 0; yaz(D, ad, dil, kume.length, h ? `${h}. adim` : "kirilmiyor", ADIM.length - new Set(kirar).size); } const acik = BILESEN.filter(([, dil, d]) => dil !== "sinir-denetimli" && d.length === 0).length; console.log(`hicbir halkasi kirilmayan bilesen: ${acik}; sinir denetimli dil sinifinda ` + `zincir birinci adimda kirildigi icin kalan dort adim hic olusmuyor`);
bolge 32 bayt, 7 alan; hedef alan "ad" 12 bayt alan duzeni: ad[0..11] sayac[12..15] tarife[16..19] yetki-bayragi[20..20] dolgu[21..23] koruma-degeri[24..27] donus-etiketi[28..31] 1. sinir denetimi olmadan uzunluk yazilan tasan bozulan en uzak bozulan koruma etiket 8 8 0 0 - saglam saglam 12 12 0 0 - saglam saglam 13 13 0 1 sayac saglam saglam 16 16 0 1 sayac saglam saglam 20 20 0 2 tarife saglam saglam 21 21 0 3 yetki-bayragi saglam saglam 24 24 0 4 dolgu saglam saglam 25 25 0 5 koruma-degeri bozuldu saglam 28 28 0 5 koruma-degeri bozuldu saglam 32 32 0 6 donus-etiketi bozuldu gecersiz 36 32 4 6 donus-etiketi bozuldu gecersiz 11 uzunlukta toplam 33 komsu alan bozuldu; 9 uzunluk alan boyunu asiyor koruma degerinin bozuldugu durum: 4/11; donus etiketinin bozuldugu durum: 2, bunlarin 0 tanesinde etiket gecerli kaldi 2. sinir denetimiyle ayni kume uzunluk sonuc bozulan yakalanan 8 yazildi 0 hayir 12 yazildi 0 hayir 13 reddedildi 0 evet 16 reddedildi 0 evet 20 reddedildi 0 evet 21 reddedildi 0 evet 24 reddedildi 0 evet 25 reddedildi 0 evet 28 reddedildi 0 evet 32 reddedildi 0 evet 36 reddedildi 0 evet sinir denetimi 11 durumun 9 tanesini yakaladi, 2 tanesi alan icinde kaldigi icin gecti; bozulan komsu alan: 0 3. adim dizisi ve adim-denetim eslemesi 1. sinir-denetimsiz-kopyalama onkosul: dil ya da cagri uzunlugu denetlemiyor 2. uzunluk-disaridan onkosul: kopyalanacak uzunluk bir girdi alanindan geliyor 3. komsu-alan-bozulmasi onkosul: hedefin komsusunda anlamli bir kalem var 4. karari-belirleyen-alan onkosul: bozulan alan bir bayrak, sayac ya da devam kaydi 5. istenen-dala-gidis onkosul: bozulmus deger gecerli bir dal adi olarak kabul ediliyor denetim kirdigi katman mesru sinir-denetimli-dil 1. adim dil sinifi 0 girdi-uzunluk-sozlesmesi 2. adim uygulama 2 derleyici-sinir-denetimi 3. adim derleyici 5 koruma-degeri-denetimi 4. adim derleyici 3 calistirilamaz-veri-alani 5. adim isletim sistemi 1 rastgele-yerlesim 5. adim isletim sistemi 1 4. bilesen basina zincir bilesen dil sinifi denetim ilk kirilan denetimsiz toplayici.surucu sinir-denetimsiz 4 3. adim 2 toplayici.cozumleyici sinir-denetimsiz 2 4. adim 3 sube-ucu.protokol-katmani sinir-denetimsiz 2 2. adim 3 saha-cihazi.gomulu-yazilim sinir-denetimsiz 0 kirilmiyor 5 dogrulayici.servis sinir-denetimli 1 1. adim 4 fatura-uretimi.servis sinir-denetimli 1 1. adim 4 hicbir halkasi kirilmayan bilesen: 1; sinir denetimli dil sinifinda zincir birinci adimda kirildigi icin kalan dort adim hic olusmuyor
Bozulmanın Sırası
Birinci çıktı on bir uzunluğu tek tek yürütür ve bozulan komşu alanları sayar. Sonuç kademelidir: 13 bayt bir alanı bozar, 20 bayt ikisini, 21 bayt üçünü, 25 bayt beşini, 32 bayt altısını. Toplam 33 komşu alan bozulması vardır ve on bir uzunluğun dokuzu hedef alanın boyunu aşar.
Sıra rastgele değildir; alanların bölgedeki dizilişiyle birebir aynıdır. Bir baytlık bir aşım en yakın komşuya dokunur, dokuz baytlık bir aşım dört komşuya. Bir taşmanın hangi kalemi bozacağını belirleyen tek şey, o kalemin hedefe olan uzaklığıdır. Bu, savunmanın neden alan düzenine bakmak zorunda olduğunu açıklar: aynı taşma, farklı bir dizilişte farklı bir kalemi bozar.
Üç alan ayrı sonuç doğurur. yetki-bayragi bir karar alanıdır: bozulduğunda bir dal başka bir
yöne gider. koruma-degeri bilinen ve sabit bir kalemdir; bozulduğu anda süreç bunu dönüşten
önce görebilir — on bir durumun 4’ünde bozuldu. donus-etiketi işlevin nereye döneceğini
adlandırır ve iki durumda bozuldu.
Son satır bu dersin en önemli sayısıdır: dönüş etiketinin bozulduğu iki durumun hiçbirinde etiket geçerli kalmadı. Kopyalanan değer tek bir bayt değeriydi ve seçilmemişti; bozulma gerçekleşti ama sonuç geçerli bir dal adı vermedi. Bozulma ile denetim akışını yönlendirmek aynı şey değildir; ikincisi için gereken adım bu derste ele alınmaz ve alınmayacaktır. Zincirin beşinci adımı bu yüzden ayrı bir adım olarak yazılır.
Sınır Denetiminin Yakaladığı
İkinci çıktı aynı on bir uzunluğu sınır denetimiyle koşturur. Dokuz durum reddedilir, iki durum geçer — ve geçen ikisi hedef alanın boyunu aşmayan uzunluklardır. Bozulan komşu alan sayısı sıfırdır.
Bu tablonun anlattığı şey, sınır denetiminin karmaşık bir çıkarım yapmadığıdır. Tek bir karşılaştırma yapar: istenen uzunluk hedef alanın boyundan büyük mü. Bu karşılaştırmanın maliyeti, zincirin geri kalanının kırılması için gereken denetimlerin yanında ölçülemeyecek kadar küçüktür.
Buradan çıkan sonuç, üçüncü çıktının birinci satırıdır. Sınır denetimini dilin kendisi yapıyorsa zincir birinci adımda kırılır: sınır denetimi olmayan bir kopyalama diye bir şey yoktur, sonraki dört adımın önkoşulu hiç oluşmaz ve meşru işe bedeli 0’dır. Dil sınıfının bu sınıfı ortadan kaldırması, bir denetim eklemesi değil, birinci adımın önkoşulunu tanımdan kaldırmasıdır.
Denetimler Hangi Adımı Kırar
Üçüncü çıktı beş adımı ve altı denetimi eşler. Denetimler üç ayrı katmandan gelir ve her biri farklı bir adıma düşer.
Uygulama katmanındaki uzunluk sözleşmesi ikinci adımı kırar: kopyalanacak uzunluk artık dışarıdan gelmez. Derleyicinin eklediği sınır denetimi üçüncü adımı kırar: kopyalama bölgenin dışına yazamaz. Derleyicinin eklediği koruma değeri denetimi dördüncü adımı kırar: bozulma olur ama dönüşten önce görülür ve süreç durur. İşletim sistemi denetimleri beşinci adıma düşer.
Meşru işe bedelleri farklıdır: dil sınıfı 0, uzunluk sözleşmesi 2, koruma değeri 3, işletim sistemi denetimleri 1’er, derleyici sınır denetimi 5. En pahalı denetim en erken kıranlardan biri değildir — erkenlik ile ucuzluk bu sınıfta birlikte gitmez.
Dördüncü çıktı altı bileşeni ölçer. İki bileşen sınır denetimli dil sınıfındadır ve zincir birinci adımda kırılır. Sınır denetimsiz dört bileşenden biri üçüncü, biri dördüncü, biri ikinci adımda kırılıyor. Biri — gömülü yazılım — hiçbir adımda kırılmıyor: beş adımın beşi de denetimsiz. Derleyici ve işletim sistemi denetimlerinin bulunmadığı bir çalışma ortamında bu sınıfın tek savunması uygulamanın kendi uzunluk sözleşmesidir ve orada da yoktur.
Özet
- Bir bölgede alanlar bitişik durur; hedef alanın boyunu aşan bir kopyalama fazla baytları komşu alanların baytlarına yazar. Bozulan alanların sırası, alanların dizilişiyle birebir aynıdır.
- 32 baytlık bölgede 11 uzunluk toplam 33 komşu alan bozdu; 9 uzunluk hedef alanın boyunu aştı. Koruma değeri 4 durumda bozuldu, dönüş etiketi 2 durumda.
- Dönüş etiketinin bozulduğu 2 durumun hiçbirinde etiket geçerli kalmadı. Bozulma ile denetim akışını yönlendirmek aynı şey değildir ve zincirin beşinci adımı bu yüzden ayrıdır.
- Aynı 11 uzunlukta sınır denetimi 9 durumu reddetti, 2’si alan içinde kaldığı için geçti ve bozulan komşu alan sayısı 0 oldu. Denetim tek bir karşılaştırmadan ibarettir.
- Sınır denetimli dil sınıfı zinciri birinci adımda kırar ve meşru işe bedeli 0’dır: sonraki dört adımın önkoşulu hiç oluşmaz. Uzunluk sözleşmesi 2., derleyici sınır denetimi 3., koruma değeri 4., işletim sistemi denetimleri 5. adımı kırar.
- Altı bileşenden 2’sinde zincir 1. adımda, 3’ünde 2., 3. ya da 4. adımda kırılıyor; 1’inde beş adımın beşi de denetimsiz.
Sonraki Adım
Bu dersin zincirinde bir alanın sınırı yoktu ve savunma o sınırı koymakla ilgiliydi. Bir sonraki sınıfta sınır zaten vardır ve saldıran onu aşmaya değil, altında kalmaya çalışır: her hesap için birkaç deneme, her denemede geçerli bir istek. Sonraki ders üç parola saldırısı biçimini maliyet ve eşik ekseninde ayırır — kilitlemenin kaç biçimi durdurduğu, hesap başına birkaç deneme yapan bir biçimin kilitlemeyi neden hiç tetiklemediği, hız sınırının kaçıncı denemede devreye girdiği ve her eşiğin kaç doğru kullanıcıyı dışarıda bıraktığı sayılır.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.