تزریق SQL چیست؟ Sql Injection
تزریق SQL که به اختصار ( SQLi ) نامیده میشود یک آسیب‌پذیری امنیتی وب است که به مهاجم اجازه می‌دهد در کوئری هایی که یک برنامه کاربردی در پایگاه داده خود اجرا می‌کند دخالت کند. به طور کلی به مهاجم اجازه می دهد تا داده هایی را مشاهده کند که معمولاً در حالت عادی قادر به بازیابی آنها نیست. این ممکن است شامل داده های متعلق به سایر کاربران یا هر داده دیگری باشد. در بسیاری از موارد، یک مهاجم می‌تواند این داده‌ها را تغییر داده یا حذف کند و باعث ایجاد تغییرات مداوم در محتوا یا رفتار برنامه شود.

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

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

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

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

نمونه های تزریق SQL

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

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

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

در اینجا برنامه یک کوئری SQL برای بازیابی جزئیات محصولات مربوطه از پایگاه داده ایجاد کند:

این کوئری SQL از پایگاه داده میخواهد که با شرایط زیر اطلاعات را برگرداند:

  • تمام جزئیات (*)

  • از جدول محصولات

  • که در دسته هدیه هستند

  • و مقدار انتشار آنها برابر ۱ است.

در این کوئری شرط انتشار برابر با یک است. یعنی محصولاتی که منتشر شده اند را برمی گرداند. برای محصولات منتشر نشده، معمولا مقدار انتشار را برابر صفر قرار می دهند.

در این برنامه هیچ گونه دفاعی در برابر حملات تزریق SQL وجود ندارد، بنابراین یک مهاجم می تواند حمله ای مانند زیر را انجام دهد:

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

نکته کلیدی در اینجا این است که توالی دو خط تیره — یک نشانگر کامنت در SQL است و به این معنی است که بقیه کوئری به عنوان یک کامنت تفسیر می شود و در بخشی از کوئری که بعد از کامنت نوشته شده است هیچ تاثیری در کوئری ندارد.

وجود کامنت به صورت کامل باقی کوئری را حذف می کند، بنابراین دیگر شرط منتشر شده = ۱ در کوئری در نظر گرفته نمیشود.
این بدان معنی است که همه محصولات از جمله محصولات منتشر نشده نمایش داده می شوند.

 

در ادامه، یک مهاجم می‌تواند باعث شود که برنامه همه محصولات را در تمام دسته ها نمایش دهد، از جمله دسته‌هایی که از آنها اطلاعی ندارد:

این آدرس منجر به کوئری SQL زیر می شود :

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

از کار انداختن منطق برنامه

برنامه ای را در نظر بگیرید که به کاربران امکان می دهد با نام کاربری و رمز عبور وارد شوند. اگر کاربر نام کاربری wiener و رمز عبور bluecheese را ارسال کند، برنامه با انجام  کوئری SQL  زیر اعتبار را بررسی می کند:

اگر کوئری جزئیات یک کاربر را برگرداند، ورود موفقیت آمیز است. در غیر این صورت مردود است.

در اینجا، یک مهاجم می تواند به عنوان هر کاربر بدون رمز عبور به سادگی با استفاده از کامنت در SQL  وارد شود  . به عنوان مثال، ارسال نام کاربری administrator  و یک رمز عبور خالی منجر به درخواست زیر می شود:

این کوئری کاربری را که نام کاربری آن مدیر است برمی گرداند و مهاجم را با موفقیت به عنوان کاربر مدیر وارد می کند.

بازیابی داده ها از سایر جداول پایگاه داده

در مواردی که نتایج یک کوئری SQL در پاسخ های برنامه برگردانده می شود، مهاجم می تواند از آسیب پذیری تزریق SQL برای بازیابی داده ها از جدول های  دیگر در پایگاه داده استفاده کند. این کار با استفاده از کلمه کلیدی Union انجام می شود که به شما امکان می دهد یک کوئری Select اضافی را اجرا کنید و نتایج را به کوئری اصلی اضافه کنید.

 

به عنوان مثال، اگر یک برنامه کوئری زیر را اجرا کند که در آن  کاربر عبارت “Gifts” را ارسال کند به صورت معمول لیست محصولاتی که گروه آنها برابر گیفت است بر می گردد.

مهاجم می تواند به جای نام گروه ، مقدار زیر را ارسال کند.

این باعث می شود که اپلیکیشن تمامی نام های کاربری و رمز عبور را به همراه نام و توضیحات محصولات برگرداند.

بررسی پایگاه داده

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

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

شما همچنین می توانید لیست جداول موجود در پایگاه داده بدست آورید و ببینید چه ستون هایی در آنها وجود دارد. به عنوان مثال، در اکثر پایگاه های داده می توانید کوئری زیر را برای لیست کردن جداول اجرا کنید:

آسیب‌پذیری‌های کور تزریق SQL

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

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

چگونه آسیب پذیری های تزریق SQL را شناسایی کنیم

اکثر آسیب پذیری های تزریق SQL را می توان به سرعت و با اطمینان با استفاده از اسکنر آسیب پذیری وب Burp Suite پیدا کرد.

تزریق SQL را می توان به صورت دستی با استفاده از مجموعه ای سیستماتیک از تست ها در برابر هر نقطه ورودی در برنامه شناسایی کرد. این معمولاً شامل موارد زیر است:

 

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

 

 

تزریق SQL در بخش های مختلف کوئری

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

 

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

 

  • در دستورات Update ، در مقادیر به روز شده یا شروط موجود در عبارت Where .
  • در دستورات Insert ، در مقادیر درج شده.
  • در دستورات Select ، در نام جدول یا ستون.
  • در عبارات Select ، در قسمت Order By .

تزریق SQL مرحله دوم

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

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

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

عوامل خاص پایگاه داده

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

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

  • ساختار نوشتن کوئری
  • تفاوت در نوع نوشتن کامنت
  • کوئری های دسته ای (یا انباشته شده)
  • API های مخصوص پلتفرم
  • پیغام های خطا

چگونه از تزریق SQL جلوگیری کنیم

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

کد زیر در برابر تزریق SQL آسیب پذیر است زیرا ورودی کاربر مستقیماً به کوئری متصل می شود

این کد را می توان به راحتی به گونه ای بازنویسی کرد که از مداخله ورودی کاربر با ساختار کوئری جلوگیری کند:

کوئری های پارامتری را می توان برای هر موقعیتی که ورودی نامعتبر به عنوان داده در کوئری ظاهر می شود، از جمله عبارت Where و مقادیر در یک عبارت Insert یا Update استفاده کرد.

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

منبع: سایت مهندس ایمانی باتشکر از زحمات ایشان

Favanicمشاهده نوشته ها

Avatar for favanic

گروه طراحی فاوانیک ارائه دهنده راهکارهای نوین صنعت تجارت الکترونیک می باشد

بدون دیدگاه

دیدگاهتان را بنویسید

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