(delsi) buffer overflow - prunik
Pavel Kankovsky
peak na argo.troja.mff.cuni.cz
Pondělí Srpen 7 12:06:27 CEST 2000
On Sun, 6 Aug 2000, Jaroslav Gratz wrote:
> |----------------instrukční segment-------------------|
> |---------datový segment---------|
> |---stack segment---|
Nikoli. Rika se tomu "flat model" a vypada to takto:
|---------- code segment ------------| (cs)
|---------- data segment ------------| (ds, es, ss)
na Linuxu je ds == ss, ted z hlavy nevim, jestli to plati i pro Win32,
ale asi ano. V kazdem pripade maji urcite vsechny segmenty stejny offset,
aby mohl program existenci segmentu srdecne ignorovat (protoze pak lze
ukazatele redukovat na offsety).
> Prostě v rámci jednoho procesu se segmenty překrývají a je možné
> beztrestně přepsat zásobník z datového segmentu a spustit kód na
> zásobníku.
Navratova adresa na zasobniku se asi bez vyjimky prepisuje pretecenim
nejake automaticke promenne, ktera je taky na zasobniku, a tudiz si
oddelenim stack seg. nepomuzete. Pomohlo by (pro tento partikularni druh
problemu), kdyby byly dva zasobniky: jeden pro navratove instrukce a druhy
pro automaticky promenne a mozna i pro parametry (jestli jste mel TOHLE
na mysli, pak to nebylo moc jasne), ale vyzadovalo by to nestandardni
kejkle. A take by neslo prekladat s -fomit-frame-pointer, coz je na
intelech, ktere nemaji registru nazbyt, celkem dulezita optimalizace.
> Špatné řešení. Generovat za běhu programu dynamicky nějaký kód na zásobník
> a ten potom spouštět je nesystémové a nepřehledné. Zásobník potom musí být
> spustitelný se všemi důsledky, co z toho vyplývají. Když už měli vývojáři
> gcc potřebu použít dynamicky generovaný kód, měli to udělat jinde než na
> zásobníku.
Kod trampoliny ma zivotnost ekvivaletni automaticke promenne, proto dava
dost dobry smysl ho umistit na stejne misto jako automatickou promennou
...tj. na zasobnik.
> |-instrukční segment-|-----datový segment----|----stack segment----|
> |-datový segment pouze pro čtení (není nutný)-|
>
> Parametry by se na zásobník předávaly tak jako doteď, buď
> push [promenna] nebo mov [ebp+n],reg. Čtení parametrů mov reg,[ebp+n].
Dejme tomu, ze mam kod:
void f(char *a) { strcpy(a, "....neco hodne dlouheho..."); }
void g(char a) { f(&a); }
Zabranite prepsani navratove adresy? Pokud ano, jak to prelozite?
> To máte pravdu, tady by to nepomohlo. Ale přepsání zásobníku a
> překrývající se segmenty jsou mnohem nebezpečnější, protože dávají
> útočníkovi možnost spustit jeho vlastní kód.
Varianty 2 a 3 (ktere jste rafinovane vymazal) ano.
> Vzhledem k tomu, kolik existuje buffer overflow exploitů, se mi to zdá
> celkem důležité (ale to je pouze můj názor). A lidé jsou omylní a stále
> budou přibývat nové exploity.
Pochybuji, ze nejaky *exploit* nekdy vznikl omylem. :)
Nicmene Vami navrhovane reseni bude vzdycky polovicate. A polovicatych
(nikoli v hanlivem smyslu) reseni uz nekolik funkcnich mame: Openwall,
StackGuard, takze znovuvynalezate kolo.
--Pavel Kankovsky aka Peak [ Boycott Microsoft--http://www.vcnet.com/bms ]
"Resistance is futile. Open your source code and prepare for assimilation."
Další informace o konferenci Linux