تا اینجای کار تا حد خوبی با SQL Injection در پایگاه داده آشنا شدید و چندین مثال از آن را در مقاله union based injection مشاهده کردید.
اما حملات SQL Injection به همین جا ختم نمیشوند و دانستن موارد قبلی مقدمهای است برای فهم و درک نکات جدیدی که طی این مقاله و مقالات بعدی با هم بررسی خواهیم کرد.
هنگامی که موارد قبلی از جمله union based و error based را دقیق امتحان کردیم و متوجه شدیم که سایت قربانی نسبت به این نوع از حملات SQL Injection امن هست و امکان این نوع از حملات SQL Injection وجود ندارد، نباید ناامید شویم زیرا که گزینه دیگری هم به نام Blind SQL Injection وجود دارد که در این مقاله آن را بررسی می کنیم و ممکن است سایت مورد بررسی به آن آسیب پذیر باشد.
Blind SQL Injection چیست؟
تا اینجای کار برای SQL Injection ابتدا از روش error based وارد میشدیم و به ازای Query های مختلف انواع خطا ها را تحلیل و بررسی میکردیم و سپس با استفاده از دستور union، محتوای مطلوبمان را از پایگاه داده استخراج می کردیم.
نکته ی قابل توجه این است که در 2 روش error based و union based، به ازای ورودی های مختلف خروجی های متفاوتی برای ما به نمایش در می آمد و با تزریق یک Query مناسب، نتیجه دلخواهمان در صفحه نمایش داده می شد.
اما فرض کنید که back-end سایت طوری طراحی شده باشد که به ازای ورودی های مختلف، خروجی تنها محدود به 2 حالت باشد؛ به طور خلاصه تر یعنی اینکه ما به هیچ نحوی نتوانیم داده های موردنظرمان را عینا مشاهده کنیم چرا که خروجی خارج از 2 حالت نیست که این 2 حالت معمولا شبیه 2 وضعیت Yes یا No هستند.
اما از آنجا که متوجه شده ایم که این سایت به احتمال زیاد آسیب پذیر به SQL Injection هست، پس احتمالا راه دیگری برای استخراج اطلاعات وجود دارد.
برای بهتر متوجه شدن این قضیه سایت زیر را در نظر بگیرید.
همانطور که مشاهده میکنید در سایت بالا یک فرم ورود User ID داریم که باید تزریق کد را در آن انجام دهیم.
ابتدا چند مقدار متفاوت را وارد میکنیم تا ببینیم چه خروجیهایی برای ما نمایش داده میشود.
مثلاً مقدار 1 را وارد میکنیم و میبینیم که پیام زیر مبنی بر وجود کاربری با ID شماره 1 به نمایش در میآید.
عدد 1 را افزایش داده و هر دفعه پیام بالا را مشاهده میکنیم تا اینکه به عدد 6 میرسیم که پیام خروجی تغییر کرده و مطابق شکل زیر پیامی مبتنی بر عدم وجود کاربری با ID شماره 6 به نمایش در میآید.
با وارد کردن مقادیر مختلف دیگر اعم از عدد یا هر عبارت دیگری که شامل انواع Query ها باشد، متوجه میشویم که پیام خروجی تنها محدود به 2 عبارت بالاست و غیر از این 2 عبارت هیچ چیز دیگری برای ما به نمایش در نمیآید.
پس با محدود بودن خروجی به 2 عبارت بالا نمیتوانیم دادههای موردنظرمان از پایگاه داده را استخراج کنیم؛ زیرا که با وارد کردن هر Query متفاوتی باز هم نتیجه ای غیر از 2 نتیجه بالا حاصل نمیشود.
راه چاره چیست؟
کلید اصلی حملات Blind در همین نکته است که با استفاده از همین 2 خروجی بالا که شبیه Yes و No هست اطلاعاتی که میخواهیم را به دست آوریم؛ اطلاعاتی نظیر لیست کاربران، رمز عبور آنها و اطلاعات حساستری که تنها با همین خروجی Yes و No حاصل میشود.
قطعاً هنوز هم برایتان سؤال هست که چگونه فقط با یک ورودی Yes و No مثلاً رمز عبور یک کاربر را به دست آوریم.
در حقیقت برای بهره وری از همین 2 خروجی باید سوالات مختلفی را از پایگاه داده بپرسیم و در هر سوال که در قالب Query تزریق می شود، با استفاده از همین جواب بله یا خیر مقداری که نیاز داریم را قدم به قدم حدس بزنیم و حدس خود را تکمیل کنیم؛ چیزی شبیه به بازی 20 سوالی که ما صرفا اجازه سوال کردن داریم و طرف مقابل هم تنها می تواند با بله یا خیر جواب ما را بدهد و نهایتا ما باید با استفاده از تحلیل جواب های بله یا خیر مقدار مطلوب را حدس بزنیم.
ورودی زیر را در نظر بگیرید:
همانطور که مشاهده میکنید پیام خروجی مبتنی بر وجود کاربر است؛ یعنی Query بالا همانطور که در مقالات قبلی توضیح دادیم یک گذاره منطقی true را ایجاد می کند و به همین دلیل پیام بالا نمایش داده میشود.
حال کمی شرط ورودی را تغییر می دهیم:
همانطور که توقع داشتیم AND یک عبارت با false نتیجه false میدهد و لذا پیام بالا به نمایش میآید.
با توجه به مثال های بالا Query های مختلفی را می توانیم با استفاده از دستور AND تست کنیم و از خروجی به دست آمده متوجه میشویم که آن عبارت از نظر منطقی صحیح بوده است یا خیر.
عبارات که در Query تزریق می کنیم در حقیقت همان سوال های ماست که در قالب یک عبارت منطقی و در کنار دستور AND تزریق می شود.
یعنی اگر خروجی User ID exists in the database حاصل شد، پس Query ما از نظر منطقی درست بوده و جواب سوال ما Yes هست و اگر خروجی User ID is MISSING from the database حاصل شد، یعنی Query ما نظر منطقی درست نبوده است و جواب سوال ما No هست.
مثلا در Query چک می کنیم که آیا کاراکتر اول رمز عبور کاربر برابر حرف a هست یا خیر؛ و همین طور حروف دیگر را بررسی می کنیم تا نهایتا رمز عبور کاربر را به دست آوریم.
حملات Blind SQL Injection به 2 دسته کلی تقسیم میشوند:
- Boolean Based
- Time Based
مثال هایی که در این مقاله بررسی کردیم نمونه ای از روش Boolean Based بودند که به صورت دقیق تر این روش را در مقالات بعدی بررسی خواهیم کرد.