flawopen.com/Incidents/windows-update-stack-symlink-eop-september-2026
CVE-2026-81963: Windows Update-Linkfehler
CVE-2026-81963 ist eine ausgenutzte Link-Auflösungs-Lücke in Windows Update. Betroffene Versionen, Microsofts Fix und sichere Dateiöffnung.[1], [2]
Ein Nachtportier mit Generalschlüssel bringt Pakete in „den Lagerraum am Ende des Flurs“ und folgt dabei den Pfeilen an den Wänden, ohne zu prüfen, wo er ankommt. Die Mieter dürfen diese Pfeile umhängen. Einer dreht den Pfeil zum Lagerraum so, dass er auf das Büro der Geschäftsführung zeigt, und der Portier, dessen Schlüssel jede Tür öffnet, geht hinein und legt das Paket auf den Schreibtisch der Chefin. Der Mieter hätte diese Tür nie öffnen können; der Schlüssel des Portiers hat es für ihn getan. Die Lösung: Der Portier liest die Nummer der Tür, die er tatsächlich geöffnet hat, und folgt keinen Pfeilen mehr, die Mieter verschieben können.[5], [9]
Kernkonzepte & Begriffe
Windows Update Stack- Die Windows-Komponenten, die Updates suchen, herunterladen, bereitstellen und installieren. Sie laufen als SYSTEM, weil das Installieren von Updates Schreibzugriffe auf geschützte Teile des Betriebssystems erfordert.[1]
SYSTEM (NT AUTHORITY\SYSTEM)- Das lokale Konto, unter dem Windows-Dienste laufen. Es hat auf dem lokalen Rechner mehr Rechte als ein Administrator, daher wird ihm kaum eine Dateioperation verweigert.[1]
Junction / symbolischer Link (Reparse Point)- NTFS-Objekte, die einen Pfad auf einen anderen umleiten. Ein Standardbenutzer kann in einem Ordner, den er kontrolliert, eine Junction anlegen und diesen Namen auf ein Verzeichnis umleiten, in das er nicht schreiben darf.[9]
Link Following (CWE-59)- Ein Programm öffnet, schreibt, verschiebt oder löscht eine Datei über ihren Namen, ohne zu prüfen, ob der Name dorthin aufgelöst wird, wo es erwartet; ein von Dritten angelegter Link lenkt die Operation um.[5], [2]
FILE_FLAG_OPEN_REPARSE_POINT- Ein CreateFileW-Flag, das die letzte Pfadkomponente selbst öffnet, wenn sie ein Reparse Point ist, statt diesem letzten Link zu folgen. Es verhindert für sich genommen nicht die Auflösung von Reparse Points in vorherigen Pfadkomponenten.[6]
TOCTOU (CWE-367)- Time-of-check to time-of-use: Das Dateisystem ändert sich zwischen einer Prüfung und der Operation, die sich darauf verlässt. Einen Pfad-String zu prüfen und ihn danach über den Namen zu öffnen, lässt genau dieses Zeitfenster offen.[12]
CWE-284 (Unzureichende Zugriffskontrolle)- Microsoft ordnet dieser CVE sowohl
CWE-59als auchCWE-284zu.CWE-59bezeichnet den konkreten Fehler bei der Linkauflösung.CWE-284ist eine allgemeine Pillar-CWE, deren Verwendung zur Zuordnung realer Schwachstellen MITRE ausdrücklich nicht empfiehlt. Sie ist als breitere Microsoft-Klassifizierung desselben gemeldeten Problems zu verstehen, nicht als Beleg für einen zweiten Fehler.[2], [11], [5]
Framework-Zuordnungen
- CWE-Referenz für die in diesem Leitfaden beschriebene Schwachstelle: CWE-59 CWE-284
- CISA KEV — aufgenommen am 2026-09-08 — CVE-2026-81963
Vorfall-Zeitstrahl
Microsoft reserviert CVE-2026-81963.[2]
September-Patchday: Microsoft veröffentlicht den Fix und kennzeichnet die Lücke als „Exploitation Detected“ und nicht öffentlich bekannt.[1]
Die CISA nimmt CVE-2026-81963 in den Katalog Known Exploited Vulnerabilities auf; US-Bundesbehörden müssen bis zum 22. September 2026 patchen.[4]
Microsoft veröffentlicht eine überarbeitete Fassung des Advisorys.[1]
Schritt-für-Schritt Angriffsablauf
Ein SYSTEM-Dienst arbeitet in einem Pfad, den Benutzer ändern können
Komponenten des Update Stack laufen als SYSTEM und verarbeiten Dateien in Staging- und Arbeitsverzeichnissen. Kann ein Standardbenutzer irgendwo auf diesem Pfad Einträge anlegen, löschen oder umbenennen, bestimmt er, wohin der Pfad aufgelöst wird. Welcher Pfad hier betroffen war, hat Microsoft nicht mitgeteilt.[1]
Der Dienst folgt dem Link
Windows löst Reparse Points beim Öffnen eines Pfads normalerweise auf. FILE_FLAG_OPEN_REPARSE_POINT betrifft die letzte Komponente; vorherige Komponenten können weiterhin aufgelöst werden. Schreibt der Dienst anschließend über einen ungeprüften Pfad, verwendet die Zugriffskontrolle sein SYSTEM-Token. Prüfen Sie den Verzeichnis-Handle und erstellen Sie die Datei relativ zu diesem Handle.[6], [8]
Quellcode: Verwundbar vs. Sicher
Microsoft hat weder die betroffene Funktion noch den Patch veröffentlicht. Dieses defensive Beispiel ist kein Microsoft-Code. Die Prüfung des Besitzers allein reicht nicht aus: Aus dem Besitzer eines Objekts folgt nicht, dass seine DACL Schreibzugriffe normaler Benutzer verweigert. Das Muster setzt voraus, dass das Installationsprogramm den festen Staging-Pfad und alle übergeordneten Verzeichnisse mit einer expliziten DACL anlegt, die Schreibzugriff nur SYSTEM und Administrators erlaubt. Die Funktion liest oder prüft die DACL nicht; die vom Installationsprogramm eingerichteten Berechtigungen sind eine Bereitstellungsvoraussetzung. Es prüft den geöffneten Verzeichnis-Handle und erstellt einen einzelnen Dateinamen relativ zu diesem Handle mit NtCreateFile und FILE_CREATE; ein zusammengesetzter Pfad wird nicht erneut geöffnet. Prüfen Sie DACL und Dateisystemverhalten in den unterstützten Umgebungen. Installieren Sie Microsofts Update, um CVE-2026-81963 zu beheben.[5], [6], [7], [8], [9], [10]
Quelltextauszug: Beispiel für Windows-Pfadbehandlung; kein Microsoft-Quellcode
/* Veranschaulichendes Beispiel, nicht Microsoft-Quellcode: Die betroffene Funktion
* wurde nicht veröffentlicht. Ein SYSTEM-Dienst schreibt in ein Staging-Verzeichnis,
* das Standardbenutzer ändern können.
*/
BOOL WriteStagedFile(LPCWSTR stagingDir, LPCWSTR name,
const BYTE *data, DWORD size)
{
WCHAR path[MAX_PATH];
if (FAILED(StringCchPrintfW(path, MAX_PATH, L"%s\\%s", stagingDir, name)))
return FALSE;
/* CWE-59: CreateFileW löst Junctions und symbolische Links in jeder Pfadkomponente
* auf; die Zugriffsprüfung verwendet das SYSTEM-Token. Ersetzt ein Benutzer
* stagingDir durch eine Junction, landet der Schreibzugriff an deren Ziel.
*/
HANDLE h = CreateFileW(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
if (h == INVALID_HANDLE_VALUE)
return FALSE;
DWORD written = 0;
BOOL ok = WriteFile(h, data, size, &written, NULL) && written == size;
CloseHandle(h);
return ok;
}/* Veranschaulichendes Abwehrmuster, weder Microsoft-Quellcode noch Patch. Das
* Installationsprogramm muss diesen Pfad und alle übergeordneten Verzeichnisse mit
* einer expliziten DACL anlegen, die Schreibzugriff nur SYSTEM und Administrators
* erlaubt.
*/
#include <windows.h>
#include <winternl.h>
static const WCHAR STAGING_DIR[] =
L"C:\\ProgramData\\Vendor\\Update\\Staging";
BOOL WriteStagedFile(LPCWSTR name, const BYTE *data, DWORD size)
{
if (name == NULL || data == NULL || name[0] == L'\0' ||
wcspbrk(name, L"\\/:") != NULL || wcscmp(name, L".") == 0 ||
wcscmp(name, L"..") == 0)
return FALSE;
/* Das Verzeichnisobjekt fixieren; ohne FILE_SHARE_DELETE kann es nicht umbenannt
* werden.
*/
HANDLE dir = CreateFileW(STAGING_DIR,
FILE_LIST_DIRECTORY | FILE_TRAVERSE | FILE_READ_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS |
FILE_FLAG_OPEN_REPARSE_POINT,
NULL);
if (dir == INVALID_HANDLE_VALUE)
return FALSE;
FILE_ATTRIBUTE_TAG_INFO tag;
WCHAR actual[MAX_PATH];
BOOL ok = FALSE;
DWORD n;
if (!GetFileInformationByHandleEx(dir, FileAttributeTagInfo,
&tag, sizeof tag) ||
(tag.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT))
goto done;
n = GetFinalPathNameByHandleW(dir, actual, MAX_PATH,
FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
if (n == 0 || n >= MAX_PATH ||
_wcsicmp(actual, L"\\\\?\\C:\\ProgramData\\Vendor\\Update\\Staging") != 0)
goto done;
/* Das neue Element relativ zu diesem Handle öffnen, den Pfad niemals neu
* zusammensetzen.
*/
size_t nameChars = wcslen(name);
if (nameChars == 0 || nameChars > 255)
goto done;
USHORT nameBytes = (USHORT)(nameChars * sizeof(WCHAR));
UNICODE_STRING relativeName = { nameBytes, nameBytes, (PWSTR)name };
OBJECT_ATTRIBUTES oa = {0};
oa.Length = sizeof oa;
oa.RootDirectory = dir;
oa.ObjectName = &relativeName;
oa.Attributes = OBJ_CASE_INSENSITIVE;
IO_STATUS_BLOCK iosb = {0};
HANDLE file = INVALID_HANDLE_VALUE;
NTSTATUS status = NtCreateFile(
&file, FILE_WRITE_DATA | SYNCHRONIZE, &oa, &iosb, NULL,
FILE_ATTRIBUTE_NORMAL, 0, FILE_CREATE,
FILE_NON_DIRECTORY_FILE | FILE_OPEN_REPARSE_POINT, NULL, 0);
if (!NT_SUCCESS(status))
goto done; /* FILE_CREATE schlägt fehl, wenn der Eintrag bereits vorhanden ist. */
DWORD written = 0;
ok = WriteFile(file, data, size, &written, NULL) && written == size;
CloseHandle(file);
done:
CloseHandle(dir);
return ok;
}Checkliste für Engineering & Systemsicherheit
- ✓Installieren Sie das kumulative Update vom September 2026: KB5124008 (Windows 11 24H2 und 25H2), KB5122880 (23H2), KB5124012 (26H1) oder KB5122871 (Server 2025). Die behobenen Builds sind 10.0.26100.9445, 10.0.26200.9445, 10.0.22631.7582, 10.0.28000.2954 und für Server 2025 10.0.26100.33438.[1]
- ✓Erfassen Sie in jedem Dienst, der als SYSTEM oder Administrator läuft, jeden Aufruf von CreateFileW, DeleteFileW, MoveFileExW, CopyFileW und SetFileSecurityW, dessen Pfad unter %ProgramData%, %TEMP%, C:\Users oder einem anderen für Benutzer beschreibbaren Ort liegt, und verlangen Sie für jeden ein Review.
- ✓Öffnen Sie Verzeichnisse mit FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, lehnen Sie solche mit gesetztem FILE_ATTRIBUTE_REPARSE_POINT ab und halten Sie das Handle ohne FILE_SHARE_DELETE offen, solange Sie darin arbeiten.[6], [9]
- ✓Prüfen Sie das Ziel vor dem Schreiben mit GetFinalPathNameByHandleW auf dem offenen Handle; verlassen Sie sich nie auf den selbst zusammengesetzten Pfad-String.[7]
- ✓Verwenden Sie in gemeinsam genutzten Verzeichnissen CREATE_NEW (oder FILE_CREATE mit NtCreateFile) statt CREATE_ALWAYS, damit eine vorhandene Datei oder ein Link den Vorgang abbrechen lässt, anstatt überschrieben zu werden.[8]
- ✓Legen Sie Arbeitsverzeichnisse von Diensten mit einer expliziten DACL an, die nur SYSTEM und Administrators Schreibrechte gibt, und lassen Sie Installer-Tests fehlschlagen, wenn icacls Schreibrechte für Users oder Authenticated Users zeigt.[10]
- ✓Führt ein Dienst Dateioperationen im Auftrag eines Aufrufers aus, wechseln Sie in dessen Identität (RpcImpersonateClient, ImpersonateNamedPipeClient), damit der Zugriff gegen sein Token geprüft wird und nicht gegen das von SYSTEM.
- ✓Alarmieren Sie, wenn Prozesse von Standardbenutzern Junctions oder Mount Points unter %ProgramData% oder %windir% anlegen; das ist im Normalbetrieb selten und der typische Beginn von Link-Following-Angriffen.
- ✓Erstellen Sie die Datei relativ zum geprüften Verzeichnis-Handle mit
NtCreateFileundFILE_CREATE; öffnen SiestagingDir\namenach der Verzeichnisprüfung niemals erneut über einen zusammengesetzten Pfad.[8]
Quellen
- Microsoft Security Response Center — CVE-2026-81963, Rechteausweitung im Windows Update Stack
- CVE-2026-81963 — CVE-Eintrag
- NVD — CVE-2026-81963
- CISA — Katalog Known Exploited Vulnerabilities
- MITRE CWE-59: fehlerhafte Link-Auflösung vor dem Dateizugriff
- Microsoft Learn — CreateFileW
- Microsoft Learn — GetFinalPathNameByHandleW
- Microsoft Learn — NtCreateFile (directory-relative names)
- Microsoft Learn — Reparse points and file operations
- Microsoft Learn — GetSecurityInfo (owner and DACL)
- MITRE CWE-284: Improper Access Control
- MITRE CWE-367: Time-of-check Time-of-use (TOCTOU) Race Condition