Stack buffer overflow

Jirka Kosina jikos na jikos.cz
Pátek Listopad 26 12:30:42 CET 2004


On Fri, 26 Nov 2004, Max Cerny wrote:

> Vytvoril jsem si vlastni program, ktery je nachylny k preteceni
> zasobniku: pomoci debuggeru jsem si zjistil jak polozim NOP cykly. Za ne
> polozim shellkod, a pote vlastni navratovou adresu, tak aby se
> prekryvala. Ted ten problem: Adresa, kterou chci podvrhnout je pokazde
> naprosto jina... Pouzivam FC 2 - jadro 2.6.8-1.521 . Slysel jsem, ze je
> zaplatovane prave kvuli temto buffer overflovum. Je to pravda? Da se ta
> navratova adresa, kterou chci podvrhnout nejak predvidat? Jak?

Ano, je to pravda, redhati kernely se snazi trosku randomizovat zasobnik 
(exec shield, da se zakazat jak pri kompilaci kernelu, tak pri runtime). 
Viz http://people.redhat.com/mingo/exec-shield/ANNOUNCE-exec-shield

Pokud chcete porozumet tomu jak se nastavuje tento randomizovany zasobnik, 
doporucuji podivat se do zdrojaku kernelu na funkci create_elf_tables().
Viz fs/binfmt_elf.c:

	sp = (void *) (u_platform - (((current->pid+jiffies) % 64) << 7)); 

* Pro lokalni exploity na kernelech s exec shieldem je daleko pohodlnejsi 
nez pracne hledat shellcode ve stacku a radeji umistete svuj shellkod do 
*argv[] nebo do environmentove promenne - jejich adresy se nemeni, protoze 
'vypln' se na stack dava az za ne.

* Dalsi moznosti, jak se vyhnout navratu do shellcode ulozeneho na stacku, 
je zfalsovani ulozeneho stackframe (jehoz adresu znate relativne k Vasemu 
vulnerable bufferu, a to staci) a pouziti techniky return into lib.

* Drobna finta spociva v tom, ze velikost te 'vyplne' o kterou se
randomizuje, je cyklicky zavisla na PID procesu. Cili pokud se Vam jednou
povede trefit return adresu ktera fungovala, tak stejne navratova adresa
by mela fungovat alespon v 1/64 pripadu (pokazde kdyz se proces spusti s
PID, ktery se od toho, pro ktery RET addr znate, lisi o nasobek 64, bude
mit 'vypln' stejnou velikost a vsechna data na stacku by mela skoncit na
stejnem miste).

* Navic 'vypln' roste o hodnotu 128 pokazde prave kdyz se PID lisi o 1.  
Takze pokud si muzete dovolit hodne dlouhou serii NOPu, zvysujete tim
pravdepodobnost, ze Vas posunuty stack nerozhazi (za kazdych 128 bajtu
NOPu ziskavate o jednicku sirsi interval, o kolik se PID procesu muze
lisit od PIDu procesu, pro ktery RET addr znate). Z cehoz plyne, ze pokud
by Vam situace dovolila nacpat tam 8192 (128x64) NOPu, mate 100%ni sanci
ze Vas shellcode uspeje.

* Pokud znate PID rodicovskeho procesu tak presne vite jaka vypln bude 
pouzita.

-- 
JiKos.


Další informace o konferenci Linux