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

11 ژانویه 2023

سلام دوستان امید‌وارم حالتون عالی باشه.
اسمم امینه و ۱۶ سالمه و این اولین رایتاپ از اولین باگی هستش که زدم. آسیب‌پذیری که کشف کردم CSRF از یه سایت ایرانی بود. این باگ رو گزارش ندادم چون سایت ایرانی بود و بیشتر جنبه تمرین و نزدیک‌ شدن به تارگت های واقعی رو داشت. بخاطر همین تارگت رو target.com در نظر میگیریم.

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

  • شماره همراه
  • ایمیل

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

مشخصات کوکی که سایت من رو باهاش احراز هویت میکرد به این صورت بود:

همونطور که میبینید فلگ SameSite برای یک کوکی حساس مقدار None ست شده. این یعنی کوکی که من باهاش لاگین میشدم میتونست در اختیار سایت‌های Cross Origin قرار بگیره و باهاش هر درخواستی رو بزنن.
همینجا بود که فکرم رفت سراغ CSRF.

رفتم داخل پنلم و به اطلاعاتی که میتونستم تغییر بدم توجه کردم. اطلاعاتی که میتونستم تغییر بدم یکی پسورد اکانتم، یکی ایمیل اکانتم و شماره همراه اکانتم بود:

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

اما تو بخش عوض کردن شماره فلو فرق میکرد:

تو این بخش شماره جدید رو از ما میخواست و یه کد OTP میرفت به شماره‌ای که وارد کردیم و بعد کد رو باید وارد میکردیم و اگه درست بود شماره عوض میشد.
درخواستی که بعد وارد کردن شماره میرفت به این شکل بود:

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

اکسپلویت

خب دست به کد شدم و رفتم کد اکسپلویت رو نوشتم تا ببینم همه چیز تا اینجا اوکی هست یا نه.
کد اکپسلویت به این صورت هستش:

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

خب حالا ما اینجا به یه چلنجی برمیخوریم.
ما برای عوض کردن شماره قربانی به دوتا درخواست نیاز داریم. یه درخواست برا گرفتن کد OTP و درخواست دوم برای ارسال کد OTP از طرف کاربر.
وقتی قربانی لینک رو باز میکنه درخواست ارسال میشه و کد OTP میاد به اتکر. حالا چلنجی که اینجا وجود داره اینه که ما باید این کدی که دریافت کردیم رو بدیم به همین فایل اکسپلویت و درخواست نهایی رو بزنه.
اما چجوری باید اینکارو کنیم؟
چجوری فایل اکسپلویت باید کد OTP رو بگیره و درخواست نهایی رو بزنه؟

من برای حل این مشکل اومدم اینکارو کردم.
یه دیتابیس اوردم بالا و بهش با پی اچ پی وصل شدم. وقتی کد رو از طرف قربانی دریافت میکردم، کد رو به صورت دستی وارد دیتابیس میکردم.(میتونستم یه اسکریپت هم بنویسم که اینکارو کنه ولی خب نیازی نبود)

داخل فایل پی اچی پی این کد رو نوشتم:

تو این کد وقتی به این فایل درخواست میاد میره به دیتابیس وصل میشه و بعد یه کوئری سلکت میزنه به دیتابیس و اخرین کدی که داخل دیتابیس وارد شده رو تو ریسپانس برمیگردونه.
خب حالا باید تو فایل اکسپلویت یه درخواست دوم اضافه کنیم، که درخواست میزنه به فایل پی اچ پی و کد OTP رو از دیتابیس میگیره و بعد میتونه درخواست نهایی رو بزنه.درخواست دوم میشه به این صورت:

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

حالا وقتشه ببینیم همه چیز درست کار میکنه یا نه.
با یه دیوایس دیگه وارد لینک شدم و کد OTP رو تو گوشی خودم دریافت کردم. 10 ثانیه دیلی از همین الان شروع شد. تو این 10 ثانیه کد رو دریافت کردم و وارد دیتابیس کردم.
تو درخواست بعدی فایل اکسپلویت یه گت زد به فایل پی اچ پی و کد رو گرفت و بعد اخرین درخواست رفت به سمت تارگت و شماره اکانت من تغییر کرد.

شماره اکانت قبل اکسپلویت:

شماره اکانت بعد اکسپلویت:

بعد که شماره تغییر کرد میتونستم فورگت پسورد بزنم و پسورد اکانت رو عوض کنم.

خیلی ممنون وقت گذاشتید و خوندید.
امیدوارم خوشتون اومده باشه❤️

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

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

  2. نگار گفت:

    سلام
    مرسی برای رایتاپ
    امکانش هست چند مورد رو بیشتر توضیح بدید

    ۱ – فلگ SameSite اینجا چه کاری انجام میده و چه مقادیری برای امن شدن میتونست داشته باشه ؟

    ۲ – آیا در این گزارش میشد از cross origin resource sharing هم استفاده کرد و مشخصات ناحیه کاربری مانند ایمیل و … رو دید ؟
    یعنی در پاسخی که از سایت دریافت میشد مقادیر allow به صورت * وجود داشت ؟ (برای cors)

    ۳ – پارامتر boundary در تصاویر چی هست؟ چرا در هر تصویر مقدار متفاوتی داره ؟ چطوری ایجاد میشه ؟ از طرف کی ؟
    عددی که در کد شما جلوی boundary وجود داره از کجا باید گرفته بشه ؟

    ۴ – و اینکه چطوری به جاوا اسکریپت و php این قدر تسلط دارید؟ جالبه که هر دو تا رو همزمان کد میزنید
    چه سورسی رو برای مطالعه ی این دو پیشنهاد می کنید ؟

    ممنون

    • aminsec گفت:

      سلام ممنون بابت نظرت.
      ۱. فلگ سیم سایت برای این ست میشه که کوکی ها در اختیار سایت های third party قرار نگیرن. که اینجا مقدار None ست شده بود. میتونست lax یا strict باشه.
      ۲. نه اینجا برنامه نویس CORS رو پیاده سازی نکرده بود و SOP این اجازه رو نمیداد.
      ۳. اون مربوط به هدر کانتنت تایپ میشه اونو بروزر خودش میسازه. اینجا هم از درخواست های قبلی برداشتم اوردم.
      ۴. تو امنیت از هر زبون باید تا حد مبتدی بلد باشید. اینجا هم کد های خاصی استفاده نکردم در حد مبتدی بودن.
      برا خوندن جاوا اسکریپت: javascript.info
      برا پی اچ پی: codecademy.com

  3. محب دلیر گفت:

    سلام امین جان. خیلی زیبا بود. خصوصا قسمتی که db بالا آوردی فکر خیلی خوبی بود. من با اینکه اصلا یه کلمه امنیت نمی‌دونم واقعا جالب بود برام این مقاله برام. آفرین و ممنون.

  4. kaveh گفت:

    خیلی خوب بود، درود به شما

    در مورد روند اکسپلویت، به نظرم یه مشکلی اصولا باید ایجاد می شد، اون هم ارور cors
    درسته که samesite روی none بود و کوکی ها از طرف کاربر فرستاده می شد ولی cross origin باید احتمالا مانع دریافت پاسخ در مرورگر می شد.
    چون دامنه مورد استفاده شما قطعا در whitelist سرور مقصد نیست.
    چطور شد در این مورد ارور نداد ؟

    همچنین زمانی که به آدرس url مربوط php که در اختیار شما است و برای گرفتن کد otp به اون درخواست زده می شه هم باید ارور cors در کنسول ظاهر می شد. و در نتیجه، قسمت آخر که ارسال کد otp از طرف کاربر به سایت بود با مشکل مواجه میشد.

    میشه توضیح بدی کجا رو دارم اشتباه می کنم ؟
    مگه نباید صراحتا در response دریافتی از سایت، header مربوط به access control allow origin و access control allow credentials بر روی * و true تنظیم بوده باشه تا با ارور cors مواجه نشیم ؟

    • aminsec گفت:

      سلام ممنون بابت نظرت.
      نه همه اینایی که گفتی مربوط به آسیب‌پذیری CORS هست. توی آسیب پذیری CSRF ما نیاز به جوابی که از سرور میاد نداریم.
      کد OTP هم به گوشی ارسال میشد و تو سایت صرفا یه پیام موفقیت امیز نشون میداد.

  5. تینار گفت:

    جذاب بود👌

  6. hackerone گفت:

    عالی بود
    Csrf از آسیب پذیری هایی هستش که کمتر بهش اهمیت می دن ولی خیلی جالبه

  7. احمد گفت:

    عالی بود

  8. Javad گفت:

    سلام
    عالی بود به عنوان اولین رایت آپ تون
    میگم شما چند ساله که کار میکنید ؟
    من هم تقریباً هم سن شما هستم ( کمی کمتر ) و تازه شروع کردم و الان دارم دوره security+ رو میگذرونم و چند وقت دیگه هم میرم سراغ Linux essential .
    به نظر شما روی چه چیز هایی برای یادگیری بیشتر وقت بزارم

    موفق باشید

  9. محمد گفت:

    سلام
    به عنوان اولین رایت آپ تون عالی بود
    انشاءالله که همیشه موفق باشید
    شما چند ساله که کار می کنید به طور کلی ؟
    من هم تقریباً هم سن شما هستم ( کمی کمتر ) و تازه شروع کردم
    و دارم بر این اساس پیش میرم :
    Network+ , Security+ , Linux essential , Python , CEH , PWK و بعدش متا اسپلویت
    و الان دارم Security+ رو میخونم ، به نظر شما بعد از متا اسپلویت برم و top 10 owasp بخونم ؟

  10. alireza گفت:

    عالی بود دمت گرم