A "Tévedek?" kérdésből nekem úgy tűnt, mintha tőlem várnál választ. (Általában feltételezem, hogy a nekem válaszoló kommentekben a kérdésekre tőlem várják a választ.) De ha nem így van, akkor semmi gond.
Ne haragudj, de most én nézzek utána, hogy te mit tudsz jól és mit nem? Ha van valami konkrét forrásod arról, hogy az MMU meg tudja akadályozni a return-to-libc támadásokat, akkor azt szívesen várom, és elismerem hogy tévedtem. Ha jelenleg nem tudsz ilyenről, akkor viszont légy szíves vedd te a fáradságot, hogy a saját állításaid igazságtartalmának utánajárj.
Arra, hogy a memory management unit képes megakadályozni az olvasást, írást és végrehajtást azokon a memóriaterületeken, amikre a jelenleg futó kódnak nincs olvasási, írási illetve végrehajtási jogosultsága. Nem képes viszont megakadályozni azt, hogy a vermen (ami egy írható/olvasható memóriaterület) felülíródjon egy visszatérési cím, és így a támadó által kiválasztott címre térjen vissza a vezérlés az eredeti hívó helyett.
Virtual machine esetén, amilyen például a webassembly futtatókörnyezete, ezekből a hardveres védelmekből mennyi használható fel?
Az oprendszertől ugyanúgy lehet kérni ezeknek a védelmeknek a bekapcsolását. A Webassemblyhez nem értek, de azt olvastam hogy a Java virtuális gép ugyanúgy elveszi a futtatási jogot a veremnek illetve adattárolásra használt memóriaterülettől, és a JIT fordítás végeredményéről ugyanúgy leveszi az írási jogot, mint egy natív kódnál az oprendszer betöltőkódja csinálná. A NullPointerException konkrétan úgy működik, hogy fizikailag null pointer van a memóriában, és a keletkező segfaultból gyárt NullPointerException példányt a JVM.
Mi védi meg itt a stack részt attól, hogy ne "data segment" jogokkal legyen belepiszkálva?
A hardver szempontjából mégis mi lenne a különbség a verem és az adatterület között? Mind a kettő írható-olvasható kell legyen, és egyiket sem szabad futtatni. Szerintem túl sokat vársz a hardveres védelmektől. Mióta van NX bitünk, a simán a verembe injektált kódon alapuló támadások nem működnek, de a return-to-libc stílusú támadások ellen nem tud mit csinálni az MMU.
Hozzászoktunk a védett módú operációs rendszerekhez, a code segment, data segment, stack segment hardveres védelmeihez.
Virtual machine esetén, amilyen például a webassembly futtatókörnyezete, ezekből a hardveres védelmekből mennyi használható fel? Szoftverből lehet emulálni, minden memóriautasítás előtt vizsgálni a címeket, de ez a szoftveres vizsgálat a performanciát töredékére csökkenti.
Mi védi meg itt a stack részt attól, hogy ne "data segment" jogokkal legyen belepiszkálva?
A C nyelven írt szépségek, ahol büntetlenül címezhetsz az változód részére allokált memóriaterületen túlra is, az a webassemblyre fordítás esetén tuti nem fog védelmet adni a virtuális gépen való stack-re írás ellen.
Bár ilyenkor a sebezhetőség szigorúan véve az eredeti kódban is ott van, illetve annak hibájából keletkezik, natív futtatás esetén valójában nem használható ki.
Tehát a natív hibás C program nem csinálna rosszat. Ha jól láttam a másik cikkben akkor azért, mert kifagy hibával. Az OS eltakarítja az egész tartalmat a natív program után. És innen jött a kérdésem, hogy WS környezetben miért ne tudja ugyanúgy kifagyni (ha nem is az egész böngésző, legalább a benne lévő WS-en keresztül futtatott C program).
Rust esetén ha nem kezeled le a túlcímzési hibát, akkor a default error handler kiírja az stdout-ra hogy hányas sorban történt a lekezeletlen hiba és kilép. Ha lekezeled a hibát, akkor futsz tovább, de ekkor sem hajtódik végre az adatszerkezeten túlcímzett olvasás/írás. Tehát nem tudsz se (érzékeny) információt szivárogtatni túlcímzéssel más adatszerkezetből, se beleírni más adatszerkezetbe.
C esetén ha éppen annál a résznél egyáltalán nem vagy nem jól kezeled le például a túlcímzést, akkor a szoftver huncutkodik egyet azon a memóriaterületen, ahol semmi keresnivalója nem lenne és észrevétlenül fut tovább. Közben jogosulatlan területről (érzékeny) adatot szivárogtat a támadónak illetve a jogosulatlan területre a támadó által beadott kódhalmazt tudja injektálni. Ehhez elég sokezer ilyen helynek csak egyikén elkövetned programozóként a hibás lekezelést, amire ha a támadó rátalál, már megvalósulhat a sérülékenység kihasználása.
Én ennél univerzálisabbra gondoltam. Ha jól értem az történik, hogy natív programoknál kifagy a program, ezért nem fog kihasználódni a hiba. Hát akkor miért nem fagy ki az izoláltan létező weboldal is pl., vagy a WS host vagy akármi, a Chrome kiírná hogy a manóba. :D Ugye ilyen vészleállás nem csak natív környezetben tudna működni.
Egyébként a webassembly már nem csak kliens-téma. Ott van a WASI is, amivel a webassembly szerveralkalmazásként futtatható. Mára túlnőtt a "csak webböngésző" elven. Rust-tal ilyet is tudsz fordítani.
úgy értem, hogy ami netről jön és kliens oldalon fut, azt alapvetően nem biztonságosnak tekintem.
se a szerver oldal, se a böngészőt futtató oprendszer nem bízhat meg benne.
ezen már semmit nem tud rontani a wasm.
A kliens-oldali biztonság alapvetően origin alapú szokott lenni, tehát mondjuk az egyik site-nak engedélyezed a geolocation-t vagy a hozzáférést egy adott lokális mappához, egy másik site-nak meg nem. Innentől nagyon is lehet értelme egy "bizalmat élvező" site-on futó kódot rávenni arra, hogy a támadó kódját lefuttassa.
Hát akkor miért nem hozzák be ugyanazt a "védelmet", ami natív környezetben megakadályozta a bekövetkezhetőségét? WS-be is be lehetne építeni ezt a modellt.
Az eredeti The Register-es cikken érdekes kommentvita található arról, hogy ez mennyire számít biztonsági problémának.
Szerintem érdekes lehet elolvasni.