Ein unbekannter Forscher hat eine Zero Day Lücke gefunden, die es erlaubt seine Rechte zu erweitern und in diesem Kontext eine Shell zu spawnen. Er veröffentlichte sowohl einen Blogbeitrag sowie einen Exploit. Im folgenden wird dieser analysiert und der Angriff erklärt.
Bisher gibt es von Microsoft keinen Patch dazu.
Wie funktioniert der Angriff?
Quelle: https://github.com/Nightmare-Eclipse/BlueHammer
1. RPC-Verbindung zum Windows Defender Dienst
Der Angriff nutzt eine Schwäche im Update-Mechanismus von Windows Defender aus. Windows Defender selbst läuft als hochprivilegierter Dienst und nutzt für Updates eine sogenannte RPC-Schnittstelle (hier c503f532-443a-4c69-8300-ccd1fbdb3839 – weitere Infos unter https://gist.github.com/enigma0x3/2e549345e7f0ac88fad130e2444bb702). Diese Schnittstelle ermöglicht es Programmen, Funktionen in anderen Adressräumen aufzurufen. Der Exploit ruft diese direkt an (ab Z.269) und täuscht dem Defender ein Update vor (RPC_STATUS stat = Proc42_ServerMpUpdateEngineSignature(bindhandle, NULL, args->dirpath, &errstat);(Z.285)). Hierfür werden sogar echte Microsoft Update Dateien aus dem Internet heruntergeladen.

Aufbau und Interaktion zur RPC Schnittstelle des Defenders
2. TOCTOU-Manipulation – Erstellen eines NT Symbolic Link
Während der Defender Dienst prüft, welche Datei er einlesen soll, entsteht eine zeitliche Lücke bis zum eigentlichen Einlesen. In dieser Zeit tauscht der Exploit das Ziel aus, mittels eines Symbolic Links. Der privilegierte Defender-Prozess liest dann nicht mehr die harmlose Update-Datei, sondern ein vom Angreifer kontrolliertes Ziel. Der Code lädt dabei NtCreateSymbolicLinkObject direkt aus der ntdll.dll zur Laufzeit, anstatt auf normale Windows-APIs zurückzugreifen. Dadurch kann er eine interne, nicht dokumentierte NT-Systemfunktion nutzen, um im Object Manager Namespace symbolische Links auf niedriger Ebene zu erzeugen und so den Pfad gezielt zwischen Prüfung und Nutzung umzubiegen.

Erstellen des NT Symbolic Links
Dieses Verfahren nennt man auch Time-of-Check, Time-of-Use (TOCTOU)-Prinzip und bedeutet so viel wie: geprüft wird Objekt A, verwendet wird aber Objekt B. Weitere Infos dazu unter: https://www.heise.de/hintergrund/Secure-Coding-CWE-377-TOCTOU-Race-Conditions-in-den-Griff-bekommen-10081613.html
3. SAM-Zugriff via Offline Registry
Nach dem Austausch des Objektes, wird dieses mit den Defender Rechten (SYSTEM) geöffnet. Darüber gelangt er an die SAM-Datenbank, welche die Benutzerverwaltung von Windows ist. Der Exploit nutzt eine Offline Registry-Bibliothekt (offreg.h), die zum Bearbeiten von Registry-Hives im Offline-Modus (also ohne die laufenden Sicherheitsprüfungen des Systems) genutzt werden kann.

Laden der Offline Registry-Bibliotheken
In Kombination mit ntsecapi.h (NT Security API) wird damit direkt in die SAM-Datenbank geschrieben, um Passwörter und Gruppenrechte zu ändern.
Dazu wird DWORD err = OROpenHive(sampath, &hSAMhive);(Z. 2492) verwendet, wobei sampathder Pfad zur Datei SAM-Datei (C:\Windows\System32\config\SAM) ist und OROpenHivedie Datei als offline Registry Hive lädt.

Initialisierung der Passwortmanipulation in DoSpawnShellAsAllUsers
4. Zugriff auf die Account Struktur und Passwort Änderung
Nachdem die SAM geladen wurde, navigiert der Code innerhalb der Registry-Struktur. Zuerst wird der Account-Bereich geöffnet (Z.2510) err = OROpenKey(hSAMhive, L"SAM\\Domains\\Account", &hkey);
Kurz darauf folgt der entscheidende Schritt, bei dem der Zugriff auf alle Benutzer erfolgt (Z.2533) err = OROpenKey(hSAMhive, L"SAM\\Domains\\Account\\Users", &hkey);.
Dieser Pfad ist wichtig, denn hier liegen alle lokalen Benutzerkonten. Jeder Subkey innerhalb dieses Schlüssels entspricht einem Benutzer, identifiziert durch seine RID.

Zugriff auf die SAM-Account-Struktur – Öffnen des Registry-Pfads
Um alle Nutzer zu verarbeiten, wird im nächten Schritt, die Anzahl der Subkeys ermittelt, mittels (Z. 2541)
DWORD subkeys = NULL; err = ORQueryInfoKey(hkey, NULL, NULL, &subkeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL);

Enumeration der Benutzerkonten in der SAM-Hive
Die eigentliche Suche nach den Accounts erfolgt über eine Schleife, die jeden Subkey durchläuft (Z. 2552)
for (int i = 0; i < subkeys; i++) { DWORD keynamesz = 0x100; wchar_t keyname[0x100] = { 0 }; err = OREnumKey(hkey, i, keyname, &keynamesz, NULL, NULL, NULL);
Dabei liefert OREnumKeyjeweils den Namen eines Subkeys. Für jeden gefundenen Eintrag wird anschließend der jeweilige User Key geöffnet (Z. 2564)
ORHKEY hkey2 = NULL; err = OROpenKey(hkey, keyname, &hkey2);
Dadurch ist es möglich, den sogenannten V-Wert auzulesen und an Usernamen, LM-Hash, NTLM-Hash und weitere Metadaten zu gelangen (Z. 2571).
DWORD valuesz = 0; err = ORGetValue(hkey2, NULL, L"V", NULL, NULL, &valuesz);
Der NTLM Hash (realNTLMHash) wird entschlüsselt und es folgt die Passwortänderung durch die Funktion ChangeUserPasswort. Dabei wird der aktuelle Hash durch den neuen Hash (newNTLM) ersetzt.

Passwortänderung durch Überschreiben des Hashes
5. Spawnen der Shell
Nach erfolgreicher Passwortänderung spawnt der Exploit im nächsten Schritt eine Shell im Kontext des manipulierten Users und nutzt dafür das temporär gesetzte Passwort:
if (!CreateProcessWithLogonW( username, NULL, newpassword_unistr, LOGON_WITH_PROFILE, L"C:\\Windows\\System32\\conhost.exe", NULL, CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT, NULL, NULL, &si, &pi)) { printf(" Shell : Error %d\n", GetLastError()); } else { printf(" Shell : OK.\n"); }

Spawnen der Shell
Mit dem erfolgreichen Spawn der Shell ist die Ausführungskette des Exploits abgeschlossen. Durch die temporäre Manipulation der NTLM-Hashes und die anschließende Anmeldung im Kontext privilegierter Accounts erhält der Angreifer unmittelbaren Zugriff auf eine interaktive Session mit erweiterten Rechte.
