آشنایی کامل با آسیب پذیری CSRF


5/5 - (1 امتیاز)

آسیب پذیری Cross-Site Request Forgery (CSRF) حمله ای است که کاربر را مجبور می کند تا اقدامات ناخواسته را روی یک Web Application که در حال حاضر در آن احراز هویت شده است را با کمک کمی مهندسی اجتماعی توسط مهاجم (مانند ارسال لینک از طریق Mail یا Chat) انجام دهد. یک مهاجم ممکن است کاربران یک Web Application را فریب دهد تا اقدامات مورد نظر او را اجرا کند. اگر قربانی یک کاربر عادی باشد، یک حمله موفقیت آمیز CSRF می تواند کاربر را مجبور به انجام Request های State Changing مانند انتقال وجه، تغییر آدرس Mail و … کند. اگر قربانی یک حساب کاربری مدیریتی باشد، آسیب پذیری CSRF می تواند کل Web Application را در معرض خطر قرار دهد.

 

توصیف آسیب پذیری:

CSRF حمله ای است که قربانی را فریب می دهد تا یک Request مخرب ارسال کند. برای انجام یک عملکرد نامطلوب از طرف قربانی، مهاجم هویت و Privilege های قربانی را به ارث می برد (البته توجه داشته باشید که این در مورد Login CSRF صادق نیست، شکل ویژه ای از حمله که در زیر توضیح داده شده است). برای اکثر سایت‌ ها، Request های مرورگر به طور خودکار شامل هر گونه اعتبار مرتبط با سایت، مانند Cookie و Session کاربر، آدرس IP، اعتبار دامنه ویندوز و …می‌ شود. بنابراین، اگر کاربر در حال حاضر در سایت احراز هویت شده باشد، سایت هیچ راهی برای تشخیص Request جعلی ارسال شده توسط قربانی و درخواست قانونی ارسال شده توسط قربانی را نخواهد داشت.

مهاجم می تواند از CSRF برای به دست آوردن اطلاعات خصوصی قربانی از طریق شکل خاصی از حمله، به نام Login CSRF استفاده کند. مهاجم یک کاربر که احراز هویت نشده را مجبور می کند تا به حسابی که مهاجم کنترل می کند وارد شود. اگر قربانی متوجه این موضوع نشود، ممکن است اطلاعات شخصی – مانند اطلاعات کارت اعتباری – را به حساب کاربری اضافه کند. سپس مهاجم می تواند دوباره وارد حساب کاربری شود تا این داده ها را به همراه سابقه فعالیت قربانی در Web Application مشاهده کند.

گاهی اوقات ممکن است حمله CSRF در خود سایت آسیب پذیر ذخیره شود. چنین آسیب‌ پذیری‌ هایی «Stored CSRF Flaws» نامیده می‌ شوند که می توان به سادگی با ذخیره یک تگ IMG یا IFRAME در فیلدی که HTML را می پذیرد، یا با یک حمله Cross-Site Scripting پیچیده تر انجام داد. اگر حمله بتواند یک حمله CSRF را در سایت ذخیره کند، شدت حمله بیشتر می شود. زیرا قربانی احتمال بیشتری دارد که صفحه حاوی حمله را ببیند تا برخی از صفحات تصادفی در اینترنت همچنین قربانی مطمئن است که قبلاً در سایت احراز هویت شده است.

حملات CSRF با نام‌ های دیگری نیز شناخته می‌ شوند، از جمله XSRF، “Sea Surf”، Session Riding، Cross-Site Reference Forgery و Hostile Linking. مایکروسافت از این نوع حمله به عنوان حمله با یک کلیک در Threat Modeling Process و بسیاری از مکان‌ ها در اسناد آنلاین خود یاد می‌ کند.

 

اقدامات پیشگیرانه که کارساز نیستند:

