**** buffer-overflow ****

Program nacitava funkciou scanf() retazec neobmedzenej dlzky do premennej, na ktoru si vyhradil 100 bajtov.
Neprilis prekvapivo, za touto premennou v pamati nasleduje par bajtov a za nimi navratova adresa, na ktoru
sa pri navrate z volania derava_funkcia() skoci.

IDA nam na adrese 0x8048719 v programe ukazuje, ze ona premenna je oproti povodnemu koncu zasobnika posunuta
o 0x6c (= 108) bajtov. Za tymito bajtami este nasleduju styri, do ktorych sa pri zavolani tejto funkcie ulozi
EBP -- takze celkove potrebujeme vyplnit bajtov 112 a za nimi sa uz bude nachadzat hladana navratova adresa.

Podobne, IDA alebo prikaz
	objdump -t buffer-overflow | grep tajna
nam ukazu, ze tajna_funkcia sa nachadza na adrese 0x080486e8. Ak teda povodnu navratovu adresu prepiseme
touto, program pri odchadzani z funkcie derava_funkcia() skoci do funkcie tajnej... a to je to, co sme chceli.

Na vykonstruovanie vhodneho obsahu sa da pouzit mnoho roznych sposobov; napriklad taky Perl:
	perl -e 'print "a"x112, "\xe8\x86\x04\x08"' | ./buffer-overflow
alebo, pre tych, ktorym sa text cita lepsie v opacnom poradi:
	perl -e 'print "a"x112, pack "L", 0x80486e8' | ./buffer-overflow

(konstrukcia pack "L", <cislo> robi iba to, ze viacbajtove cislo zapise v nativnej, little-endianovej forme;
no a "a" x 112 je presne to, co by sa dalo ocakavat... 112 a-cok).


Ak vystup tohto prikazu presmerujeme do nasho deraveho programu, uvidime cosi taketo:

Vitajte na nasej tajnej zakladni!
Heslo pre dnesny den je: VelmiZloziteATajneHeslo
Heslo pre dnesny den je: (null)
Segmentation fault (core dumped)

Podnet na zamyslenie: Preco to vypisalo tu hlasku o aktualnom dni dvakrat, a preco tam bol ten (null)?
Napoveda: Ako vyzera zasobnik

Podnet na zamyslenie 2: Vedeli by sme dosiahnut, aby program namiesto takehoto skaredeho spadnutia radsej
pokojne skoncil?

--------------
Ten isty postup by vsak zlyhal, pokial by pri kompilacii programu nebolo vypnute bezpecnostne opatrenie
zvane stack-protector (pouzil sa prepinac -fno-stack-protector). Pokial by bol zapnuty, kompilator by medzi 
tu stobajtovu premennu a navratovou adresou pridal este tzv. "stack canary" -- stvorbajtovu premennu, ktorej
hodnota sa nastavi pri zavolani funkcie a pri navrate z nej sa skontroluje. Kedze tato hodnota je volena
nahodne a utocnik ju (za normalnych okolnosti) nepozna, program namiesto skocenia na navratovu adresu
skonci s chybou:

$ perl -e 'print "a"x112, pack "L", 0x80486e8' | ./buffer-overflow-canary
*** stack smashing detected ***: ./buffer-overflow-canary terminated
Aborted (core dumped)

Podnet na zamyslenie 3: Ako to presne funguju tie kanariky? Na to nam najlepsie odpovie IDA / objdump.
