logo

SQL Injekció

Az SQL Injection a webalkalmazások biztonsági hibája, ahol a támadók káros SQL-kódot szúrnak be a felhasználói bevitellel. Ez lehetővé teszi számukra, hogy hozzáférjenek az érzékeny adatokhoz, módosítsák az adatbázis tartalmát, vagy akár átvegyék a rendszer irányítását. A webalkalmazások biztonságának megőrzése érdekében fontos tudni az SQL Injectiont.

Az SQL-injekció (SQLi) egy biztonsági rés, amely akkor fordul elő, ha a támadó manipulálni tudja egy webalkalmazás adatbázis-lekérdezését úgy, hogy rosszindulatú SQL-kódot szúr be a felhasználói beviteli mezőkbe. Ezek a beszúrt lekérdezések manipulálhatják az alapul szolgáló adatbázist érzékeny adatok módosítása vagy törlése érdekében. Egyes esetekben a támadók akár kiterjeszthetik is a jogosultságokat, hogy teljes irányítást szerezzenek az adatbázis vagy a kiszolgáló felett.



sql injekció' title=

Valós példa:

2019-ben a Capital One Data Breach egy rosszul konfigurált webalkalmazás miatt következett be, amely lehetővé tette a támadók számára, hogy kihasználják az SQL-befecskendezési sebezhetőséget. Ennek eredményeként több mint 100 millió ügyfél személyes adatai szivárogtak ki, beleértve a neveket, címeket és hitelképességi pontszámokat.

SQL Injection biztonsági szint

A DVWA négy biztonsági szintet biztosít az SQL Injection számára, hogy segítse a tanulókat abban, hogy meglássák, hogyan hatnak a különböző védelmek a támadásokra:



1. Alacsony biztonság

Az alkalmazás fogadja a bemenetet, és szűrés nélkül közvetlenül az SQL-lekérdezésbe helyezi.

$id = $_GET['id'];$query = 'SELECT first_name last_name FROM users WHERE user_id = '$id';';
  • Belépés ': Megszakítja a lekérdezést, és az adatbázis hibát dob, jelezve, hogy sebezhető.
  • Belépés 1' OR '1'='1: Becsapja a lekérdezést, hogy mindig igaz legyen, így minden felhasználó visszakerül.
  • Belépés 1' UNION SELECT user password FROM users--: Egy másik lekérdezéshez csatlakozik a rejtett adatok, például a felhasználónevek és jelszavak lekéréséhez.

2. Közepes biztonság

Az alkalmazás alapvető bemeneti fertőtlenítést alkalmaz olyan funkciók segítségével, mintaddslashes()megszökni'.

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

Hogyan lehet támadás:



Egy egyszerű'az injekció többé nem fog működni (mert azzá válik').

De a támadók továbbra is megkerülhetik a numerikus injekciót (mivel a számokhoz nem kell idézőjel).
Példa:

hogyan kell végrehajtani egy szkriptet
1 OR 1=1

Ez továbbra is visszaadja az összes rekordot.

3. Magas biztonság

Az alkalmazás előkészített utasításokat (paraméterezett lekérdezéseket) használ a felhasználói bevitel biztonságos kezelésére.

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

Támadás:

Olyan próbálkozások, mint' OR 1=1vagyUNION SELECTmár nem működik.

A lekérdezés minden bemenetet adatként kezel, nem SQL-kódként.

Az SQL-befecskendezés típusai

Az SQL-injekciónak különböző típusai vannak

1. Hibaalapú SQL-injekció

A hibaalapú SQL-befecskendezés a sávon belüli SQL-befecskendezés egy olyan típusa, ahol a támadó szándékosan hibaüzenetet generál az adatbázisban. A támadó ezt követően elemzi ezt a hibaüzenetet, hogy értékes információkat szerezzen az adatbázis szerkezetéről, például táblanevekről és oszlopnevekről, amelyek segítségével további pontosabb támadásokat hozhat létre.

Hogyan működik

Ez a támadás olyan alkalmazásokat céloz, amelyek általános üzenetek megjelenítése helyett nyers adatbázishibákat tárnak fel. Az SQL szintaxist megtörő rosszindulatú bevitel beszúrásával a támadók ezeket a hibákat váltják ki, és értékes nyomokat nyernek az adatbázis szerkezetéről.

sklearn pontossági pontszám
  1. Sebezhető bemenet azonosítása: A támadó talál egy beviteli mezőt, például egy keresősávot vagy egy URL-paramétert, amely közvetlenül kölcsönhatásba lép az adatbázissal, megfelelő beviteli fertőtlenítés nélkül.
  2. Rosszindulatú rakomány beadása: A támadó bead egy speciális karaktert (például egyetlen idézetet') vagy egy olyan függvény, amelyről ismert, hogy adatbázishibát okoz.
  3. A hiba elemzése: Az adatbázis nem tudja feldolgozni a hibás lekérdezést, részletes hibaüzenetet ad vissza. Ez az üzenet olyan fontos információkat fedhet fel, mint például:
    • Az adatbázisrendszer (pl. MySQL Oracle SQL Server).
    • Az adatbázis verziója.
    • A teljes SQL lekérdezés végrehajtása folyamatban van.
    • Konkrét szintaktikai hibák, amelyek a tábla- vagy oszlopnevek megértéséhez használhatók.
  4. A támadás finomítása: A hibaüzenetből összegyűjtött információk felhasználásával a támadó finomítani tudja a hasznos terhelést, hogy több adatot, például felhasználóneveket és jelszavakat nyerjen ki.

Példa:

1. lépés: Állítsa be környezetét

  • Indítsa el a DVWA-t. Általában egy URL-hez való navigálással érhető elhttp://localhost/dvwaa böngészőjében.
fájlt' loading='lazy' title=
  • Jelentkezzen be a DVWA-ba az alapértelmezett hitelesítő adatokkal:admin/password.
fájlt' loading='lazy' title=
  • Lépjen a DVWA Security fülre, és állítsa a biztonsági szintet alacsonyra. Ez biztosítja, hogy a sérülékenységek könnyen kihasználhatók legyenek.
fájlt' loading='lazy' title=

2. lépés: Azonosítsa a sebezhetőséget

Az SQL Injection oldalon van egy egyszerű beviteli mező, ahol megadhatja a felhasználói azonosítót. A háttérlekérdezés valószínűleg valami ilyesmiSELECT * FROM users WHERE id = 'user_input'

  • Adjon meg egy érvényes azonosítót, mint például1a beviteli mezőbe, és kattintson a "Küldés" gombra. Látnia kell az 1-es azonosítójú felhasználó adatait.
fájlt' loading='lazy' title=

SQL beadási forrás

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 ?>
  • Most próbálja megszakítani a lekérdezést. Adjon meg egyetlen idézetet'a beviteli mezőbe, és küldje el.
fájlt' loading='lazy' title=

A lekérdezés a következő lesz:

SELECT * FROM users WHERE id = ''';

Itt az adatbázis egy extra árajánlatot lát, és nem tudja, hogyan fejezze be a lekérdezést.

inurl:.git/head

A felhasználói adatok megjelenítése helyett az alkalmazás SQL-hibát ad vissza (ilyen például: „Hiba van az SQL-szintaxisban…”)

Ezt hívják hibaalapú SQL-injekciónak, mert:

  • A támadó érvénytelen bevitelt küld (')
  • Az adatbázis hibát jelez
  • Ez a hiba hasznos információkat szivárog ki az adatbázisról (például a DB oszlopok száma szerkezetének típusa stb.)

2. Unió-alapú SQL-injekció

Az Unió-alapú SQL Injection egy olyan technika, ahol a támadók aUNIONoperátor két vagy több eredményének kombinálásáhozSELECTkijelentéseket egyetlen eredményhalmazba. Ez lehetővé teszi számukra, hogy információkat nyerjenek ki az adatbázis más tábláiból. AUNIONoperátor csak akkor használható, ha:

  • Mindkét lekérdezésnek ugyanannyi oszlopa van
  • Az oszlopok hasonló adattípusokkal rendelkeznek
  • Az oszlopok ugyanabban a sorrendben vannak

UNION operátor : AUNIONoperátor a kettő vagy több eredményhalmaz kombinálására szolgálSELECTnyilatkozatok.

  • MindenSELECTnyilatkozat belülUNIONugyanannyi oszlopnak kell lennie
  • Az oszlopoknak hasonló adattípusokkal kell rendelkezniük
  • Az oszlopoknak ugyanabban a sorrendben kell lenniük
SELECT column_name(s) FROM table1UNIONSELECT column_name(s) FROM table2

Példa:

1. lépés: Először is meg kell találnunk a webhelyen lévő meglévő tábla oszlopainak számát az UNION alapú SQL Injection beszúrásához:

Az SQL Injection oldalon van egy egyszerű beviteli mező, ahol megadhatja a felhasználói azonosítót. A háttérlekérdezés valószínűleg valami ilyesmi

 SELECT * FROM users WHERE id = 'user_input'

Most próbálja megszakítani a lekérdezést. Adjon meg egyetlen idézetet'a beviteli mezőbe, és küldje el.

Ha az alkalmazás sebezhető, részletes hibaüzenetet fog kapni. Valahogy így nézhet ki:

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

2. lépés: Használja aUNIONKulcsszó az oszlopok számának felfedezéséhez

Használatához aUNIONkulcsszó (egy gyakori következő lépés), ismernie kell az eredeti lekérdezés oszlopainak számát. Ezt a segítségével megtudhatjaORDER BYzáradék

parancs arp-a
  • Próbálja meg az eredményeket oszlopok szerint rendezni
1: 1 ORDER BY 1. 
  • Beküld. Működnie kell.
fájlt' loading='lazy' title=

SQL befecskendezési forrás

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; } } ?>
  • Növelje a számot:
 1 ORDER BY 2. 

Beküld. Működnie kell.

fájlt' loading='lazy' title=
  • Folytassa a növelést, amíg hibaüzenetet nem kap. Például1 ORDER BY 4adhat neked:Unknown column '4' in 'order clause'
  • Ez azt jelenti, hogy a lekérdezésnek 3 oszlopa van.

3. Blind-Based SQL Injection

Vak SQL-injekció akkor fordul elő, ha a támadók nem látják közvetlenül a weboldalon a lekérdezés eredményeit. Ehelyett az alkalmazás viselkedésének vagy válaszidejének finom változásaiból következtetnek az információkra. Bár lassabb és fárasztóbb, mint a klasszikus SQLi, ugyanolyan hatékony lehet.

Az adatok visszaszerzése helyett a támadó a weboldal viselkedésének megfigyelésével következtet információkra. Ez általában kétféle módon történik:

  1. Logikai alapú vak SQLi: A támadó bead egy SQL-lekérdezést, amely a igaz vagy hamis eredmény. A webalkalmazás válasza attól függően változik, hogy a lekérdezés igaz vagy hamis. Például az oldal más üzenetet jeleníthet meg, vagy más elrendezést jeleníthet meg.
  2. Időalapú vak SQLi: A támadó bead egy SQL lekérdezést, amely időigényes művelet végrehajtására készteti az adatbázist (példáulSLEEP()függvény), ha egy feltétel teljesül. A támadó figyeli, hogy mennyi időbe telik az oldal betöltődése annak megállapításához, hogy a beinjektált feltétel igaz vagy hamis volt-e.

Példa:

Képzeljen el egy bejelentkezési oldalt, ahol megadja a felhasználónevet és a jelszót. Az alkalmazás a következőhöz hasonló SQL-lekérdezést készít:

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

A vak SQL-befecskendezés auser_inputmezőben, hogy kérdést tegyen fel az adatbázisnak.

Ahelyett, hogy közvetlen választ kapna, a támadó valami ilyesmivel próbálkozhat:

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

Ha az oldal normálisan betöltődik, a támadó tudja ezt1=1az a igaz nyilatkozat.

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

Ha az oldal hibát jelez, vagy másként viselkedik, a támadó tudja ezt1=2az a hamis nyilatkozat.

fájlt' loading='lazy' title=

Ezeknek az igaz/hamis kérdéseknek a használatával a támadó szisztematikusan kitalálhatja és egy-egy karakterrel információt nyerhet ki. A folyamat automatizálható, és a táblanevektől a felhasználói jelszavakig mindent kitalál.

java dobás kivétel

Az SQL-injekciós támadások hatása

  • Az érzékeny adatokhoz való jogosulatlan hozzáférés : A támadók lekérhetik az adatbázisban tárolt személyes pénzügyi vagy bizalmas információkat.
  • Adatintegritási problémák : A támadók módosíthatják az alkalmazás működését befolyásoló kritikus adatok törlését vagy megrongálódását.
  • A privilégiumok eszkalációja : A támadók megkerülhetik a hitelesítési mechanizmusokat, és rendszergazdai jogosultságokat szerezhetnek.
  • Szolgáltatás leállás : Az SQL injekció túlterhelheti a kiszolgálót, ami teljesítménycsökkenést vagy rendszerösszeomlást okozhat.
  • A hírnév károsodása : Egy sikeres támadás súlyosan károsíthatja a szervezet hírnevét, ami az ügyfelek bizalmának elvesztéséhez vezethet.

SQL-injekciós támadások megelőzése

Számos bevált módszer létezik az SQL injekciós támadások megelőzésére:

1. Használjon előkészített utasításokat és paraméterezett lekérdezéseket

Az előkészített utasítások és paraméterezett lekérdezések biztosítják, hogy a felhasználói bemeneteket a rendszer adatként kezelje, nem pedig az SQL-lekérdezés részeként. Ez a megközelítés kiküszöböli az SQL injekció kockázatát.

Példa PHP-ben (MySQLi használatával):

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

2. Tárolt eljárások alkalmazása

A tárolt eljárások az adatbázisban tárolt előre meghatározott SQL lekérdezések. Ezek az eljárások segíthetnek megakadályozni az SQL-befecskendezést, mivel nem hoznak létre dinamikusan SQL-lekérdezéseket.

Példa:

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

3. Az engedélyezési lista bevitelének ellenőrzése

Győződjön meg arról, hogy a felhasználói bemenetek érvényesek, mielőtt SQL-lekérdezésekben használnák őket. Csak bizonyos karakterek és minták, például alfanumerikus bevitel engedélyezése olyan mezőkben, mint a felhasználónevek vagy az e-mail címek.

4. Használja az ORM-keretrendszereket

Object-Relational Mapping (ORM) keretrendszerek, mint pl Hibernálni vagy Entitás-keretrendszer segíthet megakadályozni az SQL-befecskendezést azáltal, hogy automatikusan kezeli a lekérdezésgenerálást, megakadályozva a dinamikus lekérdezések felépítését.

5. Az adatbázis-jogosultságok korlátozása

Adja meg a minimálisan szükséges adatbázis-engedélyeket a felhasználóknak. Győződjön meg arról, hogy az alkalmazások csak a szükséges műveleteket hajthatják végre (pl. SELECT INSERT), és korlátozza az engedélyeket, például a DROP TABLE vagy az ALTER engedélyeket.

6. Hibakezelés

Állítsa be az adatbázist és az alkalmazást úgy, hogy ne jelenítsen meg részletes hibaüzeneteket a felhasználónak. Ehelyett belsőleg naplózza a hibákat, és általános hibaüzeneteket jelenít meg a végfelhasználók számára.