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.

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=1Ez 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
- 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.
- 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. - 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.
- 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ő el
http://localhost/dvwaa böngészőjében.
- Jelentkezzen be a DVWA-ba az alapértelmezett hitelesítő adatokkal:
admin/password.
- 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.
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ául
1a beviteli mezőbe, és kattintson a "Küldés" gombra. Látnia kell az 1-es azonosítójú felhasználó adatait.
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.
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.
- Minden
SELECTnyilatkozat 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 table2Pé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.
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.
- Folytassa a növelést, amíg hibaüzenetet nem kap. Például
1 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:
- 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.
- 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ául
SLEEP()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.
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.