
در این بخش از دوره SEC504 از موسسه SANS به آشنایی به حملات تحت وب و آسیب پذیری SQL Injection خواهیم پرداخت.
آسیبپذیری SQL Injection
در این بخش در مورد آسیبپذیری SQL Injection بحث خواهیم کرد. با استفاده از این آسیبپذیری میتوان رکوردها پایگاه داده را Update نموده و یا حذف کرده و یا درخواستهایی را به سمت آن ارسال نموده و خروجی آن را ملاحظه نمود.
با توجه به اینکه امروز اغلب برنامههای تحت وب در پشت پرده با یک پایگاه داده در ارتباط میباشند، به همین دلیل آسیبپذیری SQL Injection هم فراگیر میباشد.
در این آسیبپذیری نفوذگر سعی میکند تا با استفاده از درخواستهایی که به سمت برنامه تحت وب ارسال میکند، با پایگاه داده تعامل نموده و اطلاعات مربوط به پایگاه داده مانند جداول و ستونها را از طریق درخواستهای SQL استخراج نماید.
با استفاده از آسیبپذیری SQL Injection، نفوذگر میتواند بدون مجوز دسترسی (Authorization) اقدام به استخراج و حتی تغییر اطلاعات پایگاه داده شود.
دستورات SQL انواع مختلفی دارند ولی ما در این بخش به دو دستور مهم که Select و Update میباشد، خواهیم پرداخت. از دستور Select برای درخواستها (Query) استفاده میشود در حالی که از دستور Update برای فراخوانی دادهها از یک جدول و یا تغییر در آن استفاده میشود.
توجه داشته باشید که برنامه تحت وب، ورودیها را از کاربر دریافت نموده و آنها را داخل دستورات SQL که شامل Where یا SET میباشد قرار میدهند و این دستورات اجرا شده و نتیجه لازم حاصل میگردد.
Select [field] from [table] where [variable] = ‘[value]’ ;
Update [table] set = ‘’ ;
دو قسمت value معمولا توسط کاربر وارد میشود.
در وهله اول نفوذگر تلاش میکند تا کاراکترهای خاص و دستورات SQL را در بخشهایی که کاربر امکان ورود اطلاعات دارد، وارد نماید و مشاهده کند که آیا این دستورات به سمت پایگاه داده ارسال میشود یا خیر و آیا در سیستم نهایی اجرا میگردد یا خیر.
برای انجام تکنیک SQL Injection ابتدا باید کلیه ورودیهایی که در برنامه تحت وب قرار دارند، شناسایی شود. نفوذگر در این روش به دنبال بخشهایی است که کاربر میتواند در آن مقادیری را وارد نماید. بخشهایی مانند username، Account Number، شناسه محصول، پارامترهای جستجو و بخشهایی شبیه به این موارد، مکان مناسبی برای شناسایی آسیبپذیری SQL Injection میباشد.
پس از شناسایی بخشهای ورودی کاربر، نفوذگر اقدام به ارسال دادههای نامتعارف مانند Single quote یا double quote در این ورودیها مینماید. سپس پاسخ این درخواستها را مورد تجزیه و تحلیل قرار میدهد.
توجه داشته باشید در برخی از موارد مقادیر کنترلی یا فیلترها با استفاده از کدهای جاوا اسکریپت، سمت کاربر کنترل میگردند که این موارد با استفاده از ابزارهای پروکسی و یا با غیر فعال کردن کدهای جاوا اسکریپت مرورگر اصطلاحا Bypass میشود.
همانطور که در بالا به آن اشاره گردید میبایست پارامترهای ورودی را در برنامه تحت وب کشف کرده و مقادیر مختلف را به آن ارسال نماییم. چندین ابزار هستند که به صورت خودکار quotation را به پارامترهای ورودی ارسال نموده و به دنبال پیام خطای پایگاه داده میگردند. در ابزار Nmap نیز یک اسکریپت با نام SQLInject.nse وجود دارد که این کار را انجام میدهد. البته ابزارهایی مانند ZAP Proxy، Burp Suite و SQLmap هم دارای ویژگی اسکن خودکار شناسایی آسیبپذیری SQL میباشند. البته یکی دیگر از ابزارهایی که برای استفاده از آسیبپذیری SQL Injection استفاده میشود، ابزار Havij است.
علاوه بر Single quote و double quote، نفوذگر میتواند از کاراکترهای دیگری نیز استفاده نماید تا برخی اطلاعات دیگر را از پایگاه داده استخراج نماید. برخی از مواردی که در این بخش تست میشود شامل: % ,# ,– ,_ , ;, * باشد.
علاوه بر کاراکترهای خاص عنوان شده در بالا، نفوذگران میتوانند از عبارات منطقی مانند AND و OR استفاده نمایند. همچنین از دستوراتی مانند Select، Join و Update نیز میتوان استفاده نمود. در ادامه مثالهایی برای این موضوع آورده میشود.
فرض کنید که یک برنامه تحت وب در اختیار دارید که با استفاده از Query زیر، اطلاعات کاربری که نام آن در قسمت Value وارد شده است را استخراج میکند.
Select * from users where name = ‘[value]’;
برای تست این بخش، نفوذگر یک single quote را پس از نام کاربری وارد مینماید. در این مثال نام کاربری test میباشد. با این کار Query به صورت زیر در خواهد آمد.
Select * from users where name = ‘test’’;
با این کار در صورت وجود آسیبپذیری SQL Injection یک پیام خطا نمایش داده میشود. پیامهای خطایی که بیانگر وجود آسیبپذیری SQL Injection میباشد عبارتند از:
Database error,
SQL error,
SQL Syntax Error,
ODBC Error,
در ادامه مشاهده خواهید کرد که نفوذگر چه دستوراتی را میتواند بعد از single quote وارد نماید.
Dropping Data
همان Query پیشین را در نظر بگیرید. نفوذگر بعد از single quote عبارت drop table users را وارد میکند که با این کار جدول users از پایگاه داده جاری حذف خواهد شد. به Query زیر توجه نمایید.
Select * from users where name = ‘test’’; drop table users;–
با استفاده از کاراکتر — اگر دستوری در ادامه Query وجود داشته باشد به عنوان کامنت در نظر گرفته شده و اجرا نخواهد شد.
با اجرای دستور بالا در واقع یک حمله DoS نیز اتفاق افتاده است چراکه با توجه به حذف جدول users امکان احراز هویت کاربران مختل شده است.
لازم به ذکر است عبارت — که برای کامنت نمودن استفاده میشود، در پایگاههای داده مختلف متفاوت میباشد.
Grabbing More Data
همان Query پیشین را در نظر بگیرید. نفوذگر بعد از single quote عبارت ‘or 1=1– را وارد میکند که با این کار یک عبارتی که همواره صحیح میباشد را به انتهای Query اضافه نموده است(1=1 همواره True). در این حالت پایگاه داده فرض میکند که نام کاربری یا خالی است (‘’) یا True میباشد. با این دستور کلیه کاربران از پایگاه داده استخراج خواهند شد.
ممکن است نام کاربری مدیر یا ادمین نیز در ابتدای لیست استخراج شده باشد.
Select * from users where name = ‘’ or 1=1;–‘;
Getting Database Structure
برای ادامه مراحل SQL Injection شما باید بدانید که پایگاههای داده SQL شامل دو نوع دادهای میباشند:
جداولی که توسط کاربر تعریف شده و متادیتاها
غالبا به دست آوردن اطلاعات از طریق نام اصلی جداول امکان پذیر نمیباشد، زیرا نام جداولی که توسط کاربر (طراحی و سازنده پایگاه داده) ایجاد شده است، در اختیار ما نیست. در صورتی که نام این جداولی که توسط کاربر تعریف شدهاند را ندانیم، استخراج اطلاعات دقیق از پایگاه داده کار بسیار دشواری خواهد بود.
به همین دلیل نفوذگر برای استخراج اطلاعات بیشتر از پایگاه داده باید از متادیتاها استفاده نماید. در ابتدا نفوذگر با استفاده از متادیتاها، نام پایگاه داده را استخراج نموده و در ادامه اقدام به استخراج نام جداول، نام ستونها و در نهایت دادههای درون ستونها مینماید.
همان Query پیشین را در نظر آورید، در این بخش قصد داریم تا نام پایگاه داده جاری را استخراج نماییم. برای این منظور از ساختار زیر استفاده میکنیم.
Select * from users where name = ‘test’ union select name,1,’1’,1,’1’ from master..sysdatabases;–
برای استخراج نام جداول از دستورت زیر استفاده میکنیم:
Select * from users where name = ‘test’ union select name,1,’1’,1,’1’ from [db_name]..sysobjects where xtype=’U’;–
برای استخراج نام ستونها از دستورت زیر استفاده میکنیم:
Select * from users where name = ‘test’ UNION SELECT 1,’1’,1,’1’ FROM [database_name]..syscolumns WHERE id=(SELECT id FROM [database_name]..sysobjects WHERE name=’users’)
دفاع در برابر حملات SQL Injection
یک سطح دفاعی در برابر حملات SQL Injection شامل محدود نمودن مجوزهای برنامه وب هنگام دسترسی به پایگاه داده میباشد. به این صورت که برنامه تحت وب نباید قابلیت مدیریت بر روی پایگاه داده را داشته باشد. این قابلیت فوقالعاده خطرناک میباشد.
البته لازم به ذکر است که محدود سازی مجوزها و دسترسیها، آسیبپذیری SQL Injection را حذف نخواهد کرد، ولی توانایی مهاجم را برای بررسی کامل پایگاه داده محدود مینماید.
یکی از موارد دیگر برای مقابله با این حملات استفاده از Store Procedure میباشد. این تکنیک ورودی کاربر را به پارامترهای فردی تقسیم میکند که به عنوان عناصر مجزا در پایگاه داده اجرا میشوند. از آنجا که ورودی کاربر در بین پارامترهای مختلف تقسیم میشود، حملات SQL Injection برای نفوذگر بسیار پیچیده تر میگردد.
برای آشنایی بیشتر میتوانید به لینک زیر مراجعه نمایید:
روش دیگر، محدود سازی ورودیها و کنترل آنها در سمت سرور است. شما باید عبارات خاصی مانند علامتهای ستاره، نقل قول، درصد، پرانتز و عبارتی از این دست را که امکان دارد توسط کاربر وارد شوند را محدود نمایید.
بهترین حالت این است که شما ورودیهای عددی و کاراکترهایa-z را به عنوان ورودی کاربر قبول کرده و موارد دیگر را فیلتر نمایید. البته ModSecurity شامل ویژگیهای فیلتر نمودن پارامترها برای جلوگیری از SQL Injection و XSS میباشد.
برای شناسایی یک حمله SQL Injection میتوانید لاگهای مربوط به برنامه تحت وب را به منظور شناسایی ورودیهای خاص که تا به اینجا بحث کردیم، بررسی نمایید. برخی از مواردی که باید به دنبال آنها باشید شامل union، select، insert، drop، ASCII میباشد.
استفاده از راه کار DLP که مخفف Data Loss Prevention میباشد نیز برای نظارت بر شبکه مفید خواهد بود.
برای مرحله Containment هم باید آدرس فردی که قصد انجام این حمله علیه وب سایت شما را داشته است را مسدود نمایید.
برای مرحله Eradiction و Recovery برای چنین حملاتی، هر گونه اطلاعات که توسط نفوذگر در پایگاه داده ایجاد شده است را حذف نمایید.
گروه Antifraud خود را در صورتی که در سازمان وجود داشته باشد فراخوانی نمایید تا به شما در شناسایی تلاشهای نفوذگر در حمله به پایگاه داده کمک نماید.