تعدادی ایده ناقص برای دفاع در برابر حملات CSRF در طول بازه های زمانی های متفاوت داده شده است. در اینجا چند مورد وجود دارد که توصیه می کنیم از آنها اجتناب کنید.

  • استفاده از یک Secret Cookie:
    به یاد داشته باشید که تمام کوکی ها، حتی Secret Cookie ها، با هر Request ارسال می شوند. تمام Authentication Token ها بدون توجه به اینکه کاربر برای ارسال Request فریب خورده است یا خیر، ارسال می شود. علاوه بر این، شناسه های Session به سادگی توسط Container برنامه استفاده می شود تا Request را با یک Session Object خاص مرتبط کند. شناسه Session تأیید نمی کند که کاربر قصد ارسال درخواست را داشته است.
  • پذیرش فقط Request های POST:
    برنامه‌ ها را می‌ توان فقط برای پذیرش Request های POST برای اجرای منطق تجاری توسعه داد. متاسفانه این منطق جهت جلوگیری از CSRF نادرست است. روش‌ های متعددی وجود دارد که در آن مهاجم می‌ تواند قربانی را فریب دهد تا یک POST Request جعلی ارسال کند، مانند یک فرم ساده که در وب‌ سایت مهاجم که با مقادیر پنهان وجود دارد. این فرم می تواند به طور خودکار توسط جاوا اسکریپت فعال شود یا توسط قربانی که فکر می کند این فرم کار دیگری انجام می دهد
  • Multi-Step Transactions:
    این مورد یک پیشگیری کافی از آسیب پذیری CSRF نیست. تا زمانی که یک مهاجم بتواند هر مرحله از Transaction تکمیل شده را پیش بینی کند، CSRF امکان پذیر است.
  • URL Rewriting:
    این روش ممکن است به عنوان یک روش مفید پیشگیری از CSRF در نظر گرفته شود زیرا مهاجم نمی تواند Session ID قربانی را حدس بزند. با این حال، Session ID کاربر در URL نمایش داده می شود. خوب منطقا ما توصیه نمی کنیم یک نقص امنیتی را با معرفی دیگری برطرف کنید !!!
  • استفاده از پروتکل HTTPS:
    HTTPS به خودی خود هیچ کاری برای دفاع در برابر CSRF نمی کند اما با این حال، HTTPS باید پیش نیازی برای قابل اعتماد بودن در نظر گرفته شود.

 

حمله چگونه کار می کند؟

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

اجازه دهید مثال زیر را در نظر بگیریم: علی می خواهد 100 دلار را با استفاده از برنامه وب bank.ir که در برابر CSRF آسیب پذیر است به محمد منتقل کند. حمید، یک مهاجم است که می خواهد علی را فریب دهد تا در عوض پول را برای حمید بفرستد. خوب این حمله شامل مراحل زیر خواهد بود:

  1. ساخت یک Exploit به صورت URL یا Script
  2. فریب محمد برای اجرای کار با مهندسی اجتماعی

سناریوی GET:

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

GET http://bank.ir/transfer.php?job=MOHAMMAD&amount=100 HTTP/1.1

حمید اکنون تصمیم می گیرد از این آسیب پذیری Web Application با استفاده از علی به عنوان قربانی سوء استفاده کند. حمید ابتدا URL Exploit زیر را می سازد که 100000 دلار از حساب علی به حساب خود منتقل می کند. حمید URL دستور اصلی را می گیرد و نام محمد را با خودش جایگزین می کند و در همان زمان مبلغ انتقال را به میزان قابل توجهی افزایش می دهد:

http://bank.ir/transfer.php?job=HAMID&amount=100000

جنبه مهندسی اجتماعی حمله، علی  را فریب می دهد تا این URL را زمانی که علی وارد برنامه بانک می شود بارگیری کند. این کار معمولا با یکی از تکنیک های زیر انجام می شود:

ارسال یک Mail با محتوای HTML
قرار دادن یک Exploit به صورت URL یا Script در صفحاتی که احتمالاً توسط قربانی بازدید می شود، در حالی که آنها همچنین در حال انجام عملیات بانکی به صورت آنلاین هستند.

Exploit URK را می‌ توان به عنوان یک لینک معمولی پنهان کرد و قربانی را فریب داد که روی آن کلیک کند:

<a href=”http://bank.ir/transfer.php?job=HAMID&amount=100000″>View my Pictures!</a>

یا به عنوان یک تصویر جعلی:

<img src=”http://bank.ir/transfer.php?job=HAMID&amount=100000″ width=”0″ height=”0″ border=”0″>

اگر این تگ تصویر در ایمیل جیاگذاری می شد، علی چیزی را نمی دید. با این حال، مرورگر همچنان درخواست را به bank.ir ارسال می کند، بدون اینکه هیچ نشانه ای مبنی بر انجام انتقال وجود داشته باشد.

 

سناریوی POST:

تنها تفاوت بین حملات GET و POST در نحوه اجرای حمله توسط قربانی است. فرض کنید بانک اکنون از POST استفاده می کند و درخواست آسیب پذیر به صورت زیر است:

POST http://bank.ir/transfer.php HTTP/1.1

job=MOHAMMAD&amount=100

چنین درخواستی را نمی توان با استفاده از تگ های استاندارد A یا IMG تحویل داد، اما می توان آن را با استفاده از تگ های FORM تحویل داد:

