نگاره‌هایی پیرامون امنیت، شبکه و رمزنگاری

17 آوریل 2025

سلام امیدوارم حالتون خوب باشه. من ایلیا هستم، ۲۰ سالمه و این رایتاپ، داستان اولین تجربه هانت من هستش.
در همین حینی که من درگیر یادگیری flow های authentication بودم به رایتاپ یاشار رسیدم. واقعا رایتاپ خوب و کاملی بود و هیچ نکته مبهمی باقی نمیذاشت، به شما هم پیشنهاد میکنم حتما بررسیش کنید. از محتویات رایتاپ که بگذریم، توی آخرین پاراگراف اشاره شده بود که باگ پچ شده (قاعدتا) ولی هنوز یک “علامت سوال” توی ذهن من باقی مونده بود که باعث میشد باور نکنم که این باگ پچ شده. توی این شرایط دو تا راه جلوی من بود:

  1. با توجه به اینکه تجربه زیادی نداشتم، به خودم یادآوری کنم که حتما اشخاص دیگه ای زودتر از من این به ذهنشون رسیده و بیخیال “علامت سوال” شم
  2. جواب “علامت سوال” رو پیدا کنم تا حداقل عذاب وجدان سرکوب کردن کنجکاویم باقی نمونه

موضوعات

  • جزئیات تارگت
  • فلوی SSO
  • هدف
  • فلوی DNS Rebinding
  • “علامت سوال”
  • شروع اکسپلویت

جزئیات تارگت

وبسایت Hashnode به کاربراش اجازه میده که یک وبلاگ کاملا شخصی سازی شده برای خودشون بسازن. یکی از feature هایی که این وبسایت ارائه میده, قابلیت پیاده سازی custom domain هستش؛ یعنی به عبارتی شما میتونی روی دامین متعلق به خودت و از طریق تعریف کردن یک DNS رکورد CNAME، از وبلاگ ساخته شده استفاده کنی.

سازوکاری که توسعه دهنده های hashnode برای اعتبارسنجی دامین شما در نظر گرفتن، فرستادن DNS query جهت بررسی وجود رکورد CNAME و صحت مقدار رکورد مربوطه هستش. اگر رکورد مورد نظر وجود نداشته باشه، hashnode از سرویس دادن به دامنه مربوطه خودداری میکنه.

با توجه به شرایط اعتبارسنجی که گفته شد، اگر این دامنه توسط hashnode معتبر شناخته بشه در گام بعدی چه اتفاقی میفته؟
در مرحله اول کاربر اقدام به resolve کردن دامنه مورد نظر میکنه (نتیجه DNS Query در تصویر بالا مشخصه). بعد از دریافت جواب DNS کاربر یک درخواست HTTP با مشخصات زیر ارسال میکنه

Host: hashnode.indexe.site
target IP address -> 76.76.21.21 (آیپی متعلق به سرویس هشنود)

تصویر مربوط به یک وبلاگ hashnode که در یک دامین شخصی پیاده سازی شده

فلوی SSO

وبسایت hashnode جهت سهولت استفاده از سرویس هاش، به کاربرهای خودش اجازه میده تا با حساب کاربری hashnode، توی این وبلاگ های شخصی لاگین کنند.
ولی چجوری؟

  1. کاربر اقدام به لاگین کردن در وبلاگ با دامنه شخصی میکنه (در این سناریو blog.voorivex.team )
  2. در قدم بعدی blog.voorivex.team کاربر رو با دو پارامتر next و nonce به hashnode.com ریدایرکت میکنه.
  3. تو این مرحله چندین شرط بررسی میشن:
    • آیا کاربر در hashnode.com لاگین هست؟
    • ایا پارامتر nonce معتبر هست؟
    • آیا مقدار next، یک دامین معتبر هست؟
  4. اگه تمامی شروط برقرار باشه، کاربر با یک GUID به blog.voorivex.team ریدایرکت میشه.
  5. در قدم آخر هم blog.voorivex.team با بررسی GUID، به کاربر یک JWT token میده.

هدف

تا الان درباره حالت‌هایی که مدنظر توسعه دهنده بود صحبت کردیم. در چه سناریویی ما به عنوان هکر میتونیم از این فلو سوء استفاده کنیم؟
مسیر identity/ به عنوان ورودی، از کاربر یک GUID دریافت، و در خروجی token JWT ارسال میکنه. به طور کلی، اگر بتونیم GUID یه قربانی رو به دست بیاریم، این منجر به ATO میشه. ولی چجوری میشه GUID قربانی رو به دست آورد؟

فلوی DNS Rebinding

در حالت عادی، تمامی ترافیک وبلاگ دامین ما به hashnode ارسال میشه (به دلیل وجود رکورد CNAME) و عملا کنترلی روی درخواستهایی که به backend ارسال میشه نداریم.
و اگر DNS record مربوطه رو هم تغییر بدیم تا به IP تحت کنترل خودمون اشاره بکنیم، مکانیزم اعتبارسنجی hashnode جلوی احراز هویت کاربر رو میگیره، در نتیجه هیچگونه GUID تولید نمیشه و کاربر امکان لاگین کردن در وبلاگ رو نخواهد داشت.
اگر این مکانیزم وجود نداشت و ما امکان ثبت رکورد دلخواه رو داشتیم، میتونستیم GUID که به مسیر identity/ ارسال میشه رو، دریافت کنیم.
در نتیجه راه حل ما برای بدست آوردن مقدار GUID قربانی، rebinding DNS هست. الگوهای متنوعی برای انجام rebinding DNS وجود داره. مثال:

  • سوءاستفاده از کش server DNS
  • سوءاستفاده از تعداد دفعاتی که query DNS جهت اعتبارسنجی به nameserver ارسال میشه

هر دو الگوهای بالا برای دور زدن اعتبارسنجی hashnode ناکارآمد هستن و انگار به بن بست خوردیم.

“علامت سوال”

اگه امکان متمایز کردن درخواستهایی که به nameserver ما جهت اعتبارسنجی از طرف hashnode ارسال میشه، از درخواستهایی که توسط کاربر عادی و تنها به واسطه استفاده از وبلاگ ارسال میشه رو داشته باشیم چی؟
تو این سناریوی فرضی میتونیم با فرستادن پاسخ معتبر به hashnode، اعتبارسنجی رو دور بزنیم، و با ارسال پاسخ جعلی به قربانیها، GUID اونهارو دریافت کنیم.
پیدا کردن یک تفاوت جزئی بین این دو نوع درخواست، کلید حل این مسئله هستش. به همین دلیل یه کد نوشتم که بتونم با بررسی DNS Resolver های hashnode به یک راه حل برسم.
توی مدت کوتاهی که اسکریپتم رو ران کردم به 3 تا آیپی مختلف رسیدم که همگی در یک چیز اشتراک داشتن: همشون متعلق به سرویس EC2 آمازون بودن.

شروع اکسپلویت

قبل از اینکه شروع کنیم، نیاز داریم تا به همه range IP های متعلق به EC2 دسترسی داشته باشیم.
خود وبسایت آمازون یک لیست از range IP هاش ارائه میده. AWS IP ranges
حالا که تقریبا همه شروط لازم برای اجرای حمله فراهم شده، میتونیم به مرحله بعدی بریم.
سناریویی که لازمه پیاده سازی کنیم:

کاربر لینک مخرب رو باز میکنه

  • کاربر روی لینک زیر کلیک میکنه:
  • https://hashnode.indexe.site/verify?next=https%3A%2F%2Fhashnode.indexe.site%2F
  • این لینک باعث میشه که درخواست DNS به resolver کاربر ارسال بشه. از اونجایی که resolver کاربر به EC2 مربوط نیست، nameserver ما آیپی مخرب رو ارسال میکنه.

گرفتن مقدار NONCE از Hashnode

  • درخواست کاربر رو به آیپی معتبر که متعلق به Hashnode هست میفرستیم و مقدار nonce رو از ریسپانس به کاربر برمیگردونیم.
  • کاربر بعد از دریافت Nonce به Hashnode.com هدایت میشه.

دور زدن اعتبارسنجی و دریافت GUID قربانی

  • در این مرحله، Hashnode دامنه ما رو برای اعتبارسنجی چک میکنه. چون ما کنترل DNS رو داریم و پاسخ رو بر اساس Resolver IP ارسال میکنیم، اعتبارسنجی با موفقیت انجام میشه.
  • در نهایت، کاربر همراه با GUID خودش به آیپی مخرب ما ریدایرکت میشه و ما GUID رو استخراج میکنیم.

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

1 پست نوشته شده
  • به اشتراک بگذارید:
  1. Abolfazl گفت:

    تحلیل فوق‌العاده‌ای بود! دمت گرم بابت این رایتاپ دقیق و خفن، واقعاً آموزنده بود 🙌🔥

  2. khode4li گفت:

    ایده خیلی جالبی بود دمت گرم

  3. Ayhan گفت:

    دمت گرم اقا ایلیا فوق العاده بود

  4. zori گفت:

    افرین ! کار قشنگی بود .

دیدگاه شما در مورد Abolfazl