Pravidelný občasník originálního humoru

Vyhledávače, SQL injection a ideální nástroje hackerů (5)

Autor chlívek (Bezpečnost) - vydáno 31.8.2005

Pokračování bude hlavně o tom, jak vlastně SQL Injection "funguje" a jak se proti ní bránit. Důležité a podstatné


SQL injection je souhrnné označení pro nepříjemné bezpečnostní chyby, které umožní vstouvat do SQL kódu internetové aplikace vlastní informace - pochopitelně takové informace, které umožní změnit smysl původních SQL příkazů. V "nejméně" nebezpečném případě pak lze tímto způsobem získat přístup k datům, ke kterým přístup mít nemáte. Větší nebezpečí vyvolá možnost vstoupit do administračních částí internetové aplikace. A ještě nebezpečnější je okamžik, kdy lze vyvolat příkazy SQL serveru, které umožní ovládnout stroj na kterém SQL server běží. Případně stejně problematická varianta kdy pomocí SQL injection přesvědčíte SQL server aby například smazal nějaké tabulky nebo celou databázi.

SQL injection je použitelná všude tam, kde autoři internetové aplikace zapomněli na základní bezpečnostní pravilo - veškeré vstupy do aplikace je nutné kontrolovat na povolené hodnoty/typy. A je u plně jedno jestli jde o PHP/mySQL či ASP/MSSQL - byť o tom prvním reálně psát nebudu - přeci jenom jsem ten "Microsoftí" zlý hoch.

SQL injection rizikové části internetové aplikace jsou tedy všechna místa, kde něco stupuje zvenčí.

  • Formuláře (POST/GET)
  • Parametry URI
  • HTTP/XML/SOAP komunikace (nezapomenout na Cookies)
  • "Importy" souborů

Nejjednodušší způsob jak otestovat nějakou internetovou aplikaci na SQL injection? Začněte si hrát s vstupy do této aplikace. Na zmíněném příkladu zena-in.cz (screenshot) můžete vidět nejjednodušší způsob, který velmi rychle řekne, jestli je aplikace špatně napsaná a může mít SQL Injection s nebezpečnými následky.

A k formulářům je vhodné dodat ještě jedno malé varování - řada webových aplikací používá "hidden" (skryté) prvky. Tvůrci aplikace mají falešný pocit bezpečí, že tenhle prvek "není" vidět a ani "není" editovatelný. Přitom stačí příslušnou stránku uložit jako HTML, libovolně si jí upravit a pak používat.

' or 1=1 --

