مجله اینترنتی تخصصی نرم افزار

حمله SQL injection چیست؟

آسیب پذیری SQLi یا SQL injection

فهرست مطالب

زمان مطالعه: 37 دقیقه

SQLi مختصر شده عبارت SQL Injection و به معنی شیوه‌ای است که در آن، نفوذگر از ورودی‌های اعتبارسنجی نشده برنامه بهره می‌گیرد تا دستورات SQL مجاز را به یک برنامه کاربردی تحت وب (Web application) ارسال کند و توسط پایگاه داده (Database) اجرا شود.
در واقع حمله SQL injection، یک حمله پایه‌ای، برای بدست آوردن دسترسی‌های غیرمجاز به پایگاه داده یا دریافت اطلاعات به صورت مستقیم از دیتابیس می‌باشد. باید دانست که این حمله نه یک مشکل در پایگاه داده و نه مشکلی در وب سرور است، بلکه این حمله نقضی است در برنامه کاربردی.

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

چرا باید نگران حمله SQL injection باشیم؟ 

بسته به هدف و کاربرد برنامه و یا روش ارائه شده در پردازش ورودی‌های کاربر، SQL injection می‌تواند به منظور اجرایی کردن حملات زیر مورد استفاده قرار بگیرد:

  • دور زدن سیستم احراز هویت و سطح دسترسی (authentication و  authorization)
  • افشای اطلاعات
  • در معرض خطر قرار دادن یکپارچگی و در دسترس بودن سیستم (Integrity و Availability)
  • اجرا کد از راه دور (Remote Code Execution)

همانطور که مشاهده می‌کنید، در صورتی که بخواهیم فقط نمونه‌هایی از تاثیرات ممکنه پس از اجرای حمله SQL injection را بیان کنیم، می‌بینیم که با خطرناک‌ترین پیشامدها روبرو هستیم و این یکی از ویژگی‌‌های حملات تزریق می‌باشد.

مفاهیم اولیه حمله SQL injection

قبل از شروع مبحث و وارد شدن به جزئیات آن نیاز است که با بعضی از مفاهیم اولیه پایگاه داده و تزریق SQL آشنا شویم.

آشنایی با کوئری‌های SQL

زمانی که در مورد پایگاه‌های داده SQL صحبت می‌شود، کوئری را یک دستور SQL گویند. در واقع برنامه نویسان، کدهای SQL را در قالب کوئری‌ها نوشته و اجرا می‌کنند. کوئری‌های SQL قادر هستند که داده‌ها را انتخاب، بازیابی، اضافه، بروزرسانی یا ایجاد کنند ( داده‌هایی مانند رکوردهای دیتابیس‌ (پایگاه داده) یا جداول (Table).
نکاتی در مورد کوئری‌ها را در زیر مشاهده می‌نمایید:

  • معمولا کوئری‌ها شامل دستوراتی مانند SELECT، UPDATE، CREATE و DELETE (به ترتیب به معنی ایجاد، بروزرسانی، انتخاب و حذف) هستند.
  • کوئری‌ها برای برقرار کردن ارتباط بین تکنولوژی‌های سمت سرور و پایگاه داده مورد استفاده قرار می‌گیرد.
  • پارامترهای تکمیل شده در درخواست‌های کاربران، توسط کوئری‌ها برای جایگزینی در متغیرهای برنامه سمت سرور مورد استفاده قرار می‌گیرد.
  • کوئری‌ها برای واکشی کردن اطلاعات و یا انجام سایر عملیات‌ها در دیتابیس ایجاد می‌شوند.

دیاگرام زیر فرایند ایجاد و ارسال یک کوئری به دیتابیس را نشان می‌دهد. میبینیم که این کوئری توسط داده‌های ورودی کاربر شکل می‌گیرد و نتیجه آن به دیتابیس ارسال می‌شود.

حمله SQL injection

در کد آسیب پذیر بالا نکته‌ای که به وضوع مشاهده می‌شود این است که مقادیر ورودی کاربر به صورت مستقیم درون کوئری قرار می‌گیرد. این بخش معرفی کوتاهی بر کوئری‌ها بود بنابراین توضیحات تکمیلی دلیل آسیب پذیر بودن این کد را در ادامه ذکر خواهیم کرد.

آشنایی با کوئری‌های تزریق SQL یا SQL Injection Queries

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

برای مثال صفحه لاگین تولید شده توسط یک Activte Server Pages Script) ASP script) را تصور نمایید. در این صفحه اطلاعاتی که کاربر قادر به ارسال آن می‌باشد عبارت است از Username و Password. ممکن است نفوذگر فیلد های مذکور را توسط مقادیر زیر تکمیل و ارسال نماید.

Username: Something’ or 1=1 --

Password: SomethingElse

همانطور که در بخش کوئری های SQL ذکر شد، این مقادیر به عنوان Value در متغیرهای برنامه جایگزین می‌شوند. در صورتی که کوئری خام این فرم به شکل زیر باشد:

SELECT Count(*) FROM Users WHERE UserName=’UsernameInput’ And Password=’PasswordInput';

کوئری پس از جایگزینی داده‌های کاربر به شکل زیر به دیتابیس ارسال می‌شود.

SELECT Count(*) FROM Users WHERE UserName=’Something’ or 1=1 –’ And Password=’ Somethingelse';

در صورت آشنایی ابتدایی با عملگرهای منطقی در برنامه نویسی و در صورت بررسی کوئری خام، مشاهده می‌شود که این کوئری در حال شمارش تعداد رکوردها در جدول Users می‌باشد. و شرط شمارش آن این است که مقدار Username و Password برابر با ورودی‌های کاربر باشد. پس پایگاه داده در صورت درست بودن ورودی‌های کاربر ( Username و Password ) عدد یک را در پاسخ این کوئری ارسال می‌کند ( چون فقط می‌توان یک کاربر در جدول با این نام‌کاربری و رمزعبور داشت). همچنین درصورتی که این اطلاعات در جدول Users وجود نداشته باشد پایگاه‌ داده در پاسخ عدد صفر را برمی‌گرداند. و احتملا برنامه‌نویس در ادامه برنامه خود، شرطی قرار داده است که در صورت دریافت پاسخ 0، کاربر را غیرمجاز می‌داند و در صورت دریافت هر پاسخی غیر از 0 کاربر مجاز خواهد بود.

در اینجا نفوذگر به دلیل عدم فیلتر گذاری برنامه روی این ورودی ها موفق می‌شود که عبارات منطقی SQL را در متغیرها جایگزین کند تا شرط برنامه برای مجاز شمردن کاربران تغییر دهد. برای توضیح روشن‌تر ابتدا به دیاگرام زیر توجه نمایید.

دور زدن سیستم احراز هویت توسط حمله SQL injection

همانطور که در دیاگرام بالا مشاهده کردید. نفوذگر با استفاده از دو علامت خط تیره (–)، ادامه کوئری SQL را به Comment تبدیل کرد. در کدنویسی Comment به برنامه‌نویس کمک می‌کند تا توضیحاتی را در مورد سورس کد به برنامه اضافه کند. Comment ها هنگام اجرا در نظر گرفته نمی‌شوند و فقط در توسعه راحت‌تر برنامه کاربرد دارند. پس قسمت قرمز، در مرحله سوم دیاگرام بالا اجرا نخواهد شد.

تا به اینجا دیتابیس فقط قسمت سبز را اجرا خواهد کرد:

SELECT Count(*) FROM Users WHERE UserName=’Something’ or 1=1

حال نکته قابل توجه این می‌باشد که نفوذگر عملگر را از AND به OR تغییر داده. نتیجه عملگرد AND زمانی درست می‌باشد که هر دوشرط همزمان درست باشند ( در اینجا برابری همزمان Username و Password با ورودی‌های کاربر در یک ردیف از جدول Users ) ولی در عملگر OR فقط صحیح بودن یک طرف از شروط باعث درست بودن نتیجه شرط می‌شود.
کوئری نهایی تعداد ردیف های جدول Users را به شرط برابری Username با عبارت Something یا برابری عدد یک با یک، نشان خواهد داد. پس یک طرف از این شرط همیشه مبهم و طرف دیگر همیشه درست است. چرا؟ چون عدد یک همیشه با یک برابر خواهد بود. بنابراین پاسخ پایگاه داده به این کوئری هر عددی غیر از صفر می‌باشد (این همان شرط مجاز بودن کاربر در سیستم احراز هویت برنامه بود).

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

انواع آسیب پذیری SQL injection

انواع SQL injection

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

حمله SQL injection به طور کلی به سه بخش اصلی تقسیم بندی می‌شوند که هر کدام از بخش‌ها شامل انواع خاصی از حمله SQL injection هستند.

In-band SQL injection

In-band SQL injection از محبوب‌ترین و ساده‌ترین انواع SQLi یا SQL injection می‌باشد. این نوع حمله را با نام Clssic SQLi هم می‌شناسند و زمانی رخ می‌دهد که نفوذگر از کانال ارتباطی اصلی بهره گیرد تا حمله را پیاده‌سازی و نتایج را دریافت نماید. از متداول‌ترین انواع In-band ها می‌توان به Error-based SQLi و UNION-based SQLi اشاره نمود.

انواع این نوع حمله را در برگه تقلب زیر مشاهده می‌کنید:

برگه تقلب انواع In band SQL injection

  1. Error-based SQL injection

در این روش نفوذگر با ارسال Payloadهای مخرب باعث ایجاد خطاهای دیتابیسی می‌شود. نفوذگر با خواندن خطاهایی در سطح دیتابیس می‌تواند حمله SQL injection را پیاده‌سازی نماید. براساس خطاهای دریافت شده، مهاجم کوئری‌های SQL ای را ارسال می‌کند که خصوصا برای به خطر انداختن امنیت داده‌های برنامه طراحی شده است. این رویکرد برای ایجاد یک درخواست، به منظور Exploit کاملا مناسب است.

  1. UNION SQL injection

دستور UNION SELECT قادر است مجموعه داده‌های مورد نظر یا هدف را به برنامه‌نویس برگرداند. نفوذگر با استفاده از این دستور و تزریق آن در کوئری، برنامه را وادار به ارسال اطلاعات مورد نظر خود در پاسخ HTTP می‌نماید.برای مثال:

SLECET Name, Phone,  Address FROM Users WHERE id=1 UNION ALL SELECT Passwrod,1,1 FROM CreditCardTable

معمولا یک نفوذگر با اضافه کردن علامت Single quote (‘) به انتهای Query stringی مانند php?id=1  می‌تواند حدس بزند که آیا برنامه به حمله Union SQL injection آسیب پذیر هست یا که خیر.

  1. Tautology

در حملات Tautology-based SQL injection، نفوذگر با اضافه کردن شرطی همیشه درست باعث درست بودن همیشگی شرط WHERE می‌شود. فرض کنید میخواهیم میان چند رنگ، فقط رنگ آبی را انتخاب کنیم، در SQL کوئری مورد نظر، رشته‌ای مانند زیر خواهد شد:

Select ColorName FROM COLORS WHERE ColorName = ‘Blue

در کوئری بالا با دستور WHERE از دیتابیس خواستیم فقط رکوردهایی را که در جدول COLORS،مقدار ColorName آن‌ها برابر Blue است را جمع آوری کند. حال فرض کنید از برنامه خود بخواهیم زمانی یک رنگ را جمع آوری کند که عدد یک برابر یک باشد. از آنجایی که این دو عدد همیشه برابر هم هستند برنامه تمامی رنگ‌ها را انتخاب خواهد کرد.

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

Select ColorName FROM COLORS WHERE ColorName = ‘  ‘ OR ‘1’=’1’;  ’

دیتابیس مقدار وارد شده توسط نفوذگر را به شیوه زیر تحلیل خواهد کرد.

Select ColorName FROM COLORS WHERE ColorName = ‘  ‘ OR ‘1’=’1’;  ’

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

قابل ذکر است در SQL injection Authentication bypass از این روش هم برای دور زدن سیستم احراز هویت بهره گرفته می‌شود. مثالی از این مورد را در زیر مشاهده می‌نمایید.

Select * From members WHERE username = ‘admin’ OR 1=1 --‘ AND password = ‘password’
  1. End of Line Comment

در این نوع از تزریق SQL، نفوذگر با استفاده از line comments ( علائمی که ادامه خط را تا انتهای آن به Comment تبدیل می‌کنند ) و تزریق آن در کوئری اقدام به فعالیت‌های مخرب می‌نماید. برای تزریق این کامنت‌ها به کوئری معمولا از دو علامت خط تیره (–) استفاده می‌کنند که باعث می‌شود ادامه رشته توسط کوئری رد شود. نفوذگر از این قابلیت کامنت گذاری سوء استفاده می‌کند تا یک خط کد که با کامنت تمام می‌شود را تولید کند. پایگاه داده کد را تا جایی که علامت Comment قرار دارد ادامه و بقیه کوئری را نادیده می‌گیرد. برای مثال:

SELECT * FROM members WHERE username = ‘ admin -- ‘ AND  password = ‘password’

در صورت اجرای این کوئری، نفوذگر می‌تواند بدون داشتن رمزعبور وارد حساب کاربری admin شود و دلیل آن در نظر نگرفتن دستورات پس از عبارت ‘admin’ توسط پایگاه داده می‌باشد.

  1. In-line Comments

نفوذگران به راحتی می‌توانند با ادغام چند ورودی مخرب در یک کوئری واحد و تزریق in-line comments ( کامنت‌هایی که در وسط کوئری می‌توانند قرار بگیرند و فقط قسمت کامنت شده اجرا نخواهد شد. ) حمله SQL injection را پیاده‌سازی نمایند. توسط این حمله نفوذگر قادر خواهد بود که لیست سیاه برنامه را دور، فاصله‌ها را حذف و کوئری تزریق شده را مبهم نماید و دلیل آن جدا بودن دو ورودی ارسالی و پردازش جداگانه بر روی این دو ورودی می‌باشد. برای درک مطلب به مثال زیر توجه فرمایید:

INSERT INTO Users (UserName , isAdmin, Password) VALUES ( ‘”.$username.”’ ,  0 , ‘”.$password.”’)

رشته بالا کوئری‌‌ای پویا است که باعث ایجاد یک کاربر جدید توسط ورودی username و  password کاربر می‌شود. از طرفی عدد صفر ( به معنای Flase ) که مقداری برای isAdmin است، تعیین می‌کند که کاربر جدید سطح دسترسی ادمین را نخواهد داشت و این مقدار توسط کاربر قابل تنظیم نمی‌باشد. نتیجتا نفوذگر ممکن است ورودی ها را مانند زیر تکمیل نماید.

UserName = Attacker’, 1, /*

Password = */’mypwd

پس از ارسال این ورودی‌ها، مقادیر با دو متغییر “.$username.” و “.$password.” جایگزین خواهند شد و کوئری زیر تولید و حساب نفوذگر با سطح دسترسی ادمین ایجاد می‌گردد. (قسمت‌های قرمز، ورودی ارسالی توسط نفوذگر می‌باشد)

INSERT INTO Users (UserName, isAdmin,  Password) VALUES (‘Attacker’ , 1, /*’ ,  0 ,  ‘*/’mypwd’)

و دلیل آن رفتار پایگاه داده نسبت به این کوئری می‌باشد که به شکل زیر است.

INSERT INTO Users (UserName, isAdmin,  Password) VALUES (‘Attacker’ , 1, ’mypwd’)

همانطور که مشاهده می‌کنید محتویات بین /* و */ حذف شد و با این ترفند نفوذگر عدد 0 را به عدد 1 ( به معنای True ) تغییر داد و مقدار isAdmin را دستکاری کرد.

  1. Piggybacked Query

در حملات Piggybacked Query، نفوذگر با تزریق کوئری‌های مخرب اضافی به کوئری اصلی حمله SQL injection را پیاده‌سازی می‌کند. در این نوع حمله از Batched SQL query ( مجموعه‌ای از چند دستور که به همراه هم به سرور ارسال می‌شوند ) بهره گرفته می‌شود بدین شکل که کوئری اصلی بدون تغییر شکل باقی مانده و کوئری نفوذگر در کنار آن اجرا می‌شود. در این حملات که با نام Stacked queres هم شناخته می‌شوند نفوذگر با استفاده از علامت semicolon یا ; کوئری‌هایی مجزا تولید و اجرا می‌کند. نفوذگر معمولا با اهدافی همچون استخراج، افزودن، تغییر یا حذف داده، دستورات از راه دور را ارسال و یا حملات DoS را پیاده‌سازی می‌نماید.

برای مثال فرض کنید کوئری اصلی، مانند رشته زیر باشد.

SELECT * FROM EMP WHERE EMP.EID = 1001 AND EMP.ENAME = ‘Bob’

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

SELECT * FROM EMP WHERE EMP.EID = 1001 AND EMP.ENAME = ‘Bob’ ; DROP TABLE DEPT;'

پس از اجرای کوئری اول، DBMS علامت جدا کننده را تشخیص و کوئری مخرب تزریق شده را اجرا می‌نماید. نتیجتا DBMS تابع DEPT را از پایگاه داده اصطلاحا DROP ( حذف داده‌های جدول ) می‌نماید.

Blind SQL injection یا Inferential SQLi

در حملات Blind SQL injection که با نام Inferential (یا استنتاجی) هم می‌شناسند، بدلیل عدم دریافت خطا از سیستم، نفوذگر نیازمند است که زمان بیشتری را برای پیاده‌سازی این حملات صرف کند. ولی در مقابل، نفوذگر نشانه‌های دیگر از قبیل تفاوت زمان و یا تفاوت ظاهر را در پاسخ سرور مشاهده می‌نماید. مهاجم معمولا در حملات Blind SQLi از منطق‌های True یا False برای ایجاد تفاوت زمانی یا تفاوت ظاهری بهره می‌گیرد تا قادر شود اطلاعات مهم را از پایگاه داده استخراج کند. استفاده از این دو منطق بدین صورت است که مهاجم، سوالاتی را که پاسخ آن درست یا غلط است از پایگاه داده می‌پرسد تا بتواند این آسیب پذیری را کشف و درنهایت اجرا کند. همچنین از ویژگی‌های تشخیص این حمله می‌توان به عدم ارسال این اطلاعات محرمانه در پاسخ HTTP اشاره کرد و نفوذگر از روی رفتارهای سامانه قادر خواهد بود که داده ها را حدس بزند. به همین دلیل است که این حملات را Blind (نابینا) می‌نماند.

این حمله معمولا زمانی استفاده می‌شود که برنامه به SQL injection آسیب پذیر است ولی نتایج کوئری‌های تزریق شده برای نفوذگر قابل مشاهده نیست.  در واقع حمله Blind SQL injection همانند حمله SQL injection معمولی می‌باشند با این تفاوت که زمانی که نفوذگر برای Exploit این آسیب پذیری تلاش می‌کند، بجای خطایی سودمند، صفحات شخصی‌سازی شده را در پاسخ HTTP دریافت می‌کند.

تفاوت خطاهای سفارشی‌سازی شده و پیشفرض

زمانی که نفوذگری برای پیاده‌سازی یک حمله SQL injection با استفاده از کوئری‌ای مانند زیر تلاش نماید:

Something';DROP TABLE Orders--

دو نوع خطا ممکن است مشاهده شود. نوع اول خطایی پیشفرض ( سفارشی‌سازی نشده ) می‌باشد که می‌تواند به نفوذگر برای انجام حمله SQL injection کمک نماید و دلیل آن ارسال اطلاعاتی همچون نام و ورژن پایگاه داده و شرح خطای رخ داده شده به صورت دقیق و کامل می‌باشد. در صورتی که توسعه دهنده برنامه، خطای عمومی را غیرفعال نماید، نوع دوم خطا زمانی رخ خواهد داد که برنامه کاربردی خطایی شخصی‌سازی شده را نمایش دهد و این خطا برای نفوذگر سودمند نیست. در این شرایط نفوذگر انتخابی دیگر جز Blind SQL injection ندارد.

در ادامه با انواع حملات Blind SQL injection آشنا می‌شویم.

تفاوت blind SQL injection با SQL injection معمولی

  1. Time-based SQL injection ( انتظار برای تاخیر )

در حمله Time-based SQL injection( که با نام Time delay SQL Injection هم شناخته می‌شود )، نفوذگر تاخیر زمانی رخ داده شده در پاسخ HTTP را با توجه به درخواست‌های Ture و False خود، مورد ارزیابی قرار می‌دهد. دستور WAITFOR مانع ارسال پاسخ به مدت معین شده در پایگاه داده می‌شود. نفوذگر با ایجاد یک شرط از برنامه می‌خواهد که در صورت درست بودن کوئری ارسال شده تاخیر کوتاهی در ارسال پاسخ ایجاد نماید. بنابراین مهاجم قادر است با ارسال کوئری‌های متعدد از درست یا غلط بودن آن‌ها مطلع شود. همانطور که در مثال تصویر مشاهده می‌کنید نفوذگر می‌تواند وجود یا عدم وجود رکورد در جدول CreditCard را با توجه به تاخیر بررسی نماید.

حمله Time-based SQL injection

  1. Boolean-based SQL injection

boolean-based SQL injection

کشف آسیب پذیری Boolean-based SQL injection، که گاهی با نام Inferential SQL injection هم یاد می‌شود، از طریق ارسال درخواستی‌های با Syntax صحیح به پایگاه داده برنامه انجام می‌شود. نفوذگر در ابتدا چندین دستور و کوئری معتبر را ارسال می‌کند و سپس با توجه به آگاهی از درست یا غلط بودن آن‌ها، پاسخ‌ها را ارزیابی می‌نماید. با مقایسه صفحه‌های پاسخ و شروط و همچنین آگاهی نفوذگر از درست یا نادرست بودن کوئری، مهاجم قادر است متوجه شود که آیا حمله موفقیت آمیز بوده یا خیر.

برای مثال فرض کنید آدرس زیر مربوط به نمایش جزئیات ایتمی در یک فروشگاه می‌باشد:

http://www.example.com/item.aspx?id=67

و کوئری مربوط به درخواست بالا مانند زیر باشد:

SELECT Name, Price, Description FROM ITEM_DATA WHERE  ITEM_ID = 67

نفوذگر ممکن است آدرس زیر را از برنامه درخواست نماید:

http://www.example.com/item.aspx?id=67 and 1=2

و کوئری مربوطه به شکل تغییر پیدا کند:

SELECT Name, Price, Description FROM ITEM_DATA WHERE  ITEM_ID = 67 AND 1=2

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

http://www.example.com/item.aspx?id=67 and 1=1

و کوئری مربوطه به شکل زیر تغییر پیدا می‌کند:

SELECT Name, Price, Description FROM ITEM_DATA WHERE  ITEM_ID = 67 AND 1=1

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

  1. Heavy query

در برخی شرایط، استفاده از توابع اضافه کردن تاخیر در کوئری غیرممکن است. زیرا احتمال دارد ادمین کل، این قابلیت را غیرفعال کرده باشد. در چنین مواقعی نفوذگر می‌تواند از Heavy query، برای انجام حملات Time-based SQL injection بهره گیرد. یک Heavy query ( کوئری سنگین )، داده‌های زیادی را از پایگاه داده درخواست می‌کند که این امر باعث ایجاد تاخیر در اجرای کوئری می‌شود. مهاجمان با ایجاد چندین پیوست از جداول سیستم، کوئری سنگینی ایجاد می‌کنند. دلیل استفاده از این جداول، طولانی‌تر بودن زمان مورد نیاز برای جمع آوری این جداول است.

برای مثال رشته زیر کوئری‌ای سنگین در Oracle می‌باشد که زمان زیادی برای اجرا نیاز دارد.

SELECT count(*) FROM all_users A, all_users B, all_users C

در صورتی که نفوذگر پارامتری مخرب را به Payload تزریق کند قادر خواهد بود، درخواست خود را بدون استفاده از توابع اضافه کردن تاخیر به حمله Time-based SQL injection تبدیل کند. برای مثال:

1 and 1 < SELECT count(*) FROM all_users A, all_users B, all_users C

نتیجه کوئری نهایی مانند زیر خواهد شد:

SELECT * FROM products WHERE id=1 AND 1 < SELECT count(*) FROM all_users A, all_users B, all_users C

در اینجا نفوذگر با اضافه کردن شرطی همیشه درست (تعداد رکوردهای این جداول از عدد یک خیلی بزرگ‌تر خواهد بود) باعث ایجاد تاخیر زیادی در کوئری‌هایی که پاسخ آن صحیح است می‌شود.

Out-of-band SQL injection

در این نوع حملات مهاجمان از کانال‌های ارتباطی متفاوتی (مانند عملکرد ارسال ایمیل در پایگاه‌‌داده و یا توابع Write و Load در فایل‌ها) برای پیاده‌سازی حمله و استخراج نتایج بهره می‌گیرند. انجام این نوع حملات بدلیل اهمیت ارتباط نفوذگر و بدست آوردن قابلیت‌های پایگاه داده که برنامه کاربردی از آن استفاده می‌کند، دشوار است. این در واقع یکی از دلایلی می‌باشد که این نوع حملات زیاد متداول نیستند.
با این روش نفوذگر یک راه جایگزین بجای حملات استنتاجی برای خود کشف می‌کند. این روش یک جایگزین مناسب برای حملات Blind می‌باشد زیرا در بسیاری از مواقع، پاسخ‌های سرور خیلی پایدار ( Stable ) نیستند به عنوان مثال، تفاوت زمانی ناشی از ارسال Query های مخرب می‌‌تواند به دلیل حجم ترافیک وارده به سرور باشد و این موضوع تفاوت زمانی‌ها را غیر قابل اعتماد می‌نماید.

تکنیک‌های Out-of-band SQL Injection به توانایی‌ ایجاد درخواست‌های HTTP یا DNS توسط پایگاه داده سرور، وابسته است. به عنوان مثال این امر در مورد دستور xp_dirtree در Microsoft SQL Server صادق است و در صورت سوء استفاده از این دستور، نفوذگر قادر به ارسال درخواست‌های DNS به سرورهای شخصی خود خواهد بود.

ابزارهای شناسایی و پیاده‌سازی حمله SQL injection

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

ابزارهای شناسایی و پیاده‌سازی حمله SQL injection بر بستر کامپیوتر

SQLmap

منبع : SQLmap

ابزار SQLmap، ابزاری متن باز با هدف انجام تست‌های نفوذ برای حمله SQL injection می‌باشد. SQLmap قادر است پروسه‌های تشخیص و اکسپلویت حمله SQL injection را خودکارسازی نماید و پایگاه داده سرور را بدست بگیرد. به کمک این ابزار و موتور تشخیص قدرتمندش، امکانات زیادی برای انجام تست نفوذهای حرفه‌ای خواهیم داشت. تشخیص پایگاه‌داده مورد استفاده، واکشی داده از دیتابیس، دسترسی به فایل‌های حیاتی سیستم و اجرای دستور سیستم عاملی از طریق اتصالات Out-of-band، با استفاده از طیف گسترده‌ای از سویچ‌ها، از امکانات این ابزار می‌باشد.

نفوذگران بوسیله SQLmap قادرند که انجام حمله SQL injection را با شیوه‌های متفاوتی مانند Boolean-based Blind، Time-based Blind، Error-based، UNION query based پیاده‌سازی کنند.

SQLmap چیست

برخی از قابلیت‌های این ابزار را در زیر مشاهده می‌نمایید.

  • پشتیبانی کامل از شش تکنیک‌ حمله SQL injection یعنی Boolean-based Blind، Time-based Blind، Error-based، UNION query based، stacked Query و تزریق Out-of-band
  • پشتیبانی از اتصال مستقیم به پایگاه داده بدون نیاز به تزریق SQL و با استفاده از تعریف اطلاعات احراز هویت DBMS، آدرس IP، پورت و نام پایگاه داده
  • پشتیبانی از جمع‌آوری نام‌های کاربری، پسوردهای هش شده، privilege ها، نقش‌ها، پایگاه‌های داده، جداول و ستون‌ها
  • شناسایی و تشخیص رمزعبورهای هش شده و توانایی کرک آن‌ها با استفاده از یک Dictionary-list.
  • پشتیبانی از جستجو برای پایگاه داده، جداول و یا ستون‌ها با نام‌های خاص در سراسر دیتابیس
  • پشتیبانی از اتصال Out-of-band با استفاده از پرتکل TCP میان ماشین مهاجم و پایگاه داده
  • پشتیبانی از تخلیه (Dump) پایگاه داده به طور کامل، یا با استفاده از تعیین محدوده یا مقادیر ثابت، بسته به انتخاب مهاجم

Mole

منبع: sourceforge

ابزار mole

Mole ابزاری برای خودکارسازی حملات SQL injection و در نهایت اکسپلویت آن است و برای انجام این امر فقط نیاز به ارائه آدرس یا URLای آسیب پذیر و رشته‌ای معتبر دارد. این ابزار قادر به انجام حمله SQL injection بر اساس تکنیک‌های UNION-based و Boolean-query based می‌باشد.

Mole با استفاده از یک رابط مبتنی بر دستور (Command-based ) به کاربر اجازه انجام اقدامات مورد نیاز را به راحتی می‌دهد. CLI یا Command-Line interface مورد استفاده در این ابزار، همچنین امکان تکمیل خودکار برای دستورات و آرگومان‌ها را ارائه می‌دهد تا نیاز به تایپ کردن کاربر به حداقل برسد.

برخی از امکانات این ابزار را در زیر مشاهده می‌نمایید.

  • پشتیبانی از پایگاه‌های داده MySQL، Postgres، SQL server و Oracle
  • پیاده‌سازی و انجام حملات UNION-based SQL injection
  • پیاده‌سازی و انجام حملات Blind SQL injection
  • پیاده‌سازی و انجام حمله SQL injection با استفاده از متدهای GET و POST و یا درون Cookie
  • پشتیبانی از فیلترگذاری برای دور زدن IPS/IDS
  • پیاده‌سازی و انجام حمله SQL inecjtion که داده‌ها را به صورت باینری برمی‌گرداند.

Blisqy

منبع: github

ابزار BliSQy

مهاجمان از این ابزار برای پیاده‌سازی و انجام حملات Time-based SQL injection درون هدرهای HTTP استفاده می‌کنند. این ابزار همچنین از Fuzzing برای حملات Blind SQLi پشتیبانی می‌کند. به طور معمولا نفوذگران با استفاده از این ابزار احتمال وجود آسیب پذیری را کشف و سپس با ساخت اسکریپت این آسیب پذیری را اکسپلویت می‌نمایند.

دیگر ابزارهای حمله SQL injection

برخی دیگر از ابزارهای پیاده‌سازی حملات SQL injection را در زیر مشاهده می‌نمایید.

ابزارهای شناسایی و پیاده‌سازی حمله SQL injection بر بستر تلفن‌های هوشمند

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

SQLi

منبع: Play Store

این ابزار که برای ساخت کوئری‌های مخرب طراحی شده است با تزریق در ورودی‌های اعتبارسنجی نشده قادر به اکسپلویت آسیب پذیری SQL injection می‌باشد.

SQLi اندروید

Droid SQLi spyder

منبع: Play Store

ابزار Droid SQLi spyder یک موتور پویشگر آسیب پذیری می‌باشد که برای کشف و اکسپلویت انواع حملات مانند Blind sql injection، Cross-site Scripting (XSS)، Information disclosure، remote File include، Shell injection و … مورد استفاده قرار می‌گیرد.

ابزار Droid SQLi spyder

SQLMapChik

منبع: Github

SQLMapChik ابزاری Cross-platform و نسخه‌ای گرافیکی از SQLmap می‌باشد که برای اولین بار نسخه موبایلی آن طراحی شد.

ابزار SQLmap Chik

شیوه‌های گریز (Bypass)

فایروال‌ها و IDSها (Intrusion detection sytems) توانایی تشخیص حمله SQL injection را براساس امضاهای (Signatures) از پیش تعیین شده دارند. ولی حتی در صورتی که شبکه شامل این موارد شود، نفوذگران همواره قادر هستند با استفاده از تکنیک‌های گریز، پیاده‌سازی حمله SQL injection را بدون اینکه فایروال‌ها و IDSها تشخیص دهند، اجرا نمایند. مثالی از این گریزها را می‌توان Hex encoding، دستکاری فواصل، افزودن In-line comment، استفاده از همتاهای مصنوعی، Char encoding تعریف نمود. در این بخش به این شیوه‌های گریز به صورت دقیق پرداخته می‌شود.

گریز از IDSها:

IDSها برای تشخیص فعالیت‌های مخرب در شبکات قرار داده می‌شوند. تعیین فعالیت‌های مخرب معمولا به دو صورت یعنی امضا یا مدل‌های ناهنجاری انجام می‌گیرد. برای تشخیص دستورات مخرب و حمله SQL injection معمولا سنسورهای IDS در پایگاه‌های داده سرور قرار می‌گیرد. مهاجمان با استفاده از تکنیک‌های گریز، رشته‌های ورودی را مبهم ساخته تا IDSهای مبتنی بر امضا قادر به تشخیص حمله نباشند. امضاها در واقع یک Regex یا Regular Expression هستند که الگوی رشته‌هایی از حملات ناشناس را تعریف می‌کنند. IDSها پایگاه داده‌ای از مجموعه امضاها را شامل می‌شوند تا با مقایسه آن با رشته‌های ورودی مهاجمان، قادر به تشخیص حملات شوند. در صورتی که رشته ورودی با هر کدام از امضاها متطابق باشد، IDS اقدامات لازمه را انجام و اجازه پیاده‌سازی حمله را نمی‌دهد. بنابراین نفوذگر باید در برابر سامانه‌های شامل IDS مبتنی بر امضا بسیار برنامه ریزی شده عمل کند تا بتواند رشته خود را طوری بنویسد که منطبق با امضاها نباشد.

1. تکنیک گریز In-line Comment

در این روش، نفوذگر با استفاده از In-line comment، رشته تزریق شده را مبهم سازی می‌نماید. In-line comment ها قادرند دستوراتی را بسازند که معتبرند ولی اجرا پذیر نیستند و از طرفی به مهاجم اجازه تزریق SQL بدون استفاده از فواصل را می‌دهد. نفوذگران با استفاده از افزودن آن‌ها قادرند برخی از فیلترهارا دور بزنند.

برای مثال /* … */ ، اجازه افزودن commentهای چند خطی را می‌دهد.

‘/**/UNION/**/SELECT/**/password/**/FROM/**/Users/**/username/**/LIKE/**/’admin’—

همچنین شما می‌توانید از in-line comments داخل دستورات SQL بهره بگیرید.

‘/**/UN/**/ION/**/SEL/**/ECT/**/password/**/FR/**/OM/**/Users/**/WHE/**/RE/**/ username/**/ LIKE/**/’admin’—

2. تکنیک گریز char encoding

نفوذگر قادر است با استفاده از تابع ()Char، رشته ارسالی خود که شامل عبارات متداول حمله SQL injection می‌باشد را رمزگذاری نماید تا رشته ارسالی مطابقتی با هیچ یک از امضاهای پایگاه داده IDS نداشته باشد. تابع ()Char مقادیر hexdecimal و decimal را به کارکترهایی که به راحتی قادرند از موتور SQL گذر کنند، تبدیل نماید. همچنین قابل ذکر است که شما می‌توانید از این تابع در پایگاه داده MySQL بدون استفاده از Double quotes بهره بگیرید.

برای مثال:

بارگذاری فایل با استفاده از UNION ( رشته: /etc/passwd )

‘ union select 1, (Load_file(char(47,101,116,99,47,112,97,115,97,115,119,100))),1,1,1;

تزریق بدون استفاده از Quotes ( رشته: % )

‘ or username like char(37);

تزریق بدون استفاده از Quotes ( رشته: root )

‘ union select * from users where login = char(114,111,111,116);

بررسی وجود یک فایل ( رشته: e.ext )

‘ and 1= if((load_file(char(110,46,101,120,116))<>char(39,39),1,0));

3. تکنیک گریز بهم پیوستن رشته‌ها(String Concatenation)

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

در این روش اعتبار سنجی رشته بر اساس امضاها بی فایده است چون هر طرف از علامت مساوی به صورت جداگانه بررسی خواهد شد.

در پایگاه داده SQL server شما می‌توانید با استفاده از علامت + دو رشته مجزا را بهم متصل کنید تا یک رشته واحد داشته باشید ( در پایگاه داده Oracle علامت || برای Concatenation مورد استفاده قرار می‌گیرد).

برا مثال:

“ or ‘Simple’ = ‘sim’ + ‘ple’

دستورالعمل‌های پیوستن برای جلوگیری از تشخیص امضا، با استفاده از دستورات Execution که به شما امکان می‌دهد رشته‌ها را در سرور پایگاه‌داده به هم متصل کنید را در زیر مشاهده می‌نمایید:

Oracle: ‘; EXECUTE IMMEDIATE ‘SEL’ || ‘ECT US’ || ‘ER’

MSSQL: EXEC (‘DRO’ + ‘P T’ + ‘AB’ + ’LE’ )

همچنین شما می‌توانید با استفاده از دستورات SQL عمل Concatenation را انجام دهید.

MySQL: ‘; EXECUTE CONCAT(‘INSE’,’RT US’,’ER’)

4. تکنیک گریز مبهم سازی کد

به صورت کلی دو روش وجود دارد که نفوذگر با استفاده از آن‌ها قادر به مبهم سازی دستورات SQL است تا بتواند از تشخیص IDS جلوگیری نماید.

  • Wrapping: مهاجمان قادرند با استفاده ازwrap ( محیطی مبتنی بر Command-line که قادر به مبهم سازی اسکریپت های SQL که قابلیت اجرا خواهند داشت، است )ها کوئری‌های SQL خود را مبهم سازی و سپس به پایگاه داده ارسال نمایند. در ادامه امضاهای IDS توانایی تشخیص کوئری مبهم سازی شده را نداشته و اجازه خواهد داد تا کوئری به پایگاه داده ارسال شود به این دلیل که کوئری ارسالی با امضاها مطابقت ندارند.
  • SQL String obfuscation: در روش SQL string obfuscation رشته های SQL با استفاده از اتصال رشته‌ها، رمزگذاری و یا تبدیل رشته به hash مبهم سازی می‌شوند و سپس هنگام اجرا رمزگشایی خواهند شد.

رشته‌هایی که به این طریق مبهم سازی شوند برای IDSها قابل تشخیص نخواهند بود ازین رو نفوذگر امضاها را bypass می‌نماید.

در ادامه شما چند مثال از مبهم سازی رشته “qwerty” را مشاهده می‌نمایید.

Reverse(concat(if(1,char(121),2),0x74,right(left(0x567210,2),1),lower(mid(‘TEST’,2,1)),replace(0x7074,‘pt’,‘w’),char(instr(123321,33)+110)))

Concat(unhex(left(crc32(31337),3)-400,unhex(ceil(atan(1)*100-2)),unhex(round(log(2)*100)-4),char(114),char(right(cot(31337),2)+54),char(pow(11,2)))

در اینجا مشاهده می‌کنید که نفوذگر تلاش می‌کند با استفاده از توابع مختلف، دستور اصلی خود را در کوئری به طول مستقیم ننوشته تا IDSها آن را تشخیص ندهند.

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

/?id=1+union+(select+1,2+from+test.users)

در این صورت امضا برنامه کاربردی ممکن است با روش‌های زیر bypass شود.

/?id=(1)unIon(selEct(1) ,mid(hash,1,32) from(test.users))

/?id=1+union+(sELect’1’,concat(login,hash) from+test.users

/?id=(1)union(((((((select(1),hex(hash)from(test.users))))))))

5. تکنیک گریز دستکاری فواصل خالی

بسیاری از موتورهای تشخیص SQL injection که مبتنی بر امضا هستند، قادر به تشخیص تعداد و یا رمزگذاری‌های فضای سفید در اطراف کد می‌باشند.

در تکنیک دستکاری فواصل، نفوذگر با استفاده از افزدون یا حذف فواصل مابین دستورات SQL، رشته‌ها یا اعداد بدون تغییر در اجرا دستورات، کوئری خود را مبهم‌ سازی می‌نماید. افزودن فاصله با استفاده از کارکتر‌های خاص مانند tab، carriage return ،Linefeed می‌تواند کوئری SQL را بدون تغییر در دستورات، غیر قابل ردیابی نماید.

برای مثال امضای UNION SELECT با UNION        SELECT متفاوت است.

همچنین در برخی از پایگاه‌های داده حذف برخی از فواصل تغییری در دستورات ایجاد نمی‌کند. برای درک بهتر به مثال زیر توجه فرمایید.

‘OR’1’=’1’

6. تکنیک گریز Hex encoding

Hex encoding روشی برای گریز که در آن از HexDesimal استفاده می‌شود تا امضاها Bypass شوند. نفوذگران با استفاده از این روش مبهم سازی کوئری مخرب خود را هنگام مطابقت با امضاها غیرقابل تشخیص می‌نماید. قابل ذکر است که اکثر IDS ها توانایی تشخیص Hex را ندارند بنابراین مهاجمان از این موضوع برای دور زدن فیلتراسیون اعمال شده بر ورودی‌ها بهره می‌گیرد تا رشته تزریقی خود را مبهم سازی نماید.

برای مثال رشته SELECT می‌تواند توسط اعداد HexDesimal به صورت 0x73656c656374 نوشته شود که معمولا توسط IDS های مبتنی بر امضا قابل شناسایی نمی‌باشد.

; declare @x varchar(80);

Set @x = x73656c656374

20404076657273696f6e;

EXEC (@x)

در ادامه مثال‌هایی از رشته‌ها را همراه معادل HexDesimal آن مشاهده می‌نمایید.

SELECT @@version => 0x73656c656374204 04076657273696f6

DROP Table CreditCard => 0x44524f50205461626c5652043726564697443617264

INSERT into USERS (‘certifiedhacker’, ‘qwerty’) => 0x494e5345525420696e746f2055534552532028274A7 5676779426F79272C202771 7765727479274792729

7. تکنیک گریز استفاده از همتاهای مصنوعی

سیستم‌های تشخیص نفوذ معمولا از رایج‌ترین امضاهای حمله بهره می‌گیرند (مانند OR 1=1). این امضاها که معمولا توسط Regex شناسایی می‌شوند، موظفند بیشترین تعداد ممکن از معادل‌های رشته‌ای مانند OR 1=1 را در بر بگیرند. در هر صورت همتاهایی مصنوعی از این رشته‌ها وجود دارند که نفوذگر قادر است با استفاده از آن این امضاها را دور بزند. همتاهای مصنوعی، معادل‌هایی از این امضاها با کمی تغییرات می‌باشند.

مهاجمان از این همتاها به عنوان تکنیکی برای گریز بهره می‌گیرند زیرا رشته‌ای مانند OR ‘john’=’john’ اثری مانند رشته OR 1=1 را خواهد داشت. مهاجم می‌تواند در صورت عدم اجرا این پیلود با افزودن عبارت N پیش از یک رشته،‌ یکی از رشته‌ها را به unicode string تبدیل نماید (مانند OR ‘john’=N’john’). این تکنیک، روشی تاثیرگذار در IDS های مبتنی بر امضا مخصوصا در سیستم‌های پیشرفته می‌باشد.

مثالی از انواع نویسه‌های SQL injection را در ادامه مشاهده می‌نمایید.

  • ' یا استفاده از رشته‌ها (Strings)
  • # یا -- ایجاد کامنت‌های تک خطی
  • /*…*/ ایجاد کامنت‌های چند خطی
  • + علامت به اضافه، بهم پیوستن ( و فاصله در URL )
  • || (Double pipe) علامت بهم پیوستن
  • % نشانگر ویژگی Wildcard ( نشان دهنده صفر یا چند کارکتر )
  • Param1=val1&Param2=val2? پارامترهای URL
  • PRINT قابل استفاده به عنوان دستورات غیر اجرایی
  • variable@ متغییرهای محلی
  • variable@@ متغیرهای عمومی
  • 'Waitfor delay '0:0:10 وقفه زمانی

مثال‌هایی برای گریز از امضاهای  OR 1=1'

'OR 'john' = 'john'
'OR 'microsoft' = 'micro'+'soft'
'OR 'movies' = N'movies'
'OR 'software' like 'soft%'
'OR 7 > 1
'OR 'best' >'b'
'OR 'whatever' IN ('whatever')
'OR 5 BETWEEN 1 AND 7

 

 

8. تکنیک گریز URL encoding

 

URL encoding روشی است برای دور زدن ورودی‌های چند فیلتری و مبهم سازی کوئری‌های SQL که در حملات تزریق بسیار مورد استفاده قرار می‌گیرد. پیاده سازی این روش با جایگزین کردن کارکترها با معادل ASCII آن‌ها که به صورت HexDesimal است انجام می‌شود و شروع هر کارکتر با علامت درصد (%) علامت گذاری می‌شود.

 

برای مثال، کد ASCII کارکتر نقل قول تکی (') به صورت 0X27 می‌باشد که در URL-encoding به صورت 27% قابل استفاده است.

 

نفوذگر قادر است با استفاده از روش زیر فیلتر‌های ورودی را دور بزند:

فرض کنید کوئری معمولی به شکل زیر باشد:

‘ UNION SELECT Password FROM Users_Data WHERE name=’Admin’—

پس از انجام URL-encoding کوئری مذکور به شکل زیر تبدیل می‌شود.

%27%20UNION%20SELECT%20Password%20FROM%20Users_Data%20WHERE%20name%3D%27Admin%27%E2%80%94

 

در برخی از موارد URL-encoding به صورت معمولی پاسخگو نمی‌باشد و نفوذگر قادر است از Double-URL-encoding برای دور زدن فیلترها بهره بگیرد.

کارکتر نقل قول تکی (') پس انجام URL-encoding به 27% تبدیل می‌شود و همچنین پس از انجام Double-URL-encoding به 2527% تبدیل می‌شود ( در اینجا علامت درصد (%) باری دیگر URL-encode شده و به 25% تبدیل شد).

برای مثال فرض کنید کوئری معمولی به شکل زیر باشد:

‘ UNION SELECT Password FROM Users_Data WHERE name=’Admin’--

پس از انجام URL-encoding کوئری مذکور به شکل زیر تبدیل می‌شود.

%27%20UNION%20SELECT%20Password%20FROM%20Users_Data%20WHERE%20name%3D%27Admin%27%E2%80%94

و پس از انجام Double-URL-encoding، کوئری مذکور به شکل زیر تبدیل می‌شود.

%2527%2520UNION%2520SELECT%2520Password%2520FROM%2520Users_Data%2520WHERE%2520name%253D%2527Admin%2527%25E2%2580%2594

شما می‌توانید با استفاده از ابزارهای انلاین رشته‌های خود را URL-encode نمایید.

9. تکنیک گریز Null byte

نفوذگر قادر است با استفاده از یک بایت خالی یا Null byte یا %00 در رشته خود، مکانیزم تشخیص را از بین ببرد. برنامه‌های تحت وب معمولا از زبان‌های سطح بالا مانند PHP یا ASP در کنار توابعی از C یا ++C بهره می‌گیرند. در زبان‌های C یا ++C از نویسه NULL برای خاتمه یک رشته استفاده می‌شود. نفوذگر با استفاده از تفاوت رویکرد در این زبان‌ها حملات NULL injection را پیاده سازی می‌نماید.

برای مثال فرض کنید نفوذگر از کوئری زیر برای استخراج رمزهای عبور از پایگاه داده بهره می‌گیرد.

‘ UNION SELECT Password FROM Users_Data WHERE name=’Admin’--

در صورتی که سرور توسط WAF یا IDS مورد حفاظت قرار گیرد، نفوذگر قادر است کوئری خود را با بایت‌ تهی شروع نماید.

%00‘ UNION SELECT Password FROM Users_Data WHERE name=’Admin’--

با استفاده از کوئری بالا نفوذگر قادر به دور زدن IDS و بدست آوردن رمزعبور ادمین خواهد بود.

10. تکنیک گریز استفاده از حساسیت به بزرگی و کوچکی حروف (Case Variation)

Case sensitivity، اصطلاحی که در مورد رشته‌ها کاربرد دارد، در واقع خاصیت حساسیت به بزرگی یا کوچکی حروف است و اصطلاحا رشته‌ای که حساس باشد را Case sensitive و در مقابل رشته‌ای که حساس نباشد را Case insensitive می‌نامند.

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

برای مثال در صورتی که فیلترگذاری طوری طراحی شده است که کوئری‌های زیر را تشخیص دهد:

union select user_id, password from admin where user_name=’admin’--

UNION SELECT USER_ID, PASSWORD FROM ADMIN WHERE USER_NAME=’ADMIN--

آنگاه نفوذگر قادر است به راحتی فیلتر را با استفاده از کوئری زیر دور بزند:

UnIoN sEleCt UsEr_iD, PaSSwOrd fROm aDmiN wHeRe UseR_NamE=’AdMIn’--

11. تکنیک گریز تعریف و فراخوانی متغیر

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

برای مثال فرض کنید دستورات SQL مدنظر نفوذگر به شکل زیر باشد:

UNION Select password

نفوذگر متغیری جدید با نام sqlvar را حاوی دستورات SQL زیر تعریف و ارسال می‌کند:

; declare @sqlvar nvarchar(70); set @sqlvar = (N’UNI’ + N’ON’ + N’ SELECT’ + N’Password’); EXEC(@sqlvar)

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

اجرای کوئری بالا به نفوذگر اجازه دور زدن IDS و دسترسی به تمامی پسوردهای ذخیره شده در پایگاه داده می‌دهد.

12. تکنیک گریز IP fragmentation

نفوذگر قادر است با تکه تکه کردن بسته IP در قطعات ریزتر، IDS و WAF ها را دور بزند. IDS و WAF ها برای تشخیص درست حمله نیازمند به مونتاژ بسته‌ها می‌باشند ولی قادر به این کار نیستند. همچنین یافتن تطبیقی میان امضاها و رشته‌های تکه تکه شده غیرممکن است زیرا هر بسته به صورت جداگانه مورد بررسی قرار می‌گیرد.

روش‌های مختلفی برای دور زدن سیستم‌های مبتنی بر امضا با استفاده از IP fragmentation وجود دارد که در زیر مشاهده می‌نمایید.

  • ایجاد وقفه زمانی در ارسال قطعات حمله، با امید به اینکه IDS زودتر از سیستم نفوذگر خطای Time-out صادر نماید.
  • ارسال بسته‌ها به ترتیب معکوس
  • ارسال بسته‌ها به ترتیب. بجز بسته اول که باید در آخر ارسال شود.
  • ارسال بسته‌ها به ترتیب. بجز بسته آخر که باید در مرحله اول ارسال شود.
  • ارسال بسته‌ها بدون ترتیب یا به صورت تصادفی

13. تکنیک گریز تغییر

تغییر، یک تکنیک گریز است که نفوذگر به موجب آن می‌تواند به راحتی از گزاره‌های مقایسه‌ای فرار کند. مهاجم برای این کار نیاز است که از نقل قول‌ها (' یا ") در تزریق‌های اولیه‌ای مانند OR 1=1 بهره بگیرد. به عنوان مثال به صورت OR ‘1’=’1’. در این شرایط سرور SQL، کوئری را مقایسه‌ای میان دو عدد نمی‌داند بلکه مقایسه‌ای میان دو رشته تفسیر می‌کند.

نتیجه مقایسه دو رشته همانند مقایسه دو عدد می‌تواند مقداری درست داشته باشد بنابراین تغییری در نتیجه کوئری کامل نخواهد داشت. نتیجتا بسیار امضا برای تشخیص این نوع حمله نیازمندیم زیرا بی‌نهایت حالت وجود دارد که در آن نفوذگر با ایجاد تغییر در کوئری قادر است امضاهای مورد استفاده را دور بزند. هدف مهاجم داشتن یک دستور WHERE با نتیجه همیشه درست (True) می‌باشد که برای این کار هرگونه مقایسه ریاضی یا رشته‌ای قابل استفاده است.

به عنوان مثال کوئری‌های زیر مجموعه نتایج یکسان را در بر دارد.

SELECT * FROM accounts WHERE username = ‘Bob’ OR 1=1 --

SELECT * FROM accounts WHERE username = ‘Bob’ OR 2=2 --

SELECT * FROM accounts WHERE username = ‘Bob’ OR 1+1=2 --

SELECT * FROM accounts WHERE username = ‘Bob’ OR “evade” = “ev”+”ade” --

کاهش ریسک و اقدامات متقابل در برابر آسیب پذیری SQL injection

در بخش‌ قبلی با انواع روش‌های پیاده‌سازی حمله SQL injection، ابزارهای مورد استفاده برای تزریق SQL، تکنیک‌های گریز از IDS یا WAFها و موضوعاتی دیگر آشنا شدیم. در واقع بخش پیشین معرفی‌ای بر تکنیک‌های تهاجمی برای پیاده‌سازی حمله SQL injection بود. در این بخش تکنیک‌های دفاعی در برابر حمله SQL injection و اقدامات متقابل برای محافظت از برنامه کاربردی تحت وب مورد بحث قرار می‌گیرد.

کاهش ریسک و اقدامات متقابل در برابر آسیب پذیری SQL injection:

چرا برنامه‌های تحت وب به SQL injection آسیب پذیر می‌شوند؟

سرور پایگاه‌ داده دستورات سیستم عامل اجرا می‌نماید

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

استفاده از کاربر با سطح دسترسی بالا برای اتصال به پایگاه داده

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

پیام‌های خطا اطلاعات مهمی را افشا می‌نماید

در صورتی که ورودی ارسالی توسط کاربر پاسخی نداشته باشد (یا وجود نداشته باشد) و یا در صورتی که ساختار کوئری نهایی اشتباه باشد، سرور پایگاه داده پیام خطایی را نمایش می‌دهد. این پیام خطا ممکن است اطلاعات مهمی در مورد پایگاه داده افشاء کند که می‌تواند موجب ایجاد دسترسی غیرمجاز مهاجم به برخی از اطلاعات شود.

عدم اعتبارسنجی داده در سمت سرور

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

پیاده سازی استانداردهای توسعه، به حداقل رساندن سطوح دسترسی و استفاده از فایروال‌ها در سرور می‌تواند به دفاع در برابر حمله SQl injection کمک نماید.

حداقل رسانی سطوح دسترسی

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

پیاده سازی استانداردهای توسعه و برنامه نویسی

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

به عنوان مثال، سیاستی برای نحوه تعریف سطوح دسترسی را در نظر بگیرید. توسعه دهندگان معمولا از روش‌هایی دلخواه برای تعریف سطوح دسترسی به داده‌ها استفاده می‌کنند و این مجموعه بزرگی از احتمالا و انواع روش‌های تعریف سطوح دسترسی را در برمی‌گیرد که هر یک نگرانی‌های امنیتی منحصر به فردی را بوجود می‌آورد. سیاست بهتر این است که دستورالعمل‌هایی (guidelines) برای تعیین روند صحیح تولید محصول برای توسعه دهندگان تعریف شود. پیاده سازی این منطق نگهداشت پذیری و امنیت محصول را تا حد زیادی افزایش می‌بخشد.

یکی دیگر از سیاست گذاری‌های موثر در امنیت محصول این می‌باشد که اعتبارسنجی ورودی‌ها هم در سطح سرویس گیرنده (Client) و هم در سمت سرویس دهنده (Server) پیاده سازی شود. در برخی موارد توسعه دهنده برای جلوگیری از وقوع مشکل در عملکرد فقط به اعتبارسنجی در سمت سرویس گیرنده بسنده می‌کند. در واقع نباید تصور کرد که مرورگر قادر به انجام اعتبارسنجی براساس استانداردها است. تمام بررسی و اعتبارسنجی‌ها باید در سمت سرور هم انجام شود تا مطمئن باشیم هرگونه ورودی مخرب به درستی فیلتر خواهد شد.

به عنوان مثالی دیگر می‌توان به عدم نمایش خطاهای پیشفرض که معمولا عامل افشا اطلاعات محرمانه می‌باشند، اشاره نمود.

استفاده از فایروال‌ها در سرور

بهتر است پیکربندی فایروال طوری باشد که تنها مشتریان قابل اعتماد توانایی برقراری ارتباط با سرور را داشته باشند. در اکثر محیط‌های تحت وب، تنها شبکه اداری (در صورت وجود چنین شبکه‌ای) و وب سرور یا وب سرورهایی که خدمات ارائه می‌دهند باید توانایی اتصال به SQL server را داشته باشند. عموما SQL server فقط نیازمند اتصال به یک سرور پشتیبان است و در صورتی که از سرور به خوبی محافظت شود خطرات موارد زیر کاهش می‌یابد.

  • اپلود اسکریپت یا اجزای (component) غیرمجاز یا ناامن روی وب سرور
  • پچ‌های به اشتباه اعمال شده
  • خطاهای اجرایی

همچنین شما می‌توانید با دریافت مشاوره از متخصصان امنیتی ما، اقدام به ارزیابی و تست نفوذ وب سایت خود نمایید.

اقدامات متقابل در برابر SQL injection

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

بعضی از اقدامات برای دفاع در برابر حمله SQL injection در زیر لیست شده‌اند.

  • در مورد نوع، اندازه و یا محتوای ارسالی توسط کاربران و دریافتی توسط applications هیچ پیشبینی یا فرض قبلی نداشته باشید.
  • اندازه و نوع داده ورودی را آزمایش کرده و سپس محدویت‌های مناسب را اعمال کنید.
  • محتوای متغیرهای رشته‌ای را بررسی کرده و فقط مقادیر مورد انتظار را بپذیرید.
  • رد کردن ورودی‌های حاوی داده‌های باینری، علائم Escape و کارکتر‌های ایجاد Comment.
  • هرگز دستورات Transact-SQL را براساس ورودی‌های مستقیم کاربر ایجاد نکنید و از روش‌های اعتبارسنجی بر روی ورودی‌های کاربر بهره گیرید.
  • از اعتبارسنجی‌های چند لایه بهره بگیرید و هرگز ورودی‌های اعتبارسنجی نشده کاربران را به هم متصل (Concatenate) نکنید.
  • از ایجاد کوئری SQL به صورت پویا توسط اتصال ورودی‌ها اجتناب کنید.
  • اطمینان حاصل کنید که فایل Web config برای هر برنامه کاربردی حاوی اطلاعات حساس نیست.
  • از محدودترین نوع حساب‌های کاربری SQL برای برنامه کاربردی استفاده کنید.
  • از برنامه‌های تشخیص نفوذ برای شبکه، میزبان (Host) و برنامه کاربردی برای نظارت بر حملات تزریق کد بهره گیرید.
  • از آزمایشات تزریق خودکار به صورت Black box، تجزیه و تحلیل کد به صورت ایستا و تست نفوذ به صورت دستی بهره گیرید.
  • جداسازی داده‌های غیرقابل اعتماد از دستورات و کوئری‌ها
  • بجای متون خانا از الگوریتم‌های هش امن مانند SHA256 برای ذخیره‌سازی رمزهای عبور در پایگاه داده بهره گیرید.
  • از DAL یا database abstraction layer ها برای دسترسی به داده‌ها به صورت امن استفاده کنید.
  • قبل از استقرار برنامه کاربردی مطمئن شوید که پیام‌های ردیابی کد و یا اشکال زدایی (Debug) از برنامه حذف گردیده اند.
  • برنامه را طوری طراحی کنید که استثنائات را به خوبی به دام اندازد و آن‌ها را مدیریت کند.
  • کم‌ترین دسترسی‌ها را برای برنامه‌هایی که به سیستم مدیریت پایگاه داده (DBMS) دسترسی دارند تعریف کنید.
  • داده‌های کاربر و داده‌های بدست آمده از منابع نامعتبر را در سمت سرور اعتبارسنجی کنید.
  • از تایید شناسه‌های نقل شده ( داخل " " یا ' ' ) اجتناب کنید زیرا باعث پیچیدگی در لیست سیاه و سفید (blacklisting و whitelisting) و Escaping می‌شوند.
  • مطمئن شوید ورودی‌های کاربر پیش از استفاده در دستورات SQL پویا، sanitize می‌شوند.
  • از Regular expressions و  stored procedures برای تشخیص کدهای مخرب در ورودی‌ها بهره گیرید.
  • از استفاده از هرگونه برنامه کاربردی که توسط وب سرور آزمایش نشده است اجتناب کنید.
  • از داشتن چند دامنه در یک وب سرور اجتناب نمایید.
  • اطمینان حاصل کنید که تمام بروزرسانی‌های نرم افزاری به طور منظم انجام شوند.
  • دستورات SQL را از طریق برنامه‌های متصل به پایگاه داده، مانیتور نمایید تا دستورات مخرب ارسالی شناسایی شود.
  • استفاده از SQL views به منظور حفاظت از داده‌ها در جداول اصلی با محدود کردن سطح دسترسی و اعمال تغییرات، ضروری است.
  • عدم افشای خطاهای پایگاه داده به کاربر نهایی.
  • دسترسی به شل را برای پایگاه داده غیرفعال نمایید.
  • از یک API ایمن که دارای رابط پارامتری (parameterized) است یا API ای که از استفاده از مترجم (interpreter) به صورت کلی اجتناب می‌کند، بهره گیرید.
  • جریان کار احراز هویت را برون سپاری کنید. به عنوان مثال از OAUTH استفاده نمایید که به کاربران اجازه ورود توسط حساب‌های کاربری قبلی خود می‌دهد و اطلاعات ورود آنان را در مکانی مشخص ذخیره می‌کند.

استفاده از پارامترهای Type-safe در SQL

بررسی نوع و طول را با استفاده از parameter colloction انجام دهید تا ورودی‌های کاربر به عنوان یک کد واقعی در نظر گرفته نشود بلکه به عنوان یک مقدار وابسته تلقی شود. مثالی از آن را در زیر مشاهده می‌نمایید.

SqlDataAdapter myCommand = new SqlDataAdapter ("AuthLogin", conn);

myCommand. SelectCommand.CommandType = CommandType.StoredProcedure;

SqlParameter parm = myCommand. SelectCommand.Parameters.Add("@aut_id",SqlDbType.VarChar, 11);

parm.Value = Login.Text;

در این مثال پارامتر aut_id@ به عنوان مقداری وابسته تلقی می‌شود و نوع و طول آن بررسی خواهد شد. در ادامه مثالی از یک کد آسیب پذیر را مشاهده می‌کنید.

SqlDataAdapter myCommand =

new SqlDataAdapter ("LoginStoredProcedure '" + Login. Text + "'", conn) ;

نمونه از یک کدنویسی امن را درزیر مشاهده می‌نمایید:

SqlDataAdapter myCommand = new SqlDataAdapter( "SELECT aut_Iname, aut fname FROM Authors WHERE aut id = @aut_id", conn);

SQLParameter parm = myCommand.SelectCommand.Parameters.Add("@aut_id", SqlDbType. VarChar, 11);

Parm.Value = Login.Text;

 

امن سازی در مقابل SQL injection

یک سیستم باید برای دفاع در برابر حمله SQL injection، اقدامات متقابل ذکر شده در قسمت‌های قبلی را انجام دهد. از پارامتر‌های type-safe بهره گیرد؛ برای محافظت از وب سرور از WAF و IDS ها استفاده کند؛ برای بروز نگه داشتن سرور باید به صورت منظم وصله (patch)ها بروز شوند؛ sanitize و اعتبارسنجی روی ورودی‌های کاربران انجام شود؛ سورس برنامه برای حمله SQL injection بررسی شود؛ استفاده از برنامه‌های شخص ثالث به حداقل رسانیده شود؛ از Stored Procedures ها برای دریافت داده بهره گرفته شود؛ پیام‌های خطا غیرفعال و خطاها شخصی سازی شوند؛ برای جلوگیری از تزریق SQL در پایگاه داده نیاز است اتصال به پایگاه داده توسط حساب کاربری با سطح دسترسی پایین صورت گیرد و حداقل دسترسی‌ها برای پایگاه داده، جداول و ستون‌ها منظور شود؛ و دستوراتی مانند XP_cmdshell که می‌تواند روی سیستم عامل اثر گذارد، غیرفعال شود.

دفاع در برنامه کاربردی

اعتبارسنجی

راه‌های زیادی وجود دارد که از طریق آن داده‌های داده شده به برنامه کاربردی پیش از پردازش، sintize شوند. رویکرد اصلی تایید ورودی‌های کاربر توسط ساخت لیست‌های سیاه و سفید (blacklisting و whitelisting) می‌باشد. اعتبارسنجی به توسعه دهنده این امکان را می‌دهد که از تاثیرگذاری داده‌های ارائه شده توسط کاربر بر منطق برنامه جلوگیری نماید.

لیست سفید (Whitelisting)

اعتبار سنجی به صورت لیست سفید عملی است که در آن فقط موجودیت‌ (براساس نوع داده، محدوده، اندازه، مقدار و …) های از پیش تعیین شده است قابل دسترس است. اعتبار سنجی لیست سفید را positive validation و inclusion نیز می‌نامند.

معمولا این نوع اعتبارسنجی با استفاده از Regex انجام می‌شود. برای مثال کارکترهایی که شامل لیست سفید می‌توانند باشند عبارت‌اند از  \^ ، {} ، () ، @ ، | ، ?  ، $. اجرای اعتبارسنجی لیست سفید می‌تواند در برخی موارد پیچیده باشد زیرا گاهی نمی‌توان ورودی را به صورت دقیق تعیین کرد و یا ورودی شامل مجموعه‌ای بزرگ از احتمالات است.

لیست سیاه (blacklisting)

اعتبارسنجی به صورت لیست سیاه تمامی ورودی‌هایی را که برای دسترسی به داده محافظت شده تایید نشده‌اند را رد می‌کند. اجرای اعتبارسنجی لیست سیاه هم می‌تواند دارای چالش‌های بزرگی باشد زیرا باید هر محتوا و یا کارکتری که احتمالا نفوذگران در آینده از آن استفاده می‌کنند را تفسیر، درک و پیشبینی نمود. اعتبارسنجی لیست سیاه را negative validation و exclusion نیز می‌نامند.

این نوع اعتبارسنجی هم معمولا با استفاده از Regex حاوی کارکتر و رشته‌هایی که باید ممنوع شوند، پیاده‌سازی می‌شود. به عنوان مثال کارکترهایی که می‌توانند در این لیست قرار بگیرند عبارت‌اند از   ,  %  ,  --  ,  ;  ,  *\/  ,  *\\\  ,  _  ,  [\  ,  @  ,  _xp

به صورت کلی اعتبارسنجی به صورت لیست سیاه به تنهایی انجام نمی‌شود و همراه با لیست سفید صورت می‌گیرد. بهترین روش برای جلوگیری از حمله SQL injection استفاده از لیست سیاه به همراه تکنیک output encoding (توضیحات در قسمت بعد) است تا بتوان ورودی کاربر را پیش از اجرا در پایگاه داده کدگذاری و تایید کرد.

رمزگذاری خروجی (output Encoding)

رمزگذاری روی خروجی روشی است که پس از اعتبارسنجی اصلی مورد استفاده قرار می‌گیرد. این روش برای کدگذاری ورودی‌های کاربر پیش از ارسال آن به پایگاه داده انجام می‌شود تا از سالم بودن آن اطمینان حاصل شود. در برخی موارد، زمانی که SQL پویا در حال استفاده است اعتبارسنجی به روش لیست سیاه به تنهایی مفید نخواهد بود. به عنوان مثال هنگام بررسی فیلد نام، عبارت O’Henry یک عبارت معتبر است اما در صورت بهره گیری از لیست سیاه کارکتر نقل قول () مجاز نخواهد بود و این موضوع می‌تواند هنگام استفاده از کوئری SQL پویایی مانند کد زیر مشکل ساز باشد.

String myQuery= "INSERT INTO UserDetails VALUES ('" +first_name + "'+ '" + last_name + "');"

در شرایط فوق نفوذگر می‌تواند با ارسال ورودی زیر SQL تزریق نماید:

', ''); DROP TABLE UserDetails –

کوئری نهایی که در پایگاه داده اجرا خواهد شد مانند زیر خواهد بود:

INSERT INTO UserDetails VALUES ('', ''); DROP TABLE UserDetails -- ', '') ;

در SQL server از کارکتر نقل قول واحد (') برای اتمام رشته بهره گرفته می‌شود. بنابراین هنگام استفاده از دستورات SQL پویا، رمزگذاری روی کارکتر نقل قول واحد الزامی است. توسعه دهنده می‌تواند این کار را به دو طریق انجام دهد: جایگزینی کارکتر نقل قول واحد با دو نقل قول واحد (جایگزینی ' با  '') و یا جایگزینی کارکتر نقل قول واحد با بک اسلش (\) همراه نقل قول واحد (جایگزینی ' با '\ ). بدین طریق درصورتی که کاربر در رشته ارسالی خود از نقل قول بهره گیرد به عنوان یک رشته واقعی در کد مورد استفاده قرار می‌گیرد و باعث ایجاد راهی برای تزریق SQL نمی‌شود.

به عنوان مثال ما می‌توانیم در زبان برنامه نویسی جاوا از قطعه کد زیر برای جایگزینی کارکتر‌ها بهره بگیریم:

myQuery = myQuery.replace("'","\'");

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

اعمال حداقل سطوح دسترسی

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

به عنوان مثال، زمانی که برنامه فقط نیاز به دسترسی خواندن (Read) دارد، باید فقط مجور خواندن به آن اعطا شود. همچنین باید کمترین دسترسی‌ها به سیستم عامل اجرا کننده DBMS داده شود؛ نباید حساب کاربری با دسترسی Root اجرا کننده DBMS باشد.

ما با به حداقل رساندن دسترسی‌ها می‌توانیم دسترسی‌ غیرمجاز به داده‌ها را کاهش و برنامه را در برابر حمله SQL injection محافظت نماییم.

تشخیص حمله SQL injection

متخصصان امنیتی باید قوانینی در IDS توسعه و پیاده‌سازی کنند تا با استفاده از Regex حمله SQL injection تشخیص داده شود. آن‌ها باید از Regular expressions به منظور تشخیص کارکتر و یا عبارت‌های تزریق SQL بهره گیرند. کارکتر‌های مانند نقل قول واحد (')  و یا دو خط تیره (--). لیستی از Regex های مورد نیاز تشخیص حمله SQL injection را در زیر مشاهده می‌نمایید.

توضیح کارکتر
کارکتر نقل قول واحد ( ‘ ) ‘\
عملگر or |
معادل HEX کارکتر نقل قول واحد %27\
خط تیره دوتایی -\-\
شارپ یا round character #
معادل HEX کارکتر شارپ %23\
عدم حساسیت به بزرگ و کوچک i
رد کردن فواصل در الگو x
معادل HEX کارکتر مساوی ( = ) %3D\
معادل HEX کارکتر نقطه ویرگول ( ; ) %3B\
معادل HEX کارکتر o %6F\
معادل HEX کارکتر O %4F\
معادل HEX کارکتر r %72\
معادل HEX کارکتر R %52\

متخصصان امنیتی قادرند با استفاده از جستجو با روش Regex، کارکتر و یا عبارات حملات SQL injection را تشخیص دهند.

Regular expressions به منظور تشخیص حمله SQL injection

/(\’)|(\%27)|(\-\-)|(#)|(\%23) /ix

یک متخصص امنیتی باید با استفاده از Regular expressions، عباراتی همچون نقل قول واحد (') یا معادل Hex آن را در درخواست‌های دریافتی تشخیص دهند؛ آن‌ها باید بدنبال خط تیره‌های دوتایی (--) باشند؛ همچنین در بعضی از سرور‌های SQL نیاز است که کارکتر شارپ (#) تشخیص داده شود.

همچنین یک متخصص امنیتی باید با استفاده از Regex در گزارشات بدست آمده از ابزارهای کنترل امنیت مانند IDS یا WAF برای کشف حمله SQL injection جستجو نماید. متن زیر گزارش بدست آمده از یک IDS که توسط ابزار انالیز log، با نام Snort استخراج شده است، می‌باشد.

alart tip $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS(msg: “SQL Injection - Paranoid";

flow: to_server, established;

uricontent: “.pl”;pcre:”/(\’) | (\%27)|(\-\-) | (#) | (\%23) /ix”;

classtype: Web-application-attack;

sid:9099; rev:5;)

تجزیه و تحلیل گزارش مذکور به شرح زیر است.

ویژگی alert و محتوای آن (خط اول) نشان می‌دهد که Log مذکور توسط IDS، زمانی ایجاد شده که امضای یک حمله‌ در درخواست HTTP دریافتی، تشخیص داده شد. عبارت TCP به معنی استفاده از پرتکل TCP و EXTERNAL_NET به معنی خارجی بودن (خارج از رنج IP های شبکه) IP مشتری در درخواست دریافتی می‌باشد؛ عملگر <- اجازه تفکیک آدرس مبدا و مقصد را می‌دهد؛ HTTP_SERVER$ متغیری است که تعداد وب سرورهای یک سازمان را نشان می‌دهد؛ HTTP_PORTS$ نشان دهنده پورت‌های رایج مورد استفاده برای ترافیک‌های HTTP است مانند 80 یا 8080؛ :msg به پیام این Log اشاره دارد؛ ویژگی Flow جهت ترافیک را مشخص می‌کند و ویژگی established و "uricontent:".pl به ترتیب نشان دهنده هشداری، فقط در مورد اتصال TCP و محتوای URI مبتنی بر اسکریپت prel می‌باشد.

Regular expressions اصلاح شده به منظور تشخیص حمله SQL injection

/((\%3D) | (=) ) [^\n]* ((\%27) | (\')| (\-\-)| (\%3B) | (;)) /ix

متختصصان امنیتی باید با استفاده از Regex بالا، وجود یا عدم وجود کارکتر مساوی را در درخواست بررسی نمایند. همچنین عبارت *[n\^] به شامل بودن کارکترهایی غیر کارکتر n\ (خط جدید) اشاره دارد و در ادامه کارکترهای نقل قول واحد (')، خط تیره دوتایی (--) و نقطه ویرگول (;) بررسی می‌شوند

Regular expressions به منظور تشخیص حمله SQL injection معمولی (or)

/\/w*((\%27) | (‘)) ((\%6F) |o| (\%4F)) ((\%72) |r| (\%52)) /ix

متخصصان امنیتی باید با استفاده از regular expressions بالا عدم وجود یا وجود چندین کارکتر الفبایی، عددی یا خاص را که می‌تواند در حمله نقش داشته باشد، بررسی نمایند. کارکتر نقل قول واحد (') یا معادل HEX آن توسط عبارت ((') | (27%\)) بررسی می‌شود و همچنین باقی عبارت، کلمه or ( or و Or و oR و OR ) و معادل های آن را بررسی می‌نماید.

Regular expressions به منظور تشخیص حمله SQL injection با کلمه کلیدی UNION

یکی از انواع حملات SQL injection حمله UNION-based SQL injection معرفی شد که در آن کلمه کلیدی UNION مورد استفاده قرار می‌گیرد. متخصصان امنیتی باید بتوانند با استفاده از Regex این حملات را تشخیص دهند. Regex زیر برای تشخیص کوئری‌های SQL که حاوی کلمه کلیدی UNION هستند،  مورد استفاده قرار می‌گیرد.

/((\%27)|(\’))union/ix

در صورت استفاده از این عبارت، کارکتر نقل قول واحد ( ‘ ) و معادل HEX آن و سپس در ادامه کلمه کلیدی union مورد بررسی قرار می‌گیرد. متخصصان امنیتی باید با استفاده از عبارتی مشابه وجود کلماتی کلیدی دیگر مانند insert، select، delete، و drop را مورد بررسی قرار دهند تا بتوانند از حمله SQL injection جلوگیری نمایند.

Regex برای تشخیص حمله SQL injection روی MS SQL Server

در هر مرحله‌ای از حمله، اگر نفوذگر کشف کند که برنامه کاربردی به حمله SQL injection آسیب پذیر است و همچنین پایگاه داده متصل شده به وب سرور از نوع MS SQL Server است، او خواهد توانست حتی از پیچیده‌ترین کوئری‌های حاوی stored procedures ها یا extended procedures ها استفاده کند.

او تلاش خواهد کرد تا از extended procedures هایی مانند xp_cmdshell، xp_regread و xp_regwrite برای اجرای دستورات سیستم عاملی از طریق سرور SQL بهره گیرد.

/exec(\s|\+)+(s|x)p\w+/ix

متخصصان امنیتی باید با استفاده از Regex بالا کلمه کلیدی exec، فضاهای خالی (یا معادل HEX آن)، ترکیب حروف xp و sp به منظور بررسی برای extended proceduresها و stored proceduresها و در نهایت کارکترهای الفبایی، اعداد و کارکتر underscore (_) را مورد بررسی قرار دهند.

 

جمع بندی نهایی

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

 

منبع eccouncil
مطالب مشابه
8 نظر
  1. Amir می گوید

    مقاله کامل و علمی
    ممنون بابت زحماتتون

    1. شهریار شریفی می گوید

      متشکرم

  2. Nobody می گوید

    خیلی عالی بود

    1. مریم خیراندیش می گوید

      ممنون از توجه شما

  3. E می گوید

    درودبرشمامهندس جوان ،همه مطالب عالی وشفاف بودمنتظرمقالات دیگر شماهستم

    1. مریم خیراندیش می گوید

      ممنون از توجه شما

  4. mohammadali می گوید

    یکی از کاملترین و بهترین توضیحات رو دادید ، تشکر از شما

    1. مریم خیراندیش می گوید

      ممنون از توجه شما

ارسال نظر

آدرس ایمیل شما منتشر نخواهد شد.