<form action=”http://bank.ir/transfer.php” method=”POST”>

<input type=”hidden” name=”job” value=”HAMID”/>
<input type=”hidden” name=”amount” value=”100000″/>
<input type=”submit” value=”View my pictures”/>

</form>

این فرم از کاربر می خواهد که بر روی دکمه ارسال کلیک کند، اما خوب مهاجم می تواند آن را به طور خودکار با استفاده از Java Script نیز اجرا کند:

<body onload=”document.forms[0].submit()”>

<form…

سایر HTTP Method ها:

API های کاربردی مدرن وب اغلب از روش های HTTP دیگر مانند PUT یا DELETE استفاده می کنند. بیایید فرض کنیم بانک آسیب پذیر از PUT استفاده می کند که یک بلوک JSON را به عنوان آرگومان می گیرد:

PUT http://bank.ir/transfer.php HTTP/1.1

{ “job”:”MOHAMMAD”, “amount”:100 }

چنین درخواست هایی را می توان با Java Script در یک صفحه Exploit اجرا کرد:

<script>
function put() {
var x = new XMLHttpRequest();
x.open(“PUT”,”http://bank.ir/transfer.php”,true);
x.setRequestHeader(“Content-Type”, “application/json”);
x.send(JSON.stringify({“job”:”BOB”, “amount”:100}));
}
</script>

<body onload=”put()”>

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

Access-Control-Allow-Origin: *

سناریو اختصاصی و تجربی نیوزسک با عنوان Bypass پروتکل CSRF Token:

خوب یکی از روش های حفاظتی از حمله CSRF استفاده از CSRF Token می باشد که این Token به دو شکل پیاده سازی میشود. ( در مقاله ای جدا در خصوص دفاع در مقابل آسیب پذیری CSRF صحبت خواهیم کرد )

  •  زمانی که وارد حساب کاربری خود میشوید یک Token به حساب شما تعلق میگیرد و در Request های شما ثابت هست. 
  • در هر Request ارسال شده این Token ساخته و سپس مصرف میشود.

یک Request مثل اپدیت کردن پروفایل رو انتخاب (در POST Request ما برای اپدیت کردن پروفایل یک توکن CSRF با مقدار 123 به صورت پارامتری قرار دارد) و در Burp Suite Repeater سناریو های زیر را به ترتیب تست میکنیم:

  • سناریو یک: Send Without Token

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

  • سناریو دو: Send Without value

در این سناریو کافیه مقدار Token رو حذف کنیم و پارامتر رو فقط نگه داریم.

  • سناریو سوم: Send null value

در این سناریو کافیه که مقدار پارامتر CSRF Token رو به null تغییر بدیم

  • سناریو چهارم: Send Fake Token

در این سناریو قرار هست مقدار پارامتر Token رو به یک مقدار غیر واقعی تغیر بدیم (فقط مراقب باشید که تعداد پارامتر ها یکسان باشد).

  • سناریو پنجم: ٖٖSend used Token

این مورد توی حالت دوم که هر Request یک Token دارد اتفاق می افتد و فقط کافیه از یک Token که استفاده کردیم دوباره استفاده کنیم. 

  • سناریو ششم: Send Unused Token from other req

پیروی سناریو پنجم ٫ اینبار Token رو میسازیم ولی Request رو Drop میکنیم ٫ مقدار Token رو کپی میکنیم و در Request دیگر از آن استفاده میکنیم.

  • سناریو هفتم: ٖChange Method Req

در این سناریو Request Method رو از POST فرضا به GET تغییر می دیم و ارسالش میکنیم. اگر جواب 200 بود با GET Method سناریو هارو از اول پیاده سازی میکنیم.

اگر که این Header Referer در Request های شما چک میشد آن رو به صورت کامل پاک کنید، اگر که 200 را Response گرفتید، یکی از Payload های زیر رو به اول کد Exploit خودتون اضافه کنید.

history.pushState(“”, “”, “/?victim.tld”) 

<meta name=”referrer” content=”no-referrer”>

این یکی از گزارش های CSRF ما هست که یک نکته طلایی داخلش آن وجود دارد، در وب سایت CSRF Token وجود داشت و با هیچ روشی قابل Bypass نبود، اما باگ آنجا بود که در یک Request حساس در پروفایل فراموش کرده بودند که Token رو در Request وارد کنند. پس باید تک تک Request هارو چک میکردیم، درون Request ما فقط ایمیل بود بنابراین ما میدانستیم که ایمیل کاربر را میتوانیم Exploit کنیم. 

بدون دیدگاه

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

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