Nejdůležitější pomůcka pro ruční test na SQL Injection je řetězec [' or 1=1 --] (hranaté závorky k němu nepatří). 

Pokud takovýto řetězec (můžete si odpustit prozatím ty dvě "--" na konci) použijete pro testování, možná dostanete nějakou tu chybu od SQL serveru - pak víte s jistotou, že tvůrce webové aplikace je bordelář a možná bude jeho server brzy v háji - má neošetřené vstupy do aplikace.

A pokud právě tuhle konstrukci použijete v nejčastějším způsobu testování přihlašovacích informací - a vložíte ji do "políčka" pro heslo?

cSQL = "SELECT uniqueid FROM Users Where UserName='" & request("userid") & "' and Pwd='" & request("pwd") & "'"

Z uvedeného příkladu se pak stane toto:

SELECT uniqueid FROM Users Where UserName='' or 1=1 --' and Pwd='heslo'

Výsledkem bude likvidace nutné podmínky na shodu hesla. A pravděpodobně získání přístupu do systému. "--" se totiž postará o odstranění zbytku SQL dotazu.

Pokud naznačený nejuniverzálnější řetězec nepomůže, zkuste některé další varianty:

  • '' or 1=1 --
  • or 1=1 --
  • ' or 'a'='a
  • případně si pohrajte se závorkami

Jak se vyhnout SQL Injection?

Existuje nespočet návodů jak se SQL Injection vyhnout - pomocí Google a zadání "SQL Injection" jich najdete řadu - budete si tak moci i vybrat zda potřebujete návod pro Microsoft SQL, MySQL či pro "něco" jiného. Principy jsou ale všechny stejné :

Textové vstupy prohnat náhradou ['] za [''] (neboli dvojici apostrofů). Jde o nejjednodušší způsob, který znemožní použít ['] pro "ukončení" vytvářeného SQL dotazu.

Textové vstupy prohnat odpovídající RegExp() transformací, která v něm ponechá pouze znaky, které v něm mají být. Tímto způsobem je pochopitelně více než vhodné ošetřovat i vstupy, které se stanou později výstupy - vyhnete se tak nebezpečí jinému, jménem XSS.

Netextové vstupy prohnat odpovídající typovou konverzí - tj. například pokud ?id=XXX má být integer, tak použít odpovídající konverzí funkci - třeba int()

Vstupy s pevně daným malým výčtem opravdu testovat na to, zda danému výčtu odpovídají. Příkladem může být testování na True/False, On/Off.

Uvedeným způsobem se vyhnete SQL Injection v okamžiku, kdy nechcete použít nějakou jinou metodu tvorby SQL dotazů a zůstáváte u "oeprativní" klasiky sestavování SQL dotazů (způsobem naznačeným výše). Pokud to není nutné (a popravdě, ono to ani není příliš vhodné), tak se můžete vydat dalšími cestami, které uplně stejně zabrání SQL Injection.

Parametrizovatelné SQL využívá toho, že "objekty" používané pro vyvolání SQL dotazů zpravidla umožňují předávat parametry způsoby, které samy o sobě zabezpečí potřebné zabezpečení parametrů.

cSQL = "SELECT uniqueid FROM Users WHERE UserName=@username AND Pwd=@password"

Následně postačí využít SqlCOmmand a s pomocí SQLParameter provést odpovídající "náhradu" definovaných parametrů.

Důsledné používání uložených procedur (stored procedures) je dokonce ještě lepší způsob - hlavně proto, že umožňuje oddělit skutečné SQL dotazy od vlastních skriptů a navíc přidává další prvek zabezpečení (za předpokladu, že víte jak tohle všechno "pospojovat" dohromady) - viz další odstavce.

Co ještě udělat proti SQL Injection?

V krátkém průletu SQL Injection problémem by asi bylo vhodné ještě zdůraznit, že je více než vhodné aby účet pod kterým přistupuje internetová aplikace do SQL serveru by zcela určitě neměl být "sa" (systémový administrátor) účet.

Příslušný účet by dokonce neměl mít žádná "nadbytečná" práva - třeba mazání tabulek není dobré právo (o mazání databází ani nemluvě). A v uplně ideálním případě by měly existovat pouze uložené procedury a příslušný účet by měl mít práva pouze pro jejich spouštění - tím se dá odstranit i případné nebezpečí z "podvrhnutých" lahůdek jako "truncate table" či "delete * from" (popravdě i možnost vytvářet nové tabulky může být nebezpečná, stačí je vytvářet tak dlouho a tak velké až ...).

Autor internetové aplikace by měl zajistit i takovou maličkost, aby aplikace nezobrazovala detailní informace o vyskytnuvší se chybě - příklad zena-in.cz (screenshot) je právě tím špatnám příkladem. Protože IIS aplikace nemá potlačeno zobrazování detailních chyb, můžete při "zkoušení" SQL injection vidět i části SQL kódu - a lépe se tak rozhodovat, jak SQL injection použít.

Nebezpečná je i skutečnost, že běžná instalace MS SQL běží jako SYSTEM účet - pokud se pomocí SQL Injection dostanete k vykonávání systémových uložených procedur, můžete získat kompletní kontrolu nad strojem se SQL Serverem - postačí obyčejné exec master..xp_cmdshell '...', konkrétně pro vložení pomocí SQL Injection budete ještě muset využít [;], který umožňuje "řetězit" SQL příkazy, takže něco jako:

'; exec master..xp_cmdshell '...' --

Fantazii se pak meze nekladou. Můžete si třeba s pomocí FTP stáhnout VNC nebo nějakou jinou utilitu pro vzdálený přístup. A pak případně i spustit.

Mezi systémovými procedurami jsou ale i další hezké použitelné věci - třeba sp_makewebtask, xp_startmail, xp_sendmail = čtyři vyjmenované systémové procedury jsou dobrými kandidáty na smazání (nebo znemožnění přístupu).

Pro praktické využití SQL Injection budete pochopitelně potřebovat znát i některé systémové tabulky - nejužitečnější může být INFORMATION_SCHEMA.TABLES

SELECT * FROM INFORMATION_SCHEMA.TABLES

A následně použít INFORMATION_SCHEMA.COLUMNS  pro zjišťování jmen sloupců v tabulkách.

Související :

 

 

 



|
Poslední změna : 31.8.2005 08:56, Vytvořen : 31.8.2005 08:56, Vydán : 31.8.2005, 18787x

Komentáře pro ty z Facebooku

Aktuální články autora