در این بخش از دوره آموزشی SEC542 از موسسه SANS به آشنایی با شناسایی آسیب پذیری Cross Site Scripting و یا همان XSS آن می پردازیم.
کشف آسیب پذیری XSS
در این بخش راجع به کشف آسیب پذیری Cross Site Scripting در وباپلیکیشنها صحبت میکنیم. پیدا کردن بعضی از آنها آسان است. تنها به یک مرورگر نیاز داریم تا از طریق آن، کد JavaScript را در فیلدهای ورودی مختلف وارد کنیم. بدین ترتیب آسیبپذیریهای در دسترستر کشف میگردند.
سادهترین راه، وارد نمودن کد زیر در هر یک از فیلدهای ورودی است. بعد از ثبت و ارسال فرم، به دنبال پیام ظاهر شده بر روی صفحه (pop-up) باشید.
برای آسانتر شدن کار، باید به دنبال تزریق کد در فیلدهایی باشید که مقدار آنها به کاربر بازگشت داده شده و نشان داده میشود. اما به خاطر داشته باشید که بسیاری از ورودیهایی که اپلیکیشن میگیرد، بعدا در جاهای دیگر به کاربر نمایش داده خواهد شد.
برای مثال، فرمی را در نظر بگیرید که مخصوص ویرایش اطلاعات شخصی کاربر است. پس از ثبت اطلاعات ممکن است فرم اطلاعاتش را مستقیما به کاربر نشان ندهد بلکه این اطلاعات را ذخیره نموده و در تنظیمات پروفایل کاربر و یا در جایی که کاربران دیگر میخواهند پروفایلها را ببینند، نشان دهد. این دسته از باگها به شما اجازه میدهند به دیگران حمله کنید.
XSS و پارامترها
برای پیدا کردن آسیب پذیری Cross Site Scripting در اپلیکیشن هدف، نیاز داریم از اطلاعات جمعآوری شده در مراحل قبل استفاده کنیم. در این اطلاعات باید به همه پارامترهایی که در مراحل مختلف در صفحه استفاده شدهاند، دقت کرده و هر کدام را fuzz کنیم.
Filtering
با شناخته شدن XSS در جامعه برنامه نویسان، اپلیکیشنها به تکنیکهای فیلترینگ مجهز شدند تا خود و کاربران را در برابر حملات injection محافظت کنند. در این تکنیکها، اپلیکیشن قبل از استفاده از یک ورودی یا نمایش آن در صفحه، آن را فیلتر میکند. تکنیکهای فیلترینگ به دو دسته تقسیم میشود: whitelisting و blacklisting. روش تشخیص ورودیهای مخرب در این دو تکنیک متفاوت است. اما خوش شانسی مهاجمین در این است که با وجود اینکه اپلیکیشن کدهای مخرب را شناسایی میکند اما مهاجم نیاز دارد تنها یک راه برای بایپس فیلتر پیدا کند.
همانطور که گفتیم، دو راه برای اعتبارسنجی ورودیها وجود دارد. whitelisting و blacklisting.
whitelisting : برنامه نویس مشخص میکند چه ورودیهایی اجازه دارند در فیلد مورد نظر قرار گیرند. درواقع فیلتر براساس ورودیهای خوب شناخته شده (known goods) صورت میگیرد. این روش، روش پیشنهاد شده است.
blacklisting : برنامه نویس کاراکترهای بد و غیرمجاز شناخته شده (known bads) را شناسایی کرده و سپس یا آنها را فیلتر کرده و یا کل درخواست حاوی آن کاراکترها را بلاک میکند. معمولا این روش آسانتر بایپس میشود.
مشاهده Writeup های آسیب پذیری XSS
هر دو روش بالا، چالشهای خاص خود دارند. پیادهسازی whitelisting سختتر است چون برنامه نویس باید مشخصات و ورودیهای هر فیلد را به طور دقیق تعیین کند. برای فیلدهای تاریخ و زمان، معمولا مشکلی پیش نمیآید اما برای فیلدهایی با نوع blob و text ممکن است به مشکلاتی برخورد کنیم. علاوه بر آن، تکنیک whitelisting به دانش شناخت کاراکترهای بد احتیاج دارد و امکان این که یکی از این کاراکترها تصادفا در whitelist وارد شود، وجود ندارد.
مشکل blacklisting در آن است که هیچگاه نمیتوان به یک دانش جامع از تمام حملات رسید. مهاجمین میتوانند خلاقیتهای زیادی به خرج دهند. بنابراین حتی اگر برنامه نویس بتواند کاراکترهای بد شناخته شده را بلاک کند، باز هم کاراکترهای دیگر، انکدینگهای دیگر و اشکال دیگری از کاراکترهای غیرمجاز باقی خواهند ماند.
معمولا کارآمدترین راه حل برای جلوگیری از این دسته حملات، استفاده ترکیبی از هر دو تکنیک whitelisting و blacklisting میباشد.
بایپس فیلترها
برای بایپس فیلترهای یک اپلیکیشن تکنیکهای زیادی وجود دارد. مثلا استفاده از انکدینگهای مختلف یا توابعی مانند hex encoding یا fromCharCode. برای مثال اگر اسکریپت alert را hex encode کرده و آن را در تگ image استفاده کنیم، به پیلود زیر میرسیم:
همچنین با استفاده از تگهایی مانند IMG، DIV و style ها، میتوانیم فیلترهایی را که به دنبال تگهای SCRIPT هستند، دور بزنیم.
برگه تقلب XSS (XSS Cheat Sheet) منتشر شده توسط OWASP، از منابع عالی برای یادگیری بیشتر حملات XSS است. در بخشهای آینده خواهیم دید که بیشتر ابزارهای پیشرفته از این لیست پیلودها در حملات خود استفاده میکنند. برای دسترسی به این منبع، به لینک زیر مراجعه کنید:
www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
انواع XSS
آسیبپذیریهای XSS به سه دسته کلی تقسیم بندی میشوند: Reflected (بازتابی)، Persistent (Stored) و DOM-Based. دو دسته اول تنها مختص وباپلیکیشنهاست. دسته سوم علاوه بر وباپلیکیشن، در حملات نرمافزارهای کلاینتی نیز مورد استفاده قرار میگیرد.
حملات بازتابی XSS ساده هستند. کافیست پیلود XSS خود را در URL و یا در یک درخواست POST به صفحه آسیبپذیر ارسال کنید و ببینید که اسکریپت در بر روی صفحه بازگردانده شده و اجرا میشود. به دلیل ماهیت ساده و سریع Reflected XSS، ابزارهای اتومات به راحتی و با اطمینان این دسته از حملات را شناسایی میکنند.
Reflection اغلب در لینکها استفاده میشود. مثلا در پیامرسانها (IM messages) یا ایمیلهایی حاوی پیامی مانند “اینجا کلیک کنید تا عکسهای من را مشاهده کنید”.
Persistent XSS از صفحه پیامهای یک وبسایت (message-board) استفاده میکند تا اسکریپتهای مخرب را در مرورگر بقیه کاربران اجرا کند. این حمله معمولا در guest book ها، آگهیهای تبلیغاتی و سایر نواحی که کاربران در آن امکان ارسال اطلاعات دارند، استفاده میشود.
DOM-based زمانی اتفاق میافتد که کد سمت کلاینت به صورت ناامن از درخواست اصلی استفاده میکند.
اکسپلویت موفقیتآمیز هر یک از تکنیکها موجب میشود تا اسکریپت مهاجم به عنوان قربانی به وبسایت دسترسی یابد.
Reflected XSS
در این حملات، پیلودهای XSS در درخواست HTTP قرار گرفته و به اپلیکیشن آسیبپذیر ارسال میشوند. اپلیکیشن از پیلود استفاده کرده و بلافاصله آن را به کاربر بازتاب میدهد. بنابراین تست این دسته از XSS آسان است.
برای پیادهسازی حمله، لینک حاوی اسکریپت، با ایمیل یا از راههای دیگر به قربانی ارسال شده و با تکنیکهای مهندسی اجتماعی از او خواسته میشود بر روی لینک کلیک کند.
Persistent XSS
باگهای Persistent XSS به دلیل ذخیره شدن پیلود در اپلیکیشن ایجاد میشوند. مهاجم با یک درخواست HTTP مثلا در یک پست فروم(یا صفحه پیامها یا تنظیمات اکانت)، پیلود خود را تزریق میکند. اپلیکیشن این ورودی را پذیرفته و آن را ذخیره میکند. سپس، با مراجعه یک قربانی به صفحه حاوی پیلود، اپلیکیشن اسکریپت مخرب را به عنوان بخشی از صفحه به مرورگر کاربر برمیگرداند. این نوع از حملات بازه وسیعتری از افراد را قربانی خود میکند چرا که پیلود مخرب در معرض دید کاربران بیشتری قرار میگیرد.
DOM-Based XSS
نوع دیگری از حملات XSS که در فرآیند تست ما مفید واقع میشوند، باگهای DOM-based XSS (D-XSS) هستند. این دسته از حملات درواقع زیرمجموعهای از حملات بازتابی (Reflected) هستند. تفاوت اصلی آنها در این است که در این حملات، اپلیکیشن پیلود ما را بازتاب نمیدهد بلکه کد سمت کلاینت به گونهای نوشته شده که URL یا منابع دیگر را خوانده و در Document Object Model (DOM) از آن استفاده میکند. برای مثال اپلیکیشن ممکن است URL را بخواند و با آن یکی از فیلدهای فرم را پر کند. اگر این اتفاق سمت کلاینت بیفتد، امکان دارد اپلیکیشن نسبت به این حمله آسیبپذیر باشد.
معمولا این دسته از آسیبپذیریها در سیستمهای آنالیزگر یا mash-up یافت میشود زیرا این سیستمها اغلب از URL یا اطلاعات دیگر در توابع خود استفاده میکنند.
DOM-Based XSS Explanation
DOM-based XSS (D-XSS) واقعا یک آسیبپذیری در سرور اپلیکیشن نیست. درواقع اپلیکیشن ورودی را قبول نکرده و در پاسخ خود از آن استفاده نمیکند. دانستن این موضوع اهمیت زیادی دارد زیرا بسیاری از برنامه نویسان درک درستی از این قضیه نداشته و نمیدانند چرا با فیلتر و انکد کردن ورودیها در سرور، آسیبپذیری آنها در اپلیکیشن رفع نمیشود.
روش کار D-XSS به این صورت است که کاربر یک درخواست HTTP به سرور اپلیکیشن ارسال میکند. اگرچه معمولا این دسته از باگها در درخواستهای GET یافت میشوند، اما سورسهای زیاد دیگری نیز برای اکسپلویت وجود دارند. صفحه وب و کدهای سمت کلاینت آن میتوانند در پردازشهای خود از مقادیر موجود در URL استفاده کنند. در این حالت، مرورگر متوجه رخداد حمله نشده و کد به عنوان بخشی از صفحه اجرا میشود. به همین دلیل است که میگوییم اپلیکیشن پیلود را از سرور بازتاب نمیدهد. درواقع این مرورگر است که پیلود را در DOM اجرا میکند.
Persistent – Admin
گاهی اوقات توسعه دهندگان وب تمامی محتوای وارد شده توسط کاربران را در یک صف قرار میدهند تا مدیران سایت آنها را مرور کرده و در صورت تائید، در معرض دید عموم بگذارند. به این ترتیب تلاش میکنند تا از کاربران خود محافظت کنند. این برای مهاجمین خبر خوبی است زیرا به این معناست که در صورت پیدا کردن XSS، حتما کاربر مدیر، قربانی حمله میگردد.
مطالب این بخش توسط سرکار خانم فهیمه رضایی تهیه شده است.