محققای horizon3 یه آسیب پذیری با شناسه CVE-2023-27524 روی Apache Superset کشف و یه گزارش فنی در خصوصش منتشر کردن که در این پست بررسیش میکنیم. گزارش روی تحلیل آسیب پذیری، راه های تشخیص حملات و اصلاح متمرکزه. خوبی این گزارشات اینه که شما رو علاقمند میکنه به تحقیق رو موارد مشابه.
Apache Superset یه ابزار متن باز برای مصورسازی و کاوش روی داده ها هستش.
محققا تو تحقیقاتشون متوجه شدن که تقریبا 2000 سرور که از این ابزار استفاده میکنن، بطور پیش فرض روی یه پیکربندی غیر ایمن در حال اجرا هستن و بیشتر اونا از طریق اینترنت هم قابل دسترس هستن. به خاطر همین پیکربندی نادرست، مهاجمین میتونن با امتیاز ادمین وارد این سرور بشن ، به داده های اونا دسترسی داشته باشن، داده ها رو دستکاری کنن ، اعتبارنامه های سرورها رو جمع آوری کنن و در نهایت از راه دور کد دلخواه اجرا کنن.
بررسی آسیب پذیری :
Superset روی پایتون و فریمورک Flask توسعه داده شده. یکی از روشهای رایج در برنامه های Flask برای مدیریت وضعیت کاربر ، استفاده از کوکی های جلسه امضاء و رمزنگاری شده هستش. وقتی یه کاربری به سایت لاگین میکنه، برنامه یه کوکی جلسه (session cookie)، که شامل شناسه کاربر هستش به مروگرش می فرسته. برنامه وب، این کوکی رو با SECRET_KEY امضاء میکنه ، که یه مقدار تصادفی هستش و در یه فایل پیکربندی لوکال ذخیره میشه. مرورگر با هر درخواست وب ، این کوکی جلسه رو به برنامه وب می فرسته و برنامه قبل پردزاش درخواست با بررسی اون در هر درخواست، کاربر مجددا احرازهویت میکنه.
در حقیقت امنیت برنامه وب ، بستگی به مخفی بودن SECRET_KEY داره. اگه SECRET_KEY لو بره، مهاجم میتونه کوکی خودش بسازه و کارهایی که برای کاربر با امتیاز بالا در نظر گرفته شده رو انجام بده. یه ابزاری بنام Flask Unsign برای هک این موارد توسعه داده شده، این ابزار کامند لاینی، برای جمع آوری، دیکد کردن، بروت فورس و ساخت کوکی های جلسه برنامه های فلسک با حدس زدن SECRET_KEY توسعه داده شده.
محققا در اکتبر 2021، وقتی شروع به تحقیق روی Superset کردن، متوجه شدن که مقدار پیش فرض SECRET_KEY در زمان نصب ، مقدار زیر رو داره :
1 |
\x02\x01thisismyscretkey\x01\x02\\e\\y\\y\\h |
کاربر نهایی مسئول تغییر این مقدار به یه مقدار تصادفی، در نظر گرفته شده. محققا اومدن بررسی کنن تا ببینن چه مقدار از کاربرها، این مقدار رو تغیر دادن. برای این هدف سرورهای Superset رو روی شودان جستجو کردن. با توجه به اینکه درخواست ورود به صفحه لاگین Superset یه کوکی جلسه ایجاد میکنه، محققا این کوکی رو به برنامه flask-unsign دادن تا ببینن آیا SECRET_KEY پیش فرض بالایی براش تنظیم شده یا نه. متاسفانه متوجه شدن از 1288 مورد، 918 تاش یعنی 70 درصدش از این مقدار پیش فرض استفاده میکنه.
اکسپلویت:
اگه یه مهاجم SECRET_KEY بدونه چیکارا میتونه انجام بده؟ اگه سرور Superset پشت یه SSO قرار نگرفته باشه، مهاجم میتونه با استفاده از ابزار flask-unsign مقدار user_id یا _user_id رو به مقدار 1 تغییر بده و یه کوکی جعلی بسازه و بعنوان ادمین وارد سیستم بشه. مقدار 1 نشون دهنده اولین کاربر Superset هستش که اغلب همون مدیر میشه. مهاجم کوکی جعلی رو میتونه در local storage مرورگرش تنظیم کنه و با رفرش کردن صفحه، ادمین بشه. برای سرورهایی که پشت SSO قرار دارن، مهاجم نیاز به یسری کارایه بیشتر داره تا بتونه user_id رو بدست بیاره. در این گزارش به این مورد نپرداختن.
Superset همونطور که گفتیم، برای مصورسازی و کاوش رو داده طراحی شده بنابراین اگه یه مهاجمی بعنوان ادمین وارد بشه، میتونه این داده ها رو تغییر یا حذف کنه. به طور پیش فرض، پرمیشن اتصالات دیتابیس ها بصورت فقط خواندنی هستش، اما مهاجم با امتیاز مدیر، میتونه پرمیشن نوشتن یا DML رو هم فعال کنه. رابط SQL Lab این امکان رو برای مهاجم میده تا دستورات دلخواه SQL رو روی دیتابیس اجرا کنه. بسته به امتیاز کاربر دیتابیس، مهاجم علاوه بر خوندن داده ها، دستکاری یا حذف اونها ، میتونه روی سرور دیتابیس، کد دلخواه اجرا کنه.
اجرای کد از راه دور و جمع آوری اعتبارنامه ها:
محققا چندین مسیر اجرای کد در رابط مدیریتی وب ،نسخه های مختلف Superset پیدا کردن. اجرای کد هم روی سرور دیتابیس قابل انجامه هم روی خود سرور Superset . علاوه بر اجرای کد، محققا روش های مختلفی رو برای جمع آوری اعتبارنامه ها ،از جمله هش های یوزر و پسورد Superset و اعتبارنامه های دیتابیس که هم بصورت plaintext هستش و هم در قالب قابل برگشت، پیدا کردن. محققا گفتن که روش اکسپلویت رو منتشر نمیکنن، اما اکسپلویت پیچیدگی پایینی داره.
بررسی مجدد در سال 2023 :
محققا در اکتبر 2021، این موضوع رو با تیم Superset در میون گذاشتن، اما بعد از مدتی، در فوریه 2023، تصمیم گرفتن دوباره این وضعیت رو بررسی کنن.
محققا متوجه شدن که در ژانویه 2022 ، مقدار SECRET_KEY به یه مقدار پیش فرض چدید ، CHANGE_ME_TO_A_COMPLEX_RANDOM_SECRET تغییر کرده و تو گیتهاب هم براش یه commit لاگ شده :
محققا اومدن بررسی کردن که آیا این تغییر، موجب تغییر رفتار کاربر هم شده یا نه. برای همین، همون آزمایش اکتبر 2021، رو با کلید پیش فرض قبلی، کلید جدید و دو تا کلید جدید هم از مستندات بدست آوردن، thisISaSECRET_1234 و YOUR_OWN_RANDOM_GENERATED_SECRET_KEY ، تکرار کردن (در کل با 4 کلید)
شودان در کل 3390 سرور Superset داده که از این تعداد ، 3176 دقیقا Superset بودن. از این تعداد، 2124 یعنی 67 درصدش، از یکی از این 4 کلید استفاده کردن.
اگرچه استفاده از Superset بیشتر شده اما استفاده از کلید پیش فرض ، تغییر چندانی نداشته و خیلیا همچنان از SECRET_KEY پیش فرض استفاده میکنن. محققا در ادامه نسخه هارو هم اومدن بررسی کردن. اونا متوجه شدن که تغییر کلید و درج هشدار در نسخه 1.4.1 رخ داده. اما در نسخه های بعدی هم شاهد استفاده از کلید پیش فرض هستیم. مثلا 71 درصد از نمونه های 2.0.0 ، 55 درصد از نمونه های 2.0.1 و 87 درصد از آخرین نسخه Docker version 0.0.0-dev ، از مقادیر پیش فرض استفاده میکنن.
محققا با مشاهده نتایج، دوباره هشداری رو به تیم آپاچی ارسال کردن.
وصله:
تیم Superset با ارائه نسخه 2.1 ، این آسیب پذیری رو اصلاح کرده. در این نسخه اگه سرور با کلید پیش فرض پیکربندی شده باشه، بالا نمی یاد و کاربران خودشون، خودشونو آسیب پذیر نمیکنن.
این اصلاح هم ،امکان نصب با کلید پیش فرض رو از طریق نصب با docker-compose file یا helm template فراهم میکنه. فایل docker-compose حاوی یه کلید پیش فرض جدید ، TEST_NON_DEV_SECRET هستش که گویا کاربران ، Superset با اون اجرا میکنن. همچنین برخی پیکربندی ها هم مقدار admin/admin رو برای یوزر/پسورد کاربر ادمین در نظر گرفتن.
راههای اصلاح:
در بین این 2000 سرور آسیب پذیر، شرکتهای بزرگ، کوچک، سازمانهای دولتی و دانشگاهها وجود داشتن. محققا برای برخیشون، هشدارهایی رو صادر کردن، که بعد از یه مدت کوتاهی، پیکربندی رو اصلاح کردن.
اگه از Superset استفاده میکنید، میتونید با این اسکریپت، مشخص کنید که آیا آسیب پذیر هستید یا نه. اسکریپت با استفاده از ابزار flask-unsign و کلیدهای پیش فرض این موضوع رو بررسی میکنه.
اگه اسکریپت نشون داد که آسیب پذیر هستید و سرورتون از طریق اینترنت قابل دسترسی بود، هر چه سریعتر اونو اصلاح کنید یا از معرض دیده شدن از طریق اینترنت جلوگیری کنید.
اصلاح هم از طریق تغییر و ایجاد یه SECRET_KEY ایمن قابل انجامه که میتونید از این راهنما استفاده کنید. همچنین با توجه به اینکه اطلاعات حساس مانند پسورد دیتابیس هم با این SECRET_KEY رمزگذاری میشن، بعد از تغییر، با استفاده از superset CLI و این راهنما، اونهارو هم تغییر بدید.
در این بررسی، محققا مواردی که سرور پشت SSO باشه رو بررسی نکردن، اما توصیه کردن به دلیل اینکه ممکنه مهاجمین روش هایی رو برای دور زدن SSO داشته باشن، بازم اصلاحیه رو اعمال کنید.
تشخیص اینکه هک شدید:
تشخیص اینکه با استفاده از این آسیب پذیری، هک شدید یا نه سخته، چون مهاجم امتیاز یه کاربر قانونی رو بدست میاره. اما Superset یه لاگ از فعالیتها با عنوان action log هم ارائه میده که می تونید برای تشخیص اینکه هک شدید یا نه، فعالیتهای کاربر رو بررسی کنید. برای این بررسی هم توصیه شده دنبال فعالیتهای غیر نرمال مانند مشاهده یا دستکاری پیکربندی دیتابیس، استخراج داده یا کوئری های غیرنرمال در تاریخچه کوئری های SQLLab باشید. همچنین توصیه شده، فراخوانی های غیرنرمال API به /api/v1/database رو در access log بررسی کنید. این نکته رو در نظر بگیرید که اگه مهاجم کنترل کامل سرور به دست بگیره، میتونه ردپاهای خودش رو پاک کنه.
درس هایی که آموختیم:
مسئله secret key در فلسک، چیز جدیدی نیست، چنین مشکلی در Apache Airflow هم وجود داشت و با شناسه CVE-2020-17526 قابل رهگیری هستش. آسیب پذیری مشابه در Redash با شناسه CVE-2021-41192 که در اون هم برای اصلاح آسیب پذیری ،از راه اندازی سرور با مقدار پیش فرض جلوگیری میکرد.
اینکه کاربران داکیومنتها رو نمیخونن پذیرفته شده هستش و برنامه ها باید طوری توسعه داده بشن تا بطور پیش فرض ایمن باشن. داده هایی که در این گزارش مطرح شده، نشون دهنده این قضیه هستش.