################### # Private Release # ################### -========================================- -======== Race Condition Propusti =======- -========== Neka utrka zapocne! =========- -========================================- by BoyScout 0x01 - uvod ~~~~~~~~~~~ Mnogi misle da je ovo jako jednostavno (pa, i je), ali neki misle da je prejednostavno i potpuno nezastupljeno u programima da bi isli tako nesto exploitati. Mnogi programi koji koriste privremene fileove za spremanje i/ili uzimanje podataka za svoje potrebe. 0x02 - teorija ~~~~~~~~~~~~~~ Exploitanje race condition propusta ima smisla ili kad se exploita suidni program sa greskom kojeg hacker pokrece, ili kada exploita neki program koji je trenutno u tijeku, a vlasnik procesa je npr. root ili ako je program u crontabu i izvrsava se u odredjeno vrijeme. Ako program ne dopusta da prije njegova pokretanja napravimo akciju na fileu koji on koristi u svrhu dobivanja, recimo, root shella, tada mozemo pokusati to napraviti i za njegova izvrsavanja. Funkcije kad govorimo o race condition propustima mozemo podijeliti na atomic i nonatomic (iliti ne-atomic) :) Atomic funkcija je ona funkcija koja se izvrsava od pocetka do kraja bez ikakvih mogucnosti ometanja/prekida. Nonatomic funkcija je, pogadjate, ono suprotno -- sto najcesce hackerima omogucuje da exploitaju race condition propuste, tako sto mogu za vrijeme izvrsavanja napraviti nesto sa fileom koji program sa propustom koristi. 0x03 - praksa ~~~~~~~~~~~~~ Evo jednog programa pisanog u shell skriptnom jeziku koji ima propust: -- START -- #!/bin/sh echo "-- Pocetak programa --" FILE=/var/tmp/priv1.tmp if test -x $FILE; then echo "-- File postoji i znam sto si htio napraviti, hehe --" exit 255 fi echo "neki_podaci" > $FILE rm $FILE echo "--- Kraj programa ----" -- END -- Sto ovaj program radi? U normalnim okolnostima, ukoliko file /var/tmp/priv1.tmp ne postoji, on kreira novi file tog imena i u njega upise "neki_podaci". Ukoliko smo prije pokretanja programa napravili file istog imena (ili symlink), program bi se prekinuo prije upisivanja "neki_podaci" jer je isprobao da li file vec postoji. Ipak, moguce je i ovdje iskoristiti propust, zato sto shell skripte rijetko koriste, i do nedavno nisu imale atomic funkcije. Kao sto smo rekli, iako bi se program prekinuo da prije njegovog izvrsavanja napravimo file, moguce ga je napraviti nakon provjere. Posto je vrijeme izvrsavanja programa vrlo kratko, jako je tesko pogoditi vrijeme izmedju provjere i upisivanja podataka u file, ali ne i nemoguce. Treba pokusavati mnogo puta dok se ne uspije, a kako bi se postiglo namjerno usporenje izvrsavanja programa kako bi lakse pogodili vrijeme, moguce je procesor zatrpati s mnogo beskorisnih procesa. U C-u postoji funkcija mkstemp() koja kreira novi, nekoristeni file te ga otvara, za razliku od mktemp() koji generira novi file ali ga se treba otvoriti sa open() sto hackeru daje milisekunde vremena da ga kreira. Ako koristimo u shell skripti mkdir da kreiramo temp direktorij u koji ce ici temp file, a u isto vrijeme radimo provjeru da li je taj direktorij prije postojao, tada nam nitko ne moze ometati rad jer ako netko pokusa kreirati temp direktorij prije programa, program ce se prekinuti. Za shell skripte postoji atomic funkcija mktemp, slicna mkstemp()-u u C-u, no ona ne postoji na svim UNIXima. 0x04 - zasto bi bilo jednostavno kad moze komplicirano ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ U shell skriptama poput gornjeg primjera mozemo staviti za nastavak filea npr. ekstenziju $$ sto je u shell skriptnom jeziku oznaka za PID od skripte. Dakle, umjesto da se file zove /var/tmp/priv1.tmp, mozemo ga nazvati /var/tmp/priv1.tmp.$$ sto ce hackeru jos vise otezati posao jer ce morati pogoditi vrijeme izmedju provjere i upisivanja u file, a i PID od skripte kako bi znao koji file treba kreirati. Zato on moze (u teoriji) pri samome pocetku izvrsavanja programa suspendirati njegov proces te pogledati PID (sto ima smisla samo ako je doticni program suidan i ako ga on moze izvrsiti). 0x05 - i to je sve? ~~~~~~~~~~~~~~~~~~~ Naravno da ne. Postoji mnogo mogucnosti, koje su vama otvorene da ispobate i otkrijete. Pretpostavivsi da je program suidan na roota, mozete pravovremeno kreirati symlink na neki postojeci file ciji je vlasnik root, a ime symlinka koristi program kako bi ste corruptali taj vec postojeci file. Ili mozete napraviti symlink na nepostojeci file, kako bi se kreirao novi file sa rootovim obiljezjima. Evo kako u C-u izbjegnemo koristenja filea koji je symlink: open("/var/tmp/priv1.tmp", O_EXCL|O_CREAT|O_RDWR, 0666); A ovako u Perlu: sysopen(HANDLE, "/tmp/filename", O_EXCL|O_CREAT|O_RDWR); Funkcija lstat() u C-u provjerava da li je file koji program koristi symlink, pa se takodjer koristi u provjerama koje na vrijeme prekinu program. Isto mozete isprobati i sa hardlinkovima, ukoliko vam je to omoguceno, i sve ce biti slicno osim sto necete moci napraviti hardlink na nepostojeci file ili direktorij, tako da necete moci natjerati program na kreira novi file za vas. 0x06 - kraj ~~~~~~~~~~~ Eto ovo je jedna sitnica za one koji se nisu prije zabavljali sa race conditionima ili jednostavno to nisu smatrali jednom od mogucih security prijetnja. Ispricavam se sto nisam napisao vise primjera programa. Pozdrav ide mojim prijateljima. Oni znaju koji su. --BoyScout