הזרקת SQL מתקדמת - Blind ו-Time Based¶
כבר הסברנו בפוסט קודם באתר מה זה SQL Injection ואיך חולשה כזאת נראית בבסיס - קלט לא מסונן שנדבק ישירות למשפט SQL. אבל מה קורה כשהאתר לא מציג שום שגיאה, ושום תוצאה של השאילתה לא נראית על המסך? זה בדיוק המקום שבו נכנסות שתי הטכניקות המתקדמות ביותר בתחום - Blind SQL Injection ו-Time Based Blind SQL Injection.
למה בכלל צריך טכניקות "עיוורות"¶
ברוב האתרים המודרניים, מפתחים לא מציגים למשתמש הודעת שגיאה מפורטת של מסד הנתונים. זה נכון וטוב מבחינת אבטחה, אבל זה גם אומר שתוקף שמצא נקודת הזרקה לא רואה שום פלט ישיר מהשאילתה. אין טבלה שמוצגת, אין הודעת שגיאה שמסגירה מבנה. במצב כזה, הדרך היחידה להוציא מידע היא לשאול את מסד הנתונים שאלות של כן או לא, ולהסיק תשובות מתוך התנהגות האתר.
הזרקה מבוססת בוליאני - Boolean-Based¶
הרעיון כאן פשוט ברמת ההיגיון, גם אם המימוש דורש סבלנות. במקום לנסות להוציא נתונים ישירות, שולחים לאתר שאילתה שהתוצאה שלה היא תמיד אמת או שקר, ובודקים אם התנהגות הדף השתנתה. לדוגמה, מבחינה מושגית בסביבת מעבדה, שולחים תנאי שאמור להיות תמיד נכון, ובודקים אם הדף מציג תוכן רגיל. אחר כך שולחים תנאי שאמור להיות תמיד שקרי, ובודקים אם הדף מתנהג אחרת - למשל מציג עמוד ריק, או הודעה שונה. ברגע שיש דרך אמינה להבחין בין "נכון" ל"שקר", אפשר לשאול שאלות ממוקדות יותר, כמו האם התו הראשון בשם הטבלה הוא אות מסוימת, ולבנות תשובה תו אחר תו על ידי מאות שאלות כאלה ברצף.
הזרקה מבוססת זמן - Time-Based Blind¶
לפעמים גם ההתנהגות של הדף לא משתנה בין תשובה חיובית לשלילית - שני המקרים נראים בדיוק אותו דבר. במקרה כזה משתמשים בטריק אחר לגמרי - גורמים למסד הנתונים "לחכות" זמן מסוים אם וכאשר תנאי מסוים מתקיים, באמצעות פונקציה שגורמת לעיכוב, כמו SLEEP. אם שאלתם שאלה ותשובת השרת חזרה כמעט מיד, התנאי כנראה שקרי. אם התשובה התעכבה בכמה שניות, התנאי היה נכון. ההיגיון זהה לבדיקה הבוליאנית, רק שהערוץ להעברת המידע הוא זמן התגובה של השרת ולא תוכן העמוד. זו שיטה איטית מאוד, כי כל תו בודד דורש כמה בקשות, אבל היא עובדת גם כשאין שום רמז חזותי אחר לתפוס אותו.
איך כלים אוטומטיים ניגשים לזה¶
אף אחד לא באמת יושב ידנית ושואל אלפי שאלות של תו אחר תו - זו בדיוק הסיבה שקיימים כלים כמו sqlmap. מבחינה מושגית, כלי כזה עושה בדיוק את מה שתיארנו למעלה, רק בקנה מידה גדול ובמהירות - הוא שולח סדרות של בקשות בוליאניות או מבוססות זמן, לומד אוטומטית מה מבדיל בין תשובה אמיתית לתשובה שקרית, ובונה מתוך זה את שמות הטבלאות, העמודות, ולבסוף את הנתונים עצמם, תו אחרי תו. זה ממחיש טוב מאוד למה חולשת SQL Injection נשארת מסוכנת גם כשאין הודעות שגיאה גלויות - זה רק שאלה של כמה בקשות התוקף מוכן לשלוח.
איך מגנים מפני זה¶
ההגנה הבסיסית ביותר נשארת בדיוק כמו שהסברנו בפוסט הקודם - Prepared Statements, שאילתות מוכנות מראש שמפרידות בין המבנה של השאילתה לבין הקלט של המשתמש, כך שאין בכלל אפשרות להזריק תנאי חדש. אבל כשמדברים ספציפית על Blind ו-Time Based, יש עוד שתי שכבות שכדאי להוסיף כהגנת עומק. הראשונה היא WAF - חומת אש לאפליקציות ווב שיכולה לזהות דפוסי בקשות חוזרות וחשודות ולחסום אותן, גם אם היא לא הגנה מספיקה לבד. השנייה היא ניטור זמני תגובה חריגים - אם אתם רואים כמות גדולה של בקשות שגורמות לעיכובים לא רגילים בשרת, זה סימן אזהרה שכדאי לחקור, כי זה בדיוק העקבות שמתקפת Time Based משאירה מאחוריה.
אם אתם רוצים להעמיק ולתרגל את הטכניקות האלה בעצמכם בסביבה חוקית, מוזמנים לעבור על קורס פריצת אתרים, שבו לומדים גם את הבסיס וגם את הרמות המתקדמות יותר של החולשה הזו.
יש לכם שאלה על משהו כאן, או רוצים לדבר עם אנשים שמתרגלים בדיוק את זה? הצטרפו לקהילה שלנו.
לסיכום¶
הטכניקות של Blind ו-Time Based SQL Injection הן ההוכחה לכך שהיעדר פלט גלוי לא אומר שהאתר מוגן. תוקף סבלני, או כלי אוטומטי, יכול להוציא מידע שלם ממסד נתונים רק על סמך הבדלים דקים בהתנהגות או בזמן תגובה. וזו בדיוק הסיבה שההגנה חייבת להיות ברמת הקוד עצמו, ולא להסתמך על כך שהתוקף "לא יראה" כלום.