logo

SQL Injection

SQL Injection je bezpečnostná chyba vo webových aplikáciách, kde útočníci vkladajú škodlivý kód SQL prostredníctvom vstupu používateľa. To im môže umožniť prístup k citlivým dátam, zmeniť obsah databázy alebo dokonca prevziať kontrolu nad systémom. Je dôležité vedieť o SQL Injection, aby boli webové aplikácie zabezpečené.

SQL Injection (SQLi) je bezpečnostná chyba, ktorá sa vyskytuje, keď útočník môže manipulovať s databázovými dotazmi webovej aplikácie vložením škodlivého kódu SQL do používateľských vstupných polí. Tieto vložené dotazy môžu manipulovať so základnou databázou, aby získali úpravu alebo odstránenie citlivých údajov. V niektorých prípadoch môžu útočníci dokonca eskalovať privilégiá a získať tak plnú kontrolu nad databázou alebo serverom.



sql injekcia' title=

Príklad zo skutočného sveta:

V roku 2019 došlo k narušeniu údajov Capital One v dôsledku nesprávne nakonfigurovanej webovej aplikácie, ktorá umožnila útočníkovi zneužiť zraniteľnosť vkladania SQL. To viedlo k úniku osobných údajov viac ako 100 miliónov zákazníkov vrátane mien, adries a kreditného skóre.

Úroveň zabezpečenia vstrekovania SQL

DVWA poskytuje štyri úrovne zabezpečenia pre SQL Injection, aby pomohla študentom vidieť, ako rôzne ochrany ovplyvňujú útoky:



1. Nízka bezpečnosť

Aplikácia prevezme váš vstup a priamo ho vloží do dotazu SQL bez filtrovania.

$id = $_GET['id'];$query = 'SELECT first_name last_name FROM users WHERE user_id = '$id';';
  • Zadávanie ': Preruší dotaz a spôsobí, že databáza vyvolá chybu, ktorá odhalí, že je zraniteľná.
  • Zadávanie 1' OR '1'='1: Oklame dopyt tak, aby bol vždy pravdivý, takže sa vrátia všetci používatelia.
  • Zadávanie 1' UNION SELECT user password FROM users--: Pripojí sa k inému dotazu na získanie skrytých údajov, ako sú používateľské mená a heslá.

2. Stredná bezpečnosť

Aplikácia aplikuje základnú vstupnú dezinfekciu pomocou funkcií akoaddslashes()uniknúť'.

$id = addslashes($_GET['id']);$query = 'SELECT first_name last_name FROM users WHERE user_id = '$id';';

Ako môže byť útok:



Jednoduché'injekcia už nebude fungovať (pretože sa stane').

Útočníci však stále môžu obísť pomocou numerickej injekcie (pretože čísla nepotrebujú úvodzovky).
Príklad:

vrchný príkaz unix
1 OR 1=1

Toto stále vráti všetky záznamy.

3. Vysoká bezpečnosť

Aplikácia používa pripravené príkazy (parametrizované dotazy) na bezpečné spracovanie vstupov používateľa.

$stmt = $pdo->prepare('SELECT first_name last_name FROM users WHERE user_id = ?');$stmt->execute([$id]);

Útok:

Pokusy ako' OR 1=1aleboUNION SELECTuž nepracuje.

Dotaz považuje všetky vstupy za údaje, nie za kód SQL.

Typy SQL injekcie

Existujú rôzne typy SQL Injection

1. Injekcia SQL založená na chybách

Injekcia SQL založená na chybách je typ injekcie SQL v rámci pásma, pri ktorej útočník úmyselne spôsobí, že databáza vygeneruje chybové hlásenie. Útočník potom analyzuje túto chybovú správu, aby získal cenné informácie o štruktúre databázy, ako sú názvy tabuliek a názvy stĺpcov, ktoré možno použiť na ďalšie presnejšie útoky.

Ako to funguje

Tento útok sa zameriava na aplikácie, ktoré odhaľujú nespracované chyby databázy namiesto zobrazovania všeobecných správ. Vložením škodlivého vstupu, ktorý porušuje syntax SQL, útočníci spúšťajú tieto chyby a získavajú cenné informácie o štruktúre databázy.

vek kylie jenner
  1. Identifikujte zraniteľný vstup: Útočník nájde vstupné pole, ako je vyhľadávací panel alebo parameter adresy URL, ktorý priamo interaguje s databázou bez náležitej dezinfekcie vstupu.
  2. Vloženie škodlivého nákladu: Útočník vloží špeciálny znak (napríklad jednu úvodzovku') alebo funkciu, o ktorej je známe, že spôsobuje chybu databázy.
  3. Analyzujte chybu: Databáza, ktorá nedokáže spracovať chybný dotaz, vráti podrobné chybové hlásenie. Táto správa môže odhaliť dôležité informácie, ako napríklad:
    • Databázový systém (napr. MySQL Oracle SQL Server).
    • Verzia databázy.
    • Vykonáva sa úplný SQL dotaz.
    • Špecifické chyby syntaxe, ktoré možno použiť na pochopenie názvov tabuliek alebo stĺpcov.
  4. Upravte útok: Pomocou informácií zhromaždených z chybového hlásenia môže útočník spresniť svoje užitočné zaťaženie, aby získal viac údajov, ako sú používateľské mená a heslá.

Príklad:

Krok 1: Nastavte si prostredie

  • Spustite DVWA. Zvyčajne sa k nemu dostanete tak, že prejdete na adresu URLhttp://localhost/dvwavo vašom prehliadači.
súbor' loading='lazy' title=
  • Prihláste sa do DVWA pomocou predvolených poverení:admin/password.
súbor' loading='lazy' title=
  • Prejdite na kartu Zabezpečenie DVWA a nastavte úroveň zabezpečenia na nízku. To zabezpečí, že zraniteľné miesta sa dajú ľahko zneužiť.
súbor' loading='lazy' title=

Krok 2: Identifikujte zraniteľnosť

Stránka SQL Injection má jednoduché vstupné pole, do ktorého môžete zadať ID používateľa. Backendový dotaz je pravdepodobne niečo akoSELECT * FROM users WHERE id = 'user_input'

  • Zadajte platné ID ako1do vstupného poľa a kliknite na tlačidlo Odoslať. Mali by ste vidieť podrobnosti o používateľovi s ID 1.
súbor' loading='lazy' title=

SQL Injection Source

PHP
 $id = $_REQUEST[ 'id' ]; switch ($_DVWA['SQLI_DB']) { case MYSQL: // Check database $query = 'SELECT first_name last_name FROM users WHERE user_id = '$id';'; $result = mysqli_query($GLOBALS['___mysqli_ston'] $query ) or die( '
' . ((is_object($GLOBALS['___mysqli_ston'])) ? mysqli_error($GLOBALS['___mysqli_ston']) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '
'
); // Get results while( $row = mysqli_fetch_assoc( $result ) ) { // Get values $first = $row['first_name']; $last = $row['last_name']; // Feedback for end user echo '
ID: {$id}  
First name:
{$first}
Surname:
{$last}
'
; } mysqli_close($GLOBALS['___mysqli_ston']); break; case SQLITE: global $sqlite_db_connection; #$sqlite_db_connection = new SQLite3($_DVWA['SQLITE_DB']); #$sqlite_db_connection->enableExceptions(true); $query = 'SELECT first_name last_name FROM users WHERE user_id = '$id';'; #print $query; try { $results = $sqlite_db_connection->query($query); } catch (Exception $e) { echo 'Caught exception: ' . $e->getMessage(); exit(); } if ($results) { while ($row = $results->fetchArray()) { // Get values $first = $row['first_name']; $last = $row['last_name']; // Feedback for end user echo '
ID: {$id}  
First name:
{$first}
Surname:
{$last}
'
; } } else { echo 'Error in fetch '.$sqlite_db->lastErrorMsg(); } break; } } ode ?>
  • Teraz skúste prerušiť dopyt. Zadajte jedinú cenovú ponuku'do zadávacieho poľa a odošlite.
súbor' loading='lazy' title=

Dotaz sa stáva:

SELECT * FROM users WHERE id = ''';

Tu databáza vidí ďalšiu cenovú ponuku a nevie, ako dokončiť dotaz.

c++ rozdelený reťazec

Namiesto zobrazenia podrobností o používateľovi aplikácia vráti chybu SQL (niečo ako 'Máte chybu v syntaxi SQL...')

Toto sa nazýva chybová injekcia SQL, pretože:

  • Útočník odošle neplatný vstup (')
  • Databáza vyhodí chybu
  • Táto chyba uvoľňuje užitočné informácie o databáze (napríklad typ štruktúry počtu stĺpcov v databáze atď.)

2. Union-Based SQL Injection

Union-based SQL Injection je technika, pri ktorej útočníci používajúUNIONoperátora spojiť výsledky dvoch alebo viacerýchSELECTdo jednej sady výsledkov. To im môže umožniť extrahovať informácie z iných tabuliek v databáze. TheUNIONoperátor je možné použiť len vtedy, ak:

  • Oba dotazy majú rovnaký počet stĺpcov
  • Stĺpce majú podobné typy údajov
  • Stĺpce sú v rovnakom poradí

Operátor UNION : TheUNIONOperátor sa používa na spojenie množiny výsledkov dvoch alebo viacerýchSELECTvyhlásenia.

  • KaždýSELECTvyhlásenie v rámciUNIONmusí mať rovnaký počet stĺpcov
  • Stĺpce musia mať podobné typy údajov
  • Stĺpce musia byť v rovnakom poradí
SELECT column_name(s) FROM table1UNIONSELECT column_name(s) FROM table2

Príklad:

Krok 1: Najprv musíme nájsť počet stĺpcov existujúcej tabuľky na webovej stránke, aby sme vložili injekciu SQL založenú na UNION:

Stránka SQL Injection má jednoduché vstupné pole, do ktorého môžete zadať ID používateľa. Backendový dotaz je pravdepodobne niečo ako

 SELECT * FROM users WHERE id = 'user_input'

Teraz skúste prerušiť dopyt. Zadajte jedinú cenovú ponuku'do zadávacieho poľa a odošlite.

Ak je aplikácia zraniteľná, zobrazí sa podrobné chybové hlásenie. Môže to vyzerať nejako takto:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''' at line 1

Krok 2: PoužiteUNIONKľúčové slovo na zistenie počtu stĺpcov

Ak chcete použiťUNIONkľúčové slovo (bežný ďalší krok) potrebujete poznať počet stĺpcov v pôvodnom dopyte. Môžete to zistiť pomocouORDER BYdoložka

názov mesta v usa
  • Skúste zoradiť výsledky podľa stĺpca
1: 1 ORDER BY 1. 
  • Odoslať. Malo by to fungovať.
súbor' loading='lazy' title=

SQL Injection Source

PHP
 if( isset( $_REQUEST[ 'Submit' ] ) ) { // Get input $id = $_REQUEST[ 'id' ]; switch ($_DVWA['SQLI_DB']) { case MYSQL: // Check database $query = 'SELECT first_name last_name FROM users WHERE user_id = '$id';'; $result = mysqli_query($GLOBALS['___mysqli_ston'] $query ) or die( '
' . ((is_object($GLOBALS['___mysqli_ston'])) ? mysqli_error($GLOBALS['___mysqli_ston']) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '
'
); // Get results while( $row = mysqli_fetch_assoc( $result ) ) { // Get values $first = $row['first_name']; $last = $row['last_name']; // Feedback for end user echo '
ID: {$id}  
First name:
{$first}
Surname:
{$last}
'
; } mysqli_close($GLOBALS['___mysqli_ston']); break; case SQLITE: global $sqlite_db_connection; #$sqlite_db_connection = new SQLite3($_DVWA['SQLITE_DB']); #$sqlite_db_connection->enableExceptions(true); $query = 'SELECT first_name last_name FROM users WHERE user_id = '$id';'; #print $query; try { $results = $sqlite_db_connection->query($query); } catch (Exception $e) { echo 'Caught exception: ' . $e->getMessage(); exit(); } if ($results) { while ($row = $results->fetchArray()) { // Get values $first = $row['first_name']; $last = $row['last_name']; // Feedback for end user echo '
ID: {$id}  
First name:
{$first}
Surname:
{$last}
'
; } } else { echo 'Error in fetch '.$sqlite_db->lastErrorMsg(); } break; } } ?>
  • Zvýšte číslo:
 1 ORDER BY 2. 

Odoslať. Malo by to fungovať.

súbor' loading='lazy' title=
  • Pokračujte v zvyšovaní, kým sa nezobrazí chyba. Napríklad1 ORDER BY 4môže ti dať:Unknown column '4' in 'order clause'
  • To znamená, že dotaz má 3 stĺpce.

3. Blind-Based SQL Injection

Blind SQL Injection nastane, keď útočníci nemôžu vidieť výsledky dopytu priamo na webovej stránke. Namiesto toho odvodzujú informácie z jemných zmien v správaní aplikácie alebo dobe odozvy. Hoci je pomalší a únavnejší ako klasické SQLi, môže byť rovnako efektívny.

Namiesto získavania údajov späť útočník vyvodzuje informácie sledovaním správania webovej stránky. Zvyčajne sa to robí jedným z dvoch spôsobov:

  1. Blind SQLi na báze booleovských hodnôt: Útočník vloží dotaz SQL, ktorý vráti a pravda alebo falošný výsledok. Odpoveď webovej aplikácie sa mení podľa toho, či je dotaz pravdivý alebo nepravdivý. Stránka môže napríklad zobraziť inú správu alebo vykresliť iné rozloženie.
  2. Časovo orientované slepé SQLi: Útočník vloží dotaz SQL, ktorý spôsobí, že databáza vykoná časovo náročnú akciu (ako naprSLEEP()funkcia), ak je splnená podmienka. Útočník sleduje čas potrebný na načítanie stránky, aby určil, či bola vložená podmienka pravdivá alebo nepravdivá.

Príklad:

Predstavte si prihlasovaciu stránku, kde zadáte používateľské meno a heslo. Aplikácia vytvorí dotaz SQL takto:

SELECT * FROM users WHERE username = 'user_input' AND password = 'password_input'

Slepá injekcia SQL by zahŕňala manipuláciu suser_inputpole na položenie otázky databáze.

Namiesto získania priamej odpovede môže útočník skúsiť niečo takéto:

user_input = 'admin' AND 1=1; --

Ak sa stránka načíta normálne, útočník to vie1=1je a pravda vyhlásenie.

user_input = 'admin' AND 1=2; --

Ak stránka zobrazuje chybu alebo sa správa inak, útočník to vie1=2je a falošný vyhlásenie.

súbor' loading='lazy' title=

Použitím série týchto pravdivých/nepravdivých otázok môže útočník systematicky hádať a extrahovať informácie jeden znak po druhom. Proces môže byť automatizovaný, aby uhádol všetko od názvov tabuliek po používateľské heslá.

Vplyv útokov SQL Injection

  • Neoprávnený prístup k citlivým údajom : Útočníci môžu získať osobné finančné alebo dôverné informácie uložené v databáze.
  • Problémy s integritou údajov : Útočníci môžu upraviť vymazanie alebo poškodenie dôležitých údajov ovplyvňujúcich funkčnosť aplikácie.
  • Eskalácia privilégií : Útočníci môžu obísť autentifikačné mechanizmy a získať administrátorské privilégiá.
  • Výpadok služby : Injekcia SQL môže preťažiť server a spôsobiť zníženie výkonu alebo zlyhanie systému.
  • Poškodenie dobrého mena : Úspešný útok môže vážne poškodiť povesť organizácie, čo vedie k strate dôvery zákazníkov.

Predchádzanie útokom SQL Injection

Existuje niekoľko osvedčených postupov, ako zabrániť útokom SQL injection:

1. Použite pripravené výpisy a parametrizované dotazy

Pripravené príkazy a parametrizované dotazy zaisťujú, že používateľské vstupy sa považujú za údaje a nie za súčasť dotazu SQL. Tento prístup eliminuje riziko vstrekovania SQL.

Príklad v PHP (pomocou MySQLi):

$stmt = $conn->prepare('SELECT * FROM users WHERE username = ? AND password = ?'); $stmt->bind_param('ss' $username $password); $stmt->execute();

2. Využite uložené procedúry

Uložené procedúry sú preddefinované SQL dotazy uložené v databáze. Tieto procedúry môžu pomôcť zabrániť vstrekovaniu SQL, pretože dynamicky nevytvárajú SQL dotazy.

Príklad:

CREATE PROCEDURE GetUserByUsername (IN username VARCHAR(50)) BEGIN SELECT * FROM users WHERE username = username; END;

3. Overenie vstupu na bielu listinu

Pred použitím v SQL dotazoch sa uistite, že užívateľské vstupy sú overené. Povoľte len určité znaky a vzory, ako je alfanumerický vstup pre polia, ako sú používateľské mená alebo e-mailové adresy.

spätné volanie do pekla v javascripte

4. Používajte rámce ORM

Rámce objektovo-relačného mapovania (ORM) ako napr Hibernácia alebo Entity Framework môže pomôcť zabrániť vstrekovaniu SQL automatickým spracovaním generovania dotazov, čím sa zabráni dynamickej konštrukcii dotazov.

5. Obmedzte privilégiá databázy

Udeľte používateľom minimálne požadované oprávnenia k databáze. Zabezpečte, aby aplikácie mohli vykonávať iba nevyhnutné akcie (napr. SELECT INSERT) a obmedzte povolenia ako DROP TABLE alebo ALTER.

6. Spracovanie chýb

Nakonfigurujte databázu a aplikáciu tak, aby používateľovi nezobrazovala podrobné chybové správy. Namiesto toho zaznamenávajte chyby interne a zobrazujte generické chybové správy koncovým používateľom.