Autor: .cCuMiNn. | 4.3.2007 |
V tomto článku si povíme něco o útocích CSRF, které jsou častou chybou současných webových aplikací a dají se nejlépe přirovnat k aplikacím, které známe jako trojské koně. Vzhledem k tomu, že mnoho začátečníků nerozlišuje mezi výrazy backdoor a trojský kůň, rozhodl jsem se začátek tohoto článku věnovat právě vysvětlení těchto pojmů.
Backdoor - aplikace nebo nastavení systému, které umožňuje opakovaný vstup do systému. Útočník většinou instaluje backdoor na systém, do kterého se mu podařilo poprvé proniknout. Zadní vrátka instaluje v podobě aplikace, která naslouchá na určitém portu, kde očekává příchozí spojení. Backdoor však může útočník zanechat i v podobě nově vytvořeného uživatelského účtu nebo změnou nastavení některé systémové služby.
Trojský kůň - aplikace nebo jiná služba, která skrývá svou skutečnou činnost za rouškou prospěchu a užitečnosti. Uživatel tak spouští aplikaci, která pro něj konná užitečnou službu, ale nepozorovaně na pozadí se provádí zákeřný kód, jež často do systému instaluje backdoor, mění právy uživatele nastavení systému nebo maže soubory z disku. Trojskými koni jsou často různé zábavné shoty, freewarové minihry, warrez, ale mohou jimi být i odkazy na webových stránkách. A právě těmto odkazům se budeme v následujícím textu věnovat.
Útoky prostřednictvím trojských koní, které pomocí webových odkazů nepozorovaně provádí pod identitou uživatele, který na odkaz kliknul, nějakou skrytou a většinou nepříjemnou činnost, nazýváme útoky CSRF. Na zranitelnost CSRF trpí velké množství současných webových aplikací. Zranitelný je bohužel i tento web a ještě před nedávnem bylo pomocí tohoto útoku možné si přivlastnit jakýkoliv účet zde registrovaného uživatele.
Asi už vás zajímá, jak můžete útok CSRF provést v praxi. Nebudu vás tedy více napínat a přistoupíme rovnou k podstatě věci...
Veškeré akce, které v aplikaci provedete mají za následek odeslání informací z vašeho webového browseru směrem na server metodou GET nebo POST.
Pokud formuláře používají k předávání dat metotu GET, můžete zjistit formát odesílaných dat velice jednoduše. Vše lze totiž bez problému vyčíst z adresního řádku browseru. Nejlépe uděláme, pokud si vše ukážeme na praktickém příkladě, se kterým se můžete často v reálu setkat. Jedná se o hlasování v anketě. Pokud kliknete na některou z možností, abyste jí dali svůj hlas, můžete v adresním řádku přečíst například tento údaj:
http://www.doména.cz/anketa.php?volba=1
Pokud bychom chtěli hlasování ovlivnit a odeslat více hlasů, mohli bychom třeba neustále dávat refresh, čím by se stále odesílal požadavek na danou stránku a pokaždé by se přičetl jeden hlas. Pokud bychom nechtěli tyto odkazy odesílat ručně, mohli bychom k tomu použít script, který by automaticky odeslal klidně tisíce hlasů. Mohlo by se jednat i o jednoduchý dávkový soubor, kdy by html požadavek odesílala aplikace Netcat.
Jak, ale jistě všichni víte, bývají ankety proti podobnému zkreslování chráněni pomocí cookie, kontrolou ip adresy nebo mohou hlasovat jen registrovaní uživatelé a u každého je hlídáno, zda už hlasoval, či nikoliv. V takovém případě, by nám nebyl výše uvedený postup nic platný.
Co se však stane, pokud odkaz http://www.domena.cz/anketa.php?volba=1 odešlete na různé e-mailové adresy nebo jej vložíte do diskuzního fóra a uživatelé na odkaz kliknou? Pokud je kontrola pomocí cookies nebo ip adresy a tito lidé v anketě zatím nehlasovali, pak dojde k započtení jejich hlasu.
Jestliže používají formuláře při předávání dat metodu POST, je situace poněkud složitější. Můžeme samozřejmě zkusit zapsat parametry do URL, stejně jako u metody GET. Někdy to může vést ke zdaru. Mnohem častěji to však takto nepůjde a budeme si muset poradit jinak. Nejprve musíme zjistit, jaké proměnné formulář předává. To nejsnáze zjistíme, nahlédneme-li do zdrojového kódu stránky, kde vyhledáme požadovaný formulář. Někdy jsou však zdrojové kódy tak propletené a složité, že je jednodužší sáhnout po některém z dostupných síťových snifferů, kterým je například Ethereal a zjistit si odchycením paketů, jaká data a v jakém fomátu jsou odesílány. Poté si na svých stránkách vytvoříme kopii formuláře, jehož vstupní pole nastavíme na požadované hodnoty a automaticky je odešleme původnímu cíli. Opět si to ukážeme na konkrétním příkladu s anketou. Nejprve se podíváme do zdrojového kódu ankety, kde vyhledáme patřičný formulář, který může vypadat například takto:
Anketa bývá často tvořena také jednotlivými odkazy, takže není pravidlem, že byste měli hledat pouze formuláře.
Pokud trochu upravíme odesílaná data, můžeme opět použít postup s Netcatem ve smyčce. To ale opět bude fungovat pouze v případě, že provozovatel ankety nijak nekontroluje více vstupů od jednoho návštěvníka. V opačném případě budeme postupovat tak, že nalákáme uživatele Internetu na své stránky, třeba pod záminkou shlédnutí pěkného obrázku a necháme je nevědomky v anketě zahlasovat. Na svých stránkách pro tento účel vytvoříte kopii výše uvedeného formuláře s tím rozdílem, že jednotlivá pole předem naplníte požadovanou hodnotou a dáte jim typ hidden, aby zůstaly skryty před zrakem návštěvníka, který na tuto stránku zavítá. Kód, který zobrazí obrázek a pod ním tlačítko s nápisem další, by mohl vypadat například takto:
Když nyní odešleme odkaz na naše stránky na mnoho e-mailových adres nebo jej vložíme do různých diskusních fór, máme jistotu, že se najde určité procento uživatelů, kteří na tento odkaz kliknou. Po shlédnutí vtipného obrázku, jistě zatouží po dalších a tak stisknou tlačítko "další". Tím ovšem dojde k odesální formuláře skriptu, který za ně přidá hlas v anketě.
Určitě sami vidíte, že má popsaný způsob několik částí, které by se dali zlepšit. První, co vás asi napadne je, že by bylo dobré, kdyby se zahlasovalo automaticky po vstupu na stránku a ne až po kliknutí na tlačítko. Jednoduchou úpravou kódu můžeme docílit toho, že formulář odešle data pomocí javascriptu okamžitě po vstupu uživatele a nemusíme tím pádem ani zobrazovat žádný obrázek. Kód by vypadal takto:
Další z věcí, které na našem postupu nejsou zrovna nejlepší je to, že po automatickém zahlasování je uživatel, který na náš odkaz kliknul, přesměrován na stránky ankety, kde mu je například zobrazena hláška "Děkujeme za Váš hlas v anketě". Nejlepší by samozřejmě bylo, pokud bychom uživatele nalákali na náš obrázek a hlasování by se uskutečnilo na pozadí, aniž by se o tom uživatel dozvěděl. Toho můžeme dosáhnout tak, že použijeme framy. Tak dojde zároven k načtení obrázku do jednoho framu a k zahlasování v anketě ve framu druhém. Pokud framu, který se postará o hlasování v anketě, nastavíme nulovou velikost, bude uživateli zobrazen pouze náš obrázek. Použili bychom k tomu celkem třech souborů umístěných na naší stránce. Soubory by mohly vypadat takto:
Může se také stát, že při hlasování v anketě je nám po zaslání hlasu zobrazen dotaz, zda si skutečně přejeme dát hlas právě této volbě a musíme ještě svou volbu potvrdit. V takovém případě bychom použili framů tří. První by nic netušícímu uživateli zobrazil obrázek, druhý by odeslal hlas do ankety a třetí by s určitým zpožděním odeslal potvrzení hlasu.
Vložení odkazu a čekání, až na něj některý z návštěvníků klikne, není jedinou z variant útoku CSRF. Máme-li k dispozici možnost vložit na stránky odkaz na obrázek, můžeme jej nasměrovat na náš script, který se provede vždy, když návštěvník na stránky zavítá namísto zobrazení obrázku. V tomto případě stačí vložit na stránku tag <img src="http://www.utocnik.cz/fakeimg">.
Pokud jste zalogováni do webové aplikace (informační portál, webmail, e-banking, apd.), budete zřejmě identifikováni na základě session, cookie, apd. Pokud útočník nezná vaše přihlašovací údaje, nemůže s vaším účtem nijak nakládat. Může však výše popsanými metodami využít útoku CSRF k tomu, aby uživatele donutil nevědomky provádět činnosti, které by jinak nikdy neudělal. Uvedeme si příklad zneužití.
Registrovaný uživatel webové aplikace má většinou možnost pomocí formuláře měnit nastavení svého účtu. Může si měnit své přístupové heslo, login, jméno, e-mailovou adresu pro přeposílání pošty, apd. Pokud by si útočník zjistil strukturu formuláře, který se stará o změnu těchto údajů, mohl by do diskuze vložit odkaz na své stránky, kde by byl připraven zákeřný kód, který by odeslal pod identitou uživatele údaje potřebné pro změnu jeho osobního nastavení.
Zde je pár příkladů z nedávné historie:
blackhole.sk – Známá stránka věnující se hackingu, kde bylo tímto způsobem možné změnit přístupové heslo uživatele a ovládnout tak plně jeho účet, viz. oznámení.
Seznam.cz - zde se nacházela chyba, která díky CSRF umožnila přidat jakoukoliv e-mailovou adresu do seznamu adres pro přesměrování příchozí pošty, viz. článek Uživatelé SEZNAM.CZ v ohrožení
SOOM.cz - Ještě do nedávna zde byla možnost změnit útokem CSRF e-mailovou adresu registrovaného uživatele a poté si nechat zaslat zapomenuté heslo. Tímto způsobem bylo možné celý účet plně ovládnout.
Pokud tato zranitelnost není ošetřena v bankovní aplikaci, může útočník bez vědomí uživatele disponovat s jeho účtem, vkládat jeho jménem příkazy k úhradě, apd.
Jak je vidět, jsou zranitelnosti tohoto druhu velmi nebezpečné a bohužel i docela rozšířené. Podíváme se proto také na způsoby ochrany.
Jedním z primitivních způsobů ochrany je kontrola hodnoty REFERER, která by měla uvádět, odkud zaslaná data přichází. Bohužel lze tuto hodnotu spoofovat tak, aby obsahovala jinou než skutečnou hodnotu, nebo aby tato hlavička nebyla uvedena vůbec. Tento způsob proto nelze v žádném případě doporučit. Řešením může být dynamické pole ve formuláři, které se plní jedinečným identifikačním řetězcem nebo opisování náhodného kódu z obrázku. V těchto případech, pokud stránka neobsahuje zranitelnost XSS, není možné řetězec zjistit a zakomponovat jej do odesílaných dat. Více se o obraně proti útokům CSFR můžete dočíst například v tomto článku.
Zdroj: Zranitelný kód