(CVE-2018-0833)
تحقیقات و تست هایی که با متد FUZZER بر روی SMB صورت گرفته ,
نتیجه آن پیدا کردن یک آسیب پذیری ساده ولی در عین حال با قدرت و تخریب گر شده است.
این آسیب پذیری روی (Windows 8.1 (X86 و (Windows server 2012 R2(x64 تست و آنالیز شده است.
برای درک بهتر این آسیب پذیری و نحوه کار کردن آن در smb باید بیشتر با smb آشنایی پیدا کنید وحداقل درک متوسطی از آن داشته باشید .
نگاهی به هدر پکت SMBv1:
ساختارSMB_Header مقدار آن byte 32 است.
پروتکل (byte 4):این قسمت باید دارای مقادیری رشته ای “\xFF” ,”S”,”M”,”B” با اندازه4 byte باشد. این کلمات بیانگر مقادیر Ascii هستند که به ترتیب نمایش داده شده اند. در اولین داکیومنت های منتشر شده راجع به SMB این بخش از 1byte پیغام و (3byte) server id تشکیل شده است.
منبع:https://msdn.microsoft.com/en-us/library/ee441774.aspx
همانظور که مشاهده می کنید , مقدار پروتکل با نوع FF byte شروع شده.
در این قسمت به اتفاقات رخ داده در SMBv2 می پردازیم.
اگر مقدار بیتیSMB2_FLAGS_ASYNC_COMMAND در پارامتر Flag وجود داشته باشد , هدر به شکل زیر است.
پروتکل (ID (4 byte : مشخص کننده پروتکل, مقدار آن باید (در شبکه) 0XFE,’S’,’M’ و ‘B’
منبع:https://msdn.microsoft.com/en-us/library/cc246528.aspx
مقدار پروتکل با FE Byte شروع شده است .
حالا می پردازیم به پروتکل SMBv3:کارایی این نسخه از پروتکل چگونه است:
SMBv3 رمزگذاری شده است و هدر آن smb2_Transform است که در ارتباطاتی امن تبادل می شود .
هدر Trasform که برای SMB2 است , وقتی Client وServer پیام رمزگذاری شده ای را ارسال کرده باشند در ارتباط خود از این هدر استفاده می کنند.
پروتکل (4byte):مقدار آن باید (در شبکه) 0Xfd,’s’,’M’,’B’ باشد
SMBv3 همیشه رمزگذاری شده است ,مذاکره و ارتباطات SMBv3 , کهSession آن با Session , SMBv2 آغاز شده است.
پکت های داخل Session , SMBv3 هنگام نصب:
از پکت های 1 تا 8 هدر SMB به این صورت است:
همانطور که در عکس بالا مشاهده می کنید می توانید ببینید شمارنده byte هنوز از OxFE استفاده می کند که کد SMBv2 است , می توان آن را در مستندات مایکروسافت متوجه شد.
” آسیب پذیری Null Pointer در SMBv3 “
از فریم 9 رمزگذاری شده است و شمارنده آن هم از OxFاستفاده کرده است.
همانطور که در POC مشاهده می کنید , Crash وقتی اتفاق می افتد که بی وقفه SMB پکتی را با هدر OxFD ارسال می کند و این ارتباط به وجود آمده بدون negotiating باSession , ارسال می شود.
نگاهی عمیقتر به این Crash می کنیم تا این مشکل را متوجه شویم.
آنالیز و تست های صورت گرفته برای پیدا کردن دلیل این مشکل فقط رویwindows 8.1 انجام شده است .
که دلیل آن به صورت خلاصه ارسال یک بسته به طور خاص به Kernel است و به دلیل استفاده از حافظه رمزگذاری شده و ایمن به آن فشار زیادی وارد می کند.
(آدرس 0x00000030)
ماژولی که این Crash در آن رخ می دهد “mrxsmb.sys” می باشد که smb مایکروسافت که مخفف (Server Massage Block ) می باشد. محل دقیق Crash را (mrxsmb!smbWKsReceiveEvent+8539)اعلام کرد و این قسمت برای حرکت (ecx+3oh) برای رجیستر کردن EAX است.
مقدار ECX به ادرس 0X00000000 اشاره می کند.
وقتی که جریان داخل IDA را دنبال می کنید :
بسته مورد استفاده قرار می گیرد که بررسی شود که آیا رمزگذاری در آن فعال است یا خیر .
این رمزگذاری ها به SMB 3.0 ارتباط دارد چون در این نسخه از پکت های رمزگذاری شده SMB استفاده می شود.
داخل WinDBG به این صورت است:
اساسا چک می کند که رمزگذاری فعال باشد, که اگر موردی قابل توجه در آن پیدا شد راه “False” را دنبال می کند و به سمت مرحله و کار بعدی خود می رود.
بررسی و مقایسه هایی انجام می دهد که اگر ECX با مقدار HEX 0X34 ثبت شده باشد, در این صورت مقایسه می کند که اگر ECX مقدارش کمتر یا برابر 0X34 باشدکه موردی که در حال بررسی می باشد , (False) است.
این مسیر False ادامه دارد:
مقایسه های دیگری نشان می دهد که اگر EDX بالاتر از مقدار (ESP+4C) باشد ,نتیجه مورد ما True می شود.
مرحله بعدی به راحتی مقدارهای مورد نیاز خود را ثبت(Register) می کند.
مرحله بعدی دوباره مقدار ECX را با 0X34 مقایسه می کند که اگر ECX از 0X34 بالاتر باشد مسیر (True) یا درست را طی می کند.
در موردی که ما در حال بررسی آن هستیم به سمت مسیر درست می رود در صورتی که مقدار ECX بیشتر از 0X34 باشد.
در بلوک دستوری زیر تستی انجام می شود بین مقدارهای زیر _Microsoft_Windows_SMBClientEnableBits to 0x80000000
که در WinDBG می توانیم ببینیم که این تست نتیجه (False) را می دهد و سپس این مسیر (False) را دنبال می کنیم.
دستورالعمل های تستی همیشه درست خواهد بود , و ما را به سمت “locAoF2OeO5” می فرستد.
بعد از قرار دادن صفر داخل پشته , به سمت عملکرد”LocAoF20E15″ می رود:
در دستورالعملی که ECX+30h به سمت EAX حرکت می کند , Crash در اینجا رخ می دهد به دلیل اینکه ECX مساوی با 0X0000000 است و سعی می کند مقادیر خود را از 0X00000030 بخواند که این اطلاعات درفضای ذخیره سازی امنی قرار دارد.
همین موضوع دلیلی می شود تا Kernel دچار مشکل شود و ماشین یا دستگاه را مجبور به راه اندازی مجدد میکند.