آسیب پذیری Null Pointer در SMBv3

آسیب پذیری Null Pointer در SMBv3

آسیب پذیری Null Pointer در SMBv3

 

(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 دچار مشکل شود و ماشین یا دستگاه را مجبور به راه اندازی مجدد میکند.

 

0 پاسخ

دیدگاه خود را ثبت کنید

تمایل دارید در گفتگوها شرکت کنید؟
در گفتگو ها شرکت کنید.

پاسخی بگذارید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *