روابط عمومی شرکت ایدکو (توزیعکنندهی محصولات کسپرسکی در ایران)؛ مدتی پیش خبری رسید از اکسپلویت روز صفر که تیم کسپرسکی در حملات باجافزاری که به عنوان CVE-2023-28252 پچ شد کشف کرد. ما سریعاً این حمله را به مایکروسافت گزارش دادیم. آن اکسپلویت روز صفر کشفشده به اکسپلویتهای [1]EoP دیگرِ مایکروسافت ویندوز شبیه بود که در طول سال 2023 آن را در حملات باجافزاری دیدیم. پی بردیم که از تاریخ ژوئن 2022 مهاجمین از اکسپلویتها برای دست کم 5 آسیبپذیریِ درایور CLFS[2] استفاده میکردهاند که چهار آسیبپذیری از بین این 5 آسیبپذیری (CVE-2022-24521, CVE-2022-37969, CVE-2023-23376, CVE-2023-28252) در محیط بیرون به عنوان روزهای صفر مچشان گرفته شد.
استفاده از درایور روز صفر Win32k در حملات این روزها واقعاً تعجب آور نیست، زیرا مشکلات طراحی آن مؤلفه به خوبی شناخته شده و بارها و بارها مورد سوء استفاده قرار گرفته است. اما ما قبلاً ندیده بودیم که این همه اکسپلویت درایور CLFS در حملات فعال مورد استفاده قرار گیرد، و ناگهان تعداد زیادی از آنها فقط در یک سال ضبط شدند. آیا مشکل جدی در مورد درایور CLFS وجود دارد؟ آیا همه این آسیبپذیری ها مشابه با هم هستند؟ آیا مایکروسافت به نوعی در اصلاح این آسیب پذیریها سهلانگاری کرد؟ این سؤالات ما را بر آن داشت تا نگاه دقیقتری به درایور CLFS و آسیب پذیریهای آن بیندازیم. از آنجایی که شاید متن کمی طولانی شود آن را به شش بخش مجزا تقسیم کردیم. با ما همراه باشید.
این قسمت قسمت های داخلی درایور Common Log File System (CLFS) و اشکالات طراحی آن را پوشش میدهد.
پنج بخش بعدی، علل اصلی و سوء استفاده از پنج آسیبپذیری را که در طول سال در حملات باجافزار استفاده شدهاند، پوشش میدهند.
قسمت 1 - Windows CLFS و پنج اکسپلویت از اپراتورهای باج افزار
قسمت 2 –Windows CLFS و پنج اکسپلویت از اپراتورهای باج افزار (Exploit #1 – CVE-2022-24521)
قسمت 3 –Windows CLFS و پنج اکسپلویت از اپراتورهای باج افزار (Exploit #2 – سپتامبر 2022)
قسمت 4 - Windows CLFS و پنج اکسپلویت از اپراتورهای باج افزار (Exploit #3 - اکتبر 2022)
قسمت 5 –Windows CLFS و پنج اکسپلویت از اپراتورهای باج افزار (Exploit #4 – CVE-2023-23376)
قسمت 6 –Windows CLFS و پنج اکسپلویت از اپراتورهای باج افزار (Exploit #5 – CVE-2023-28252)
جزئیات CLFS
برای درک دلایل اصلی آسیبپذیریها و بهرهبرداری از آنها، بسیار مهم است که بفهمیم CLFS چیست، چگونه کار میکند و ویژگیهای طراحی آن کدام است.
Common Log File System (CLFS) یک زیرسیستم فایل log همه منظوره است. این توسط خود سیستم عامل استفاده میشود، اما میتواند توسط هر برنامهای که نیاز به ثبت دادهها/رویداد با کارایی بالا دارد، استفاده شود، و مایکروسافت اسنادی را برای آن ارائه میکند (در اینجا برای حالت هسته و اینجا برای APIهای حالت کاربر). اولین بار در Windows Server 2003 R2 / Windows Vista ظاهر شد و در درایور clfs.sys پیادهسازی شد. گزارشها با تابع API CreateLogFile ایجاد/باز میشوند و شامل یک فایل اصلی ویژه با فراداده (به نام Base Log File و دارای پسوند فایل blf.)و هر تعداد کانتینر برای ذخیره دادههای واقعی است. این کانتینرها با استفاده از توابع API AddLogContainer و AddLogContainerSet ایجاد میشوند.
همانطور که ممکن است حدس بزنید، Base Log File (BLF)، یک فایل با ابرداده، نقش کلیدی در کار با گزارش ها ایفا می کند. فرمت این فایل توسط مایکروسافت مستند نشده و قرار است هرگونه کار با آن از طریق API ارائه شده انجام شود. اما خود فرمت خیلی پیچیده نیست و مایکروسافت نمادهای اشکالزدایی را برای clfs.sys فراهم می کند، بنابراین فقط زمان زیادی بود که شخصی آن را مهندسی معکوس کند. و جای تعجب نیست که این قالب توسط مایکروسافت مستند نشده است، زیرا فقط نگاه کردن به آن زنگ خطر را به صدا در میآورد. فایل های BLF از ساختارهای حافظه هسته تشکیل شدهاند و حتی فیلدهایی برای ذخیره نشانگرهای حافظه وجود دارد!
اگرچه تبلیغاتی از سوی مایکروسافت نیست اما نمیتوان گفت که آنها آن را پنهان میکند، زیرا اساساً در اسناد ذکر شده است. مستندات میگوید که CLFS برای عملکرد بهینهسازی شده است و تمام کارها در بافرهایی انجام میشود که بدون کپی روی دیسک ریخته میشوند. این بدان معناست که این بافرها از روی دیسک به همان روش خوانده میشوند.
CLFS برای حل یک کار نسبتاً پیچیده وجود دارد و بنابراین عملکرد پیچیدهای دارد. پایه کد آن کاملا قدیمی است. فایل های ساختار مشکوک را در هسته تجزیه میکند. همه کدها برای عملکرد بهینه شده اند. در تجربه ما کدهایی با تمام این ویژگی ها معمولاً در معرض آسیبپذیری هستند. و این مورد نیز از این قاعده مستثنی نیست. جستجوی «آسیبپذیری درایور سیستم فایل لاگ مشترک ویندوز» در میان راهنماهای بهروزرسانی امنیتی نشان میدهد که بیش از 30 آسیبپذیری از این دست از سال 2018 اصلاح شده، از جمله چهار روز صفر که قبلاً ذکر شد که در محیط بیرون ثبت شدهاند.
حال بیایید نگاهی دقیقتر به فرمت فایل BLF بیندازیم. مستندات الکس یونسکو در انجام این تحقیق بسیار مفید بود، اگرچه باید اعتراف کنیم که مجبور بودیم تجزیه کننده CLFS را خودمان بنویسیم و بسیاری از مطالب مشابه را خودمان مهندسی معکوس کنیم تا به طور کامل دلایل اصلی آسیب پذیریها را درک کنیم. در زیر تمام جزئیات مربوط به فرمت فایل BLF را توضیح خواهیم داد که برای درک علل ریشهای آسیب پذیریهایی که میخواهیم در مورد آنها صحبت کنیم و نحوه سوء استفاده از آنها لازم است. در زیر برخی از اطلاعات کلیدی برای درک قالب آورده شده است. فایل های BLF از رکوردها تشکیل شدهاند. این رکوردها در بلوک ها ذخیره میشوند. این بلوکها بخش به بخش نوشته/خوانده می شوند. اندازه یک بخش برابر با 0x200 بایت است. دو بایت آخر یک سکتور برای ذخیره امضای سکتور استفاده می شود. اگر دو بایت آخر توسط امضای سکتور اشغال شده باشد، بایت های اصلی بلوک کجا ذخیره میشوند؟ در مکان دیگری که توسط offset در هدر بلوک مشخص شده است، اما ما در یک لحظه به آن باز خواهیم گشت. رکوردها بسته به نوع آنها ممکن است شامل ساختارهای داده اضافی نیز باشند.
هر بلوک با یک هِدر بلوک - CLFS_LOG_BLOCK_HEADER شروع می شود. هیچ توضیحی از این ساختار در نمادهای اشکالزدایی وجود ندارد، بنابراین برای جلوگیری از سردرگمی از نام فیلدهای مستندات ذکر شده قبلی استفاده میکنیم. هدر بلوک حاوی اطلاعاتی در مورد تعداد بخشها، جمع کنترلی دادههای بلوک و سایر فیلدهایی است که برای ما چندان مهم نیستند. ما فقط به دو زمینه علاقه داریم. اولین مورد RecordOffsets است که آرایهای از افست رکوردها است. این فرمت به بلوکها اجازه میدهد تا رکوردهای زیادی داشته باشند، اما همیشه فقط اولین افست در کد استفاده میشود. ما همچنین به یک افست به نام SignaturesOffset علاقه مند هستیم. این افست به مکانی در بلوک اشاره میکند که بایتهای اصلی در آن ذخیره میشوند، بایتها با امضاهای بخش که قبلا ذکر شد جایگزین میشوند. همه افست ها نسبی هستند و در صورت استفاده به ابتدای هدر بلوک اضافه میشوند. فایلهای BLF از شش بلوک تشکیل شده اند. این بلوکها دارای نامها/انواع زیر هستند: CONTROL، CONTROL_SHADOW، GENERAL، GENERAL_SHADOW، SCRATCH، SCRATCH_SHADOW . با این حال، در واقع شش نوع مختلف وجود ندارد، بلکه تنها سه نوع وجود دارد. بلوک های SHADOW حاوی کپی قبلی فرادادههای ضبط شده هستند و در صورت قطع شدن ضبط برای بازیابی دادهها استفاده میشوند.
فایلهای BLF تازه ایجادشده همیشه طرحبندی یکسانی دارند، و اکسپلویتها از آن بهره میبرند – نیازی به ساختن از ابتدا یا حمل یک فایل BLF از پیش ساختهشده برای ایجاد آسیبپذیری نیست، کافی است از سیستمعامل بخواهید یک فایل BLF جدید ایجاد و در افست هاردکد دادههای پچ ایجاد کند.
حالا بیایید در مورد رکوردهایی که در بلوک ها ذخیره میشوند صحبت کنیم. رکوردهای ذخیره شده در بلوک های CONTROL توسط ساختار CLFS_CONTROL_RECORD ، رکوردهای ذخیره شده در بلوک های GENERAL توسط ساختار CLFS_BASE_RECORD_HEADER و رکوردهای ذخیره شده در بلوک های SCRATCH توسط ساختار CLFS_TRUNCATE_RECORD_HEADER تعریف میشوند. همه این ساختارهای رکورد با ساختار CLFS_METADATA_RECORD_HEADER شروع میشوند که دارای یک فیلد DumpCount است.
DumpCount توسط تابع ReadMetadataBlock برای انتخاب بین یک بلوک معمولی و کپی SHADOW و آخرین و معتبرترین بلوک استفاده میشود. بلوک CONTROL در همان ابتدای فایل BLF قرار دارد و CLFS_CONTROL_RECORD حاوی اطلاعاتی در مورد مکان بلوک های دیگر است. یشتر فیلدها در ساختار CLFS_CONTROL_RECORD توسط تابع تغییر اندازه log استفاده میشوند، اما فیلد rgBlocks نیز وجود دارد که ما در حال حاضر بیشتر به آن علاقهمندیم. این فیلد آرایه ای از ساختارهای CLFS_METADATA_BLOCK با اطلاعات مربوط به تمام بلوک های موجود در فایل است. هر ساختار CLFS_METADATA_BLOCK حاوی اطلاعاتی در مورد اندازه بلوک، افست آن (از ابتدای فایل) و یک مکان نگهدار برای ذخیره نشانگر هسته بلوک هنگام بارگیری در حافظه است. بلوک GENERAL بلوکی است که حاوی اطلاعات واقعی ذخیره شده در فایل BLF است. این شامل اطلاعاتی در مورد مشتریان (کسانی که از گزارش استفاده میکنند)، کانتینرها (فایلهایی با دادههای واقعی)، توصیفگرهای امنیتی برای کانتینرها میشود.
ساختار CLFS_BASE_RECORD_HEADER بسیار بزرگ است و 10 بخش را اشغال میکند. این به این دلیل است که شامل پنج آرایه بزرگ با افست است. اطلاعات مربوط به کلاینت ها و کانتینرها به صورت ساختارهای CLFS_CLIENT_CONTEXT و CLFS_CONTAINER_CONTEXT نشان داده میشود که در بلوک GENERAL به عنوان نماد ذخیره میشوند. نماد چیست؟ این ترکیبی از ساختار CLFSHASHSYM و ساختار CONTEXT بلافاصله پس از آن است. همه این کارها به این دلیل انجام می شود که کد بتواند به سرعت یک ساختار CONTEXT را با استفاده از جستجوی هش پیدا کند. آرایههای rgClientSymTbl، rgContainerSymTbl و rgSecuritySymTbl آفستها را به ساختارهای CONTEXT در قالب نمادها ذخیره میکنند. آرایههای rgClients و rgContainers برای ذخیره افستهایی استفاده میشوند که مستقیماً به همان ساختارهای CONTEXT اشاره میکنند، اما ساختارهای CLFSHASHSYM را دور میزنند. درایور CLFS از همه این آرایه ها استفاده می کند و توابع مختلف از روش های مختلفی برای دسترسی به ساختارهای CLFS_CLIENT_CONTEXT و CLFS_CONTAINER_CONTEXT استفاده میکنند. این به وضوح یک طراحی بد است که همانطور که خواهید دید نتیجه معکوس هم داشته است!
ما همچنین به زمینه cbSymbolZone علاقه مند هستیم. از آنجایی که مشتریان و کانتینرهای بیشتری را می توان در زمان اجرا به گزارش اختصاص داد، کد از این فیلد برای دریافت افست رایگان بعدی در بلوک GENERAL استفاده می کند، جایی که میتواند یک نماد جدید ایجاد کند. این منطقه برای ساختارهای جدید بلافاصله پس از ساختار CLFS_BASE_RECORD_HEADER شروع میشود.
تمام ساختارهای موجود در ناحیه نماد (از جمله CLFSHASHSYM، CLFS_CLIENT_CONTEXT و CLFS_CONTAINER_CONTEXT) به عنوان گره یا نود نمایش داده میشوند. همه این ساختارها با یک عدد جادویی منحصر به فرد شروع می شوند که نوع گره و سپس اندازه ساختار را مشخص میکند. یک واقعیت جالب در رابطه با CLFSHASHSYM این است که برخی از توابع به سادگی آدرس ساختار CONTEXT را میگیرند، 12 یا 16 را از آن کم م و با فیلدهای cbSymName و cbOffet ساختار CLFSHASHSYM که انتظار می رود در آنجا وجود داشته باشد، کار میکنند.
ساختار CLFS_CLIENT_CONTEXT شامل فیلدهای زیادی است که بسیاری از آنها خود توضیحی هستند. برای درک ریشهای آسیبپذیریهایی که در زیر توضیح داده شده است، ما بیشتر به فیلدهای llCreateTime/llAccessTime/llWriteTime و fAttributes علاقهمندیم. سه مورد اول خود توضیح هستند و fAttributes حاوی پرچمهای FILE_ATTRIBUTE مرتبط با فایل BLF است.
CLFS_CONTAINER_CONTEXT آخرین ساختاری است که باید به آن نگاه کنیم. لطفاً به قسمت pContainer توجه کنید. این یک مکان نگهدار برای ذخیره یک اشاره گر هسته در کلاس CClfsContainer است. این ممکن است نیاز به تکرار داشته باشد: CLFS_CONTAINER_CONTEXT و تمام ساختارهای دیگر که قبلاً بحث شد از فایلهای BLF ذخیره شده روی دیسک خوانده میشوند. بنابراین، اگر مهاجمان موفق شوند یک CLFS_CONTAINER_CONTEXT مخرب را به یک فایل BLF تزریق و آن را با کد بدون اعتبارسنجی/آغازسازی مناسب پردازش کنند، مهاجمان میتوانند جریان کنترل را ربوده و امتیازات خود را از سطح کاربر به هسته ارتقا دهند.
نواقص مرگبار CLFS
CLFS شاید خیلی "برای عملکرد بهینه شده" باشد. بهتر است به جای خالی کردن ساختارهای هسته که روی یک فایل نوشته شده است، یک فرمت فایل معقول داشته باشیم. تمام کار با این ساختارهای هسته (با اشاره گرها) درست در بلوکهای خوانده شده از دیسک اتفاق میافتد. از آنجایی که تغییرات در بلوکها و ساختارهای هسته ذخیره شده در آنجا انجام میشود، و این تغییرات باید روی دیسک ریخته شوند، کد بلوکهای شروع شده از CLFS_LOG_BLOCK_HEADER را بارها و بارها هر بار که نیاز به دسترسی به چیزی دارد، تجزیه میکند. تمام این تجزیه با استفاده از افستهای نسبی انجام میشود که میتواند به هر مکانی در یک بلوک اشاره کند. اگر یکی از این آفستها در حین اجرا در حافظه خراب شود، عواقب آن میتواند فاجعهبار باشد زیرا مهاجمین میتوانند یک CLFS_CONTAINER_CONTEXT مخرب را تامین کنند. اما شاید بدتر از همه، آفستهای موجود در فایل BLF روی دیسک را میتوان به گونهای دستکاری کرد که ساختارهای مختلف با هم همپوشانی داشته باشند و منجر به عواقب غیرقابل پیشبینی شود. همه این عوامل منجر به تعداد زیادی آسیبپذیری و اکسپلویت آسان از آنها میشود.
[1] elevation-of-privilege
[2] Common Log File System
منبع: کسپرسکی آنلاین (ایدکو)
کسپرسکی اسم یکی از بزرگترین شرکتهای امنیتی و سازنده آنتی ویروس است که برخی از کاربران اشتباهاً این شرکت و محصولات آنتی ویروس آن را با عناوینی نظیر کسپرسکای،کاسپرسکی، کسپراسکای، کسپراسکای، و یا کاسپراسکای نیز میشناسد. همچنین لازم به ذکر است مدیرعامل این شرکت نیز یوجین کسپرسکی نام دارد.