سلام امیدوارم حالتون خوب باشه، تو این پست میخوام آسیبپذیری Mass Assignment که چند ماه پیش بابتش بانتی گرفتم رو باهاتون به اشتراک بذارم، امیدوارم براتون مفید باشه.
آشنایی با Mass Assignement
بعضی وقتها برنامه نویسه وب اپلیکیشن، ساختاری رو پیادهسازی میکنه که پارامتر های درخواست کلاینت داخل یک شئ (Object) یا آرایه (Array) قرار میگیرن و عملیات انجام میشه.
با یک مثل ساده این مورد رو بهتر درک میکنین، مثلا وقتی یک فرم ثبتنام رو پر میکنید سامانه میاد هر پارامتری که فرستادین رو با همون مقدار تو پایگاه داده ذخیره میکنه، در کل این کار بهینه هست و از طرفی کار برنامه نویس رو آسون میکنه و نیازی نیست هر پارامتر رو تعریف کنه.
برای درک بهتر این کد رو در نظر بگیرین:
<?php
include 'functions.php';
if ($_POST['email'] && $_POST['pass'] && $_POST['first_name'] && $_POST['last_name'] ) {
update_user( [ $_POST['email'], $_POST['pass'], $_POST['first_name'], $_POST['last_name'] ] );
}
توی این کد، برنامه نویس باید دونه دونه پارامتر ها رو اول چک کنه و بعد بده به تابع که اپدیت بشن، تو این حالت برنامه یکم static میشه و از طرفی اصولی نیست حالا اگه فردا یک پارامتر جدید به اسم address اضافه شد، دوباره باید بیاد این رو ویرایش کنه و…
خب حالا این پیاده سازی رو بررسی کنیم:
<?php
include 'functions.php';
foreach ($_POST as $post_param => $value) {
update_user($post_param, $value, $user_id)
}
اینجا هر پارامتری که توی درخواست کاربر باشه رو به تابع update_user میده که توی دیتابیس کاربر رو اپدیت کنه که اگه یک پارامتر دیگه توی دیتابیس هم تعریف شد، دیگه نیازی به تغییر کد نیست.
حالا آسیبپذیری کی بوجود میاد؟ خب متوجه شدیم هر کاربر میتونه هر پارامتری رو بفرسته و توی دیتابیس یوزر خودش رو تغییر بده، خب ممکنه پارامتری وجود داشته باشه که کاربر نباید به اون دسترسی داشته باشه، مثلا permission که سطح دسترسی کاربر رو مشخص میکنه؛ کافیه مهاجم توی درخواستی که برای ویرایش پروفایل خودش میفرسته، پارامتر permission رو برابر با ۱۰ بذاره و دسترسی خودش رو افزایش بده!
در ادامه یک نمونه واقعی این آسیبپذیری رو بررسی میکنیم.
شرح آسیبپذیری
با استفاده از این آسیبپذیری مهاجم میتونه دسترسی خودش رو از یک کاربر با سطح دسترسی مشتری به سطح دسترسی مدیریت افزایش بده و به پنل مدیریت دسترسی بگیره.
مراحل تست و کشف آسیبپذیری
من ابتدا عملیات های مختلف سایت رو بررسی کردم مثل بخش ارسال تیکت، ساختار ریست پسورد، ویرایش اطلاعات پروفایل، ویرایش عکس پروفایل و…
بعد از اینکه با Burp درخواست ها رو بررسی میکردم به چنین موردی بر خوردم که مربوط به ویرایش کردن اطلاعات پروفایل بود:
پاسخ:
یسپانس رو بررسی کردم به پارامتر user_type برخوردم، اومدم توی درخواست user_type رو تعریف کردم و معادل admin قرار دادم:
و توی پاسخ user_type من برابر با admin شد و دسترسی به پنل مدیریت گرفتم که در نتیجه دسترسی به اطلاعات چند صد هزار نفر و کلی محصول شد.
راه هایی که من استفاده میکنم برای پیدا کردن پارامتری مثل user_type:
- بررسی ریکوست هایی که سایت به API ها و.. میزنه، مثلا /api/v1/user/info/
- فاز کردن پارامتر های داخل درخواست
- بررسی کد های JavaScript
- و…
گزارش آسیبپذیری
سطح آسیبپذیری بحرانی(Crtical) بستن که بعد از ارتباط با سازمان یه جلسه تو گوگل میت برگذار شد، اونجا لایو آسیبپذیری رو تست و گزارش کردم، که همون روز باگ رو پچ کردن و ۳ تومن بانتی پرداخت کردن.
سخن پایانی
در کنار این سناریو حمله، ما سناریو های دیگه ای هم داریم، مثلا پارامتر email_verified رو در نظر بگیرید که در حالت عادی false هست، اگه تارگت آسیبپذیر باشه میتونیم به true تغییر بدیم و فرایند تایید ایمیل رو بایپس کنیم.
یا یک موردی که توی ورکشاپ SSO آقا یاشار پیادهسازی شده بود، قابلیت احراز هویت با SSO بود که برای هر شخص بصورت پیشفرض روی false تنظیم شده بود، که جلوی دسترسی به فروشگاه رو میگرفت، با این آسیبپذیری پارامتر sso_status به true تغییر کرد و میتونستیم توی بخش shop احراز هویت کنیم، که توی تارگت واقعی یکی از مزایای این مورد اینه که کلی بخش برای تست داریم 🙂
لینک های مفید
https://cheatsheetseries.owasp.org/cheatsheets/Mass_Assignment_Cheat_Sheet.html
آفرین صدرا عالی بود لذت بردم
مرسی
Good Job ✌️
nice catch!
ایول صدرا عالی بود
دمت گرم مرسی از وقتی که گذاشتی مفید بود واقعا❤?
عالی بود باریکلا ✌️
????
هم حرکتت و هم توضیحاتت عالی بود
مختصر و مفید با اشاره به جزئیات مهم
عالی و آموزنده👌🏻
بسیار عالی صدرا جان حال کردیم بسیار ساده و روان نوشتی حال کردیم باز بنویس
ایول خوب بود