
CVE-2025-8088
Aviso: Este conteúdo é apenas para fins educacionais e de pesquisa. Não use estas informações para atividades maliciosas.
Hoje, vamos mergulhar fundo em uma fascinante vulnerabilidade de travessia de caminho, rastreada como CVE-2025-8088. Essa vulnerabilidade permite que um atacante grave um arquivo arbitrário em qualquer local do sistema da vítima quando ela extrai um arquivo RAR especialmente criado. O que torna esse exploit particularmente interessante é sua abordagem "shotgun" para garantir a entrega bem-sucedida do payload, independentemente de onde o usuário extraia o arquivo.
Este post detalhará a técnica usada no Prova-de-Conceito (PoC) em Python fornecido para criar o arquivo .rar malicioso.
O objetivo final deste PoC é clássico e eficaz: persistência. Ao explorar a vulnerabilidade de travessia de caminho, o exploit visa colocar um payload (payload.bat) na pasta de Inicialização do Windows (AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup). Qualquer executável ou script colocado aqui será executado automaticamente na próxima vez que o usuário fizer login, concedendo ao atacante acesso persistente.
O script Python automatiza um processo de várias etapas para construir o exploit.rar final. Vamos percorrer sua lógica.
A primeira coisa que o script faz é preparar os componentes:
payload.bat é criado. Este é o arquivo malicioso que queremos colocar na máquina da vítima.PAYLOAD = "@echo off\necho Payload executed!\npause\n"
file1.txt, file2.txt, etc.). Esses arquivos servem a dois propósitos: eles fazem o arquivo parecer legítimo e, mais importante, agem como transportadores do nosso payload oculto.def create_files() -> Tuple[List[Path], Path]:
# ...
for i in range(NUM_DEPTHS):
decoy = Path(f"{DECOY_FILE_PREFIX}{i+1}.txt")
" X " * 200) é definida. Este placeholder será embutido nos metadados do arquivo e, posteriormente, substituído pelo nosso caminho malicioso.Esta é uma parte fundamental da técnica. Em vez de nomear um arquivo com um caminho de travessia, o script usa um recurso do sistema de arquivos NTFS chamado Fluxos de Dados Alternativos (ADS). O ADS permite "ocultar" dados dentro de um arquivo existente.
O script anexa o payload.bat como um ADS a cada arquivo isca. O nome desse fluxo é onde o placeholder é usado. Em essência, ele cria caminhos de arquivo que se parecem com isto para o sistema de arquivos:
file1.txt:XXXXXXXXXXXXXXXXXXXX...
O conteúdo do payload.bat agora está secretamente armazenado dentro de file1.txt.
def attach_ads(decoy: Path, placeholder: str):
"""Attach payload to decoy as Alternate Data Stream"""
ads_path = f"{decoy}:{placeholder}"
with open(ads_path, "wb") as f:
f.write(Path("payload.bat").read_bytes())
Em seguida, o script localiza a ferramenta de linha de comando Rar.exe no sistema e a usa para criar um arquivo base legítimo (base.rar). Este arquivo contém todos os arquivos isca, que agora carregam secretamente o payload em seus Fluxos de Dados Alternativos.
Neste ponto, base.rar é um arquivo perfeitamente válido e não malicioso. O WinRAR pode extraí-lo sem qualquer problema e criará os arquivos isca com seus nomes ADS longos e estranhos.
def create_base_rar(rar_exe: str, decoys: List[Path]) -> Path:
# ...
subprocess.run(
f'"{rar_exe}" a -ep -os "{base_rar}" {files}',
# ...
)
É aqui que o exploit se torna astuto e resiliente. O atacante não sabe onde a vítima extrairá o arquivo. Será em C:\Users\victim\Downloads? C:\? D:\Temp?
Para superar essa incerteza, o script gera uma lista de diferentes strings de travessia de caminho, cada uma com uma profundidade diferente:
..\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\payload.bat..\..\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\payload.bat..\..\..\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\payload.batA ideia é que, ao fornecer múltiplas profundidades, pelo menos uma delas conseguirá navegar do diretório de extração de volta à raiz do sistema de arquivos (como C:\) e, em seguida, até a pasta de Inicialização de destino.
def build_relative_paths() -> List[str]:
"""Generate paths with different traversal depths"""
paths = []
for depth in range(1, NUM_DEPTHS + 1):
paths.append(("..\\" * depth) + RELATIVE_DROP_PATH)
return paths
Este é o coração do exploit. O script abre base.rar em modo binário e realiza uma cirurgia nele.
Ele itera pela estrutura interna do arquivo, procurando o cabeçalho de cada arquivo (file1.txt, file2.txt, etc.). Dentro de cada cabeçalho, ele encontra o nome ADS do placeholder (:XXXXXXXXXXXXXXXXXXXX...) e o substitui por um dos caminhos de travessia maliciosos gerados no passo anterior.
file1.txt recebe o caminho com ..\.file2.txt recebe o caminho com ..\..\.def patch_rar(base_rar: Path, placeholder: str, relative_paths: List[str]) -> Path:
# ...
while pos + 4 <= len(data) and current_file_index < len(target_paths_utf8):
# ...
# Find the placeholder and replace it with the target path
c = patch_placeholder_in_header(hdr, placeholder_utf8, target_utf8)
# ...
Simplesmente alterar os dados do cabeçalho corromperia o arquivo. O WinRAR usa uma soma de verificação CRC32 para verificar a integridade de cada bloco de cabeçalho. Se a soma de verificação não corresponder ao conteúdo do cabeçalho, ele gerará um erro.
O PoC antecipa isso. Após aplicar o patch em um cabeçalho com o caminho malicioso, ele recalcula a soma de verificação CRC32 correta para o bloco de cabeçalho modificado inteiro e grava a nova soma de verificação no arquivo. Isso faz com que o arquivo adulterado pareça perfeitamente válido para o WinRAR.
def rebuild_all_header_crc(buf: bytearray) -> int:
"""Recalculate CRC checksums for all headers"""
# ...
while pos + 4 <= len(buf):
# ...
# Calculate CRC for the header region
region = buf[block_start + 4:header_end]
crc = zlib.crc32(region) & 0xFFFFFFFF
# Write the new CRC back into the buffer
struct.pack_into("<I", buf, block_start, crc)
# ...