
CVE-2025-8088
Descargo de responsabilidad: Este contenido es solo para fines educativos y de investigación. No utilice esta información para actividades maliciosas.
Hoy realizamos una inmersión profunda en una fascinante vulnerabilidad de recorrido de ruta, registrada como CVE-2025-8088. Esta vulnerabilidad permite a un atacante escribir un archivo arbitrario en cualquier ubicación del sistema de una víctima cuando esta extrae un archivo RAR especialmente manipulado. Lo que hace interesante a este exploit en particular es su enfoque de "dispersión" para garantizar la entrega exitosa de la carga útil, independientemente de dónde extraiga el usuario el archivo.
Esta publicación analizará la técnica utilizada en la Prueba de Concepto (PoC) en Python proporcionada para crear el archivo .rar malicioso.
El objetivo final de esta PoC es clásico y efectivo: la persistencia. Al explotar la vulnerabilidad de recorrido de ruta, el exploit busca depositar una carga útil (payload.bat) en la carpeta de Inicio de Windows (AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup). Cualquier ejecutable o script colocado aquí se ejecutará automáticamente la próxima vez que el usuario inicie sesión, otorgando al atacante acceso persistente.
El script de Python automatiza un proceso de varios pasos para construir el archivo exploit.rar final. Analicemos su lógica.
Lo primero que hace el script es preparar los componentes:
payload.bat. Este es el archivo malicioso que queremos depositar en la máquina de la víctima.PAYLOAD = "@echo off\necho Payload executed!\npause\n"
file1.txt, file2.txt, etc.). Estos archivos tienen dos propósitos: hacer que el archivo parezca legítimo y, más importante, actuar como portadores de nuestra carga útil oculta.def create_files() -> Tuple[List[Path], Path]:
# ...
for i in range(NUM_DEPTHS):
decoy = Path(f"{DECOY_FILE_PREFIX}{i+1}.txt")
"X" * 200). Este marcador se incrustará en los metadatos del archivo y luego se reemplazará con nuestra ruta maliciosa.Esta es una parte clave de la técnica. En lugar de nombrar un archivo con una ruta de recorrido, el script utiliza una característica del sistema de archivos NTFS llamada Flujos de Datos Alternativos (ADS). Los ADS permiten "ocultar" datos dentro de un archivo existente.
El script adjunta el payload.bat como un ADS a cada archivo señuelo. El nombre de este flujo es donde se utiliza el marcador de posición. En esencia, crea rutas de archivo que se ven así para el sistema de archivos:
file1.txt:XXXXXXXXXXXXXXXXXXXX...
El contenido de payload.bat ahora está almacenado secretamente 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())
A continuación, el script encuentra la herramienta de línea de comandos Rar.exe en el sistema y la utiliza para crear un archivo base legítimo (base.rar). Este archivo contiene todos los archivos señuelo, que ahora llevan secretamente la carga útil en sus Flujos de Datos Alternativos.
En este punto, base.rar es un archivo perfectamente válido y no malicioso. WinRAR puede extraerlo sin problemas y creará los archivos señuelo con sus nombres largos y extraños de ADS.
def create_base_rar(rar_exe: str, decoys: List[Path]) -> Path:
# ...
subprocess.run(
f'"{rar_exe}" a -ep -os "{base_rar}" {files}',
# ...
)
Aquí es donde el exploit se vuelve inteligente y resiliente. El atacante no sabe dónde extraerá la víctima el archivo. ¿Será C:\Users\victim\Downloads? ¿C:\? ¿D:\Temp?
Para superar esta incertidumbre, el script genera una lista de diferentes cadenas de recorrido de ruta, cada una con una profundidad 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.batLa idea es que al proporcionar múltiples profundidades, al menos una de ellas navegará con éxito desde el directorio de extracción hasta la raíz del sistema de archivos (como C:\) y luego a la carpeta de Inicio objetivo.
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 es el corazón del exploit. El script abre base.rar en modo binario y realiza una cirugía sobre él.
Itera a través de la estructura interna del archivo, buscando la cabecera de cada archivo (file1.txt, file2.txt, etc.). Dentro de cada cabecera, encuentra el nombre del marcador de posición del ADS (:XXXXXXXXXXXXXXXXXXXX...) y lo reemplaza con una de las rutas maliciosas de recorrido generadas en el paso anterior.
file1.txt recibe la ruta con ..\.file2.txt recibe la ruta con ..\..\.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)
# ...
Simplemente cambiar los datos de la cabecera corrompería el archivo. WinRAR utiliza una suma de verificación CRC32 para verificar la integridad de cada bloque de cabecera. Si la suma de verificación no coincide con el contenido de la cabecera, mostrará un error.
La PoC anticipa esto. Después de parchear una cabecera con la ruta maliciosa, recalcula la suma de verificación CRC32 correcta para el bloque de cabecera completo modificado y escribe la nueva suma de verificación de nuevo en el archivo. Esto hace que el archivo manipulado parezca perfectamente válido para 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)
# ...