
Reproduce la RCE no autenticada de ClamAV en ZendTo y la escalada de privilegios a root en un laboratorio autorizado, con destino Docker fijado, verificación con cierre ante fallos, salida vinculada a nonce y limpieza.
Este directorio es un paquete de reproducción independiente, para laboratorio autorizado, de la cadena de ejecución de código de ZendTo a ClamAV sin cuenta y de su continuación separada mediante Smarty/cron root con el perfil predeterminado. Incluye:
El PoC inicial ejecuta un comando seleccionado por el llamante como la cuenta de servicio estándar clamav. La variante opcional continúa ese punto de apoyo sin cuenta hasta un comando seleccionado por el llamante como root. Ambas usan id por defecto, rechazan la ruta literal /root/flag y devuelven la salida vinculada a un nonce a través de HTTPS.
Las relaciones vulnerables de grupo, directorio, Smarty y cron root son las predeterminadas del paquete/instalador Debian de ZendTo. No obstante, la alcanzabilidad de root depende del entorno: este fixture positivo exacto usa un volumen /var/zendto con ext4, FFI/POSIX/exec de PHP CLI funcionales y un proceso clamd sin confinamiento. La aplicación de AppArmor/SELinux o de semánticas de sistema de archivos incompatibles puede bloquear la continuación en otra instalación por lo demás estándar.
Use esto solo en el fixture desechable incluido o en otro sistema que esté explícitamente autorizado a probar.
El objetivo exacto y autoritativo es un artefacto local, intencionadamente sin versionar, en:
image/zendto-installer-systemd-debian12.tar.zst
Git ignora los archivos de imagen de Docker. Antes de una regresión exacta, coloque una copia local autorizada en esa ruta; scripts/setup.sh requiere su SHA-256 e ID de imagen registrados. source-recipe/README.md documenta cómo se construyó y capturó la imagen derivada del instalador. Una nueva construcción desde repositorios de paquetes en vivo es útil para probar la topología, pero no se presupone byte-idéntica al objetivo fijado.
El script de configuración y el entrypoint del contenedor rechazan cualquier discrepancia con el siguiente perfil:
| Componente | Valor exacto probado |
|---|---|
| ID de imagen Docker | sha256:de6d2f06ca04943362a9bdec5026e808448953728f31bd926343a4ed2ca2ef7c |
| ZendTo | 6.15-8 |
| Paquete ClamAV/libclamav | 1.4.3+dfsg-1~deb12u2 |
| libclamav | libclamav.so.12.0.3, SHA-256 55e3cd94…027c |
| Build ID de libclamav | e6427ab62146ee3001fe463d12e797e9d25bf81a |
| glibc | 2.36-9+deb12u14, SHA-256 6b4a4535…421 |
| base de datos principal | v63, SHA-256 0b2182d2…365 |
| base de datos diaria | v28082, SHA-256 cddbcccf…906 |
| base de datos bytecode | v339, SHA-256 6d4aa01f…ffb |
| clamd | MaxThreads 12, IdleTimeout 30, Restart=no |
| ciclo de vida | clamav-daemon.socket habilitado, systemd como PID 1 |
| runtime web | Apache 2.4.68, PHP 8.2.32 |
| postura MAC | fixture Docker privilegiado sin confinamiento |
| puente a root | clamav estándar en www-data; /var/zendto root:www-data 0775 |
| consumidor root | cron de limpieza root estándar, cada hora en el minuto 25 |
| caché Smarty | zendto.conf compilado determinista con Smarty 4.5.4 |
| sistema de archivos de intercambio | volumen nombrado /var/zendto con ext4 |
Los valores completos están en PROFILE.json.
Esto es más sólido que fijar solo la versión del paquete ClamAV. La construcción del asignador también depende de glibc, del tráfico del parser dirigido por CVD, de los ajustes de los workers y de la biblioteca objetivo exacta. FreshClam está deshabilitado en la imagen capturada, y el arranque falla si daily.cvd se ha desviado o si ha aparecido un daily.cld.
El contenedor de investigación actualmente de larga duración en el espacio de trabajo padre no es el fixture limpio: las pruebas posteriores deshabilitaron su formulario de remitente externo y actualizaron su base de datos diaria. Esos cambios están excluidos intencionadamente aquí. Este paquete usa la línea base limpia contra la que se demostró la ejecución nativa.
/sys/fs/cgroupzstd, Python 3 con venv, un compilador de C, file y GNU readelfEl objetivo comparte el kernel del host y la implementación de ASLR. El comportamiento de mapeo dependiente del kernel sigue siendo, por tanto, una variable de portabilidad.
Solo un fixture systemd debe compartir el espacio de nombres de cgroup del host a la vez. En la máquina de investigación original, detenga el fixture antiguo sin eliminarlo:
docker stop zendto-installer-systemd-native
Más tarde puede restaurarse con docker start zendto-installer-systemd-native.
Desde este directorio:
./scripts/verify-bundle.sh
./scripts/setup.sh
El script de configuración:
.venv con las dependencias Python fijadas del PoC;/var/zendto e inicia systemd; yrenameat2(RENAME_EXCHANGE) ejecutada como clamav.Los endpoints predeterminados son solo de bucle local:
http://127.0.0.1:18084/
https://127.0.0.1:18447/
El certificado es autofirmado. El PoC usa deliberadamente verify=False en cada petición HTTP. Se pueden seleccionar otros puertos de bucle local antes de la configuración:
export ZENDTO_HTTP_PORT=19084
export ZENDTO_HTTPS_PORT=19447
./scripts/setup.sh
Use las mismas variables de entorno para los comandos posteriores de Compose/asistentes.
Compruebe el objetivo en cualquier momento:
./scripts/verify-target.sh
docker compose ps
La línea base limpia del instalador tiene:
allowExternalUploads = TRUE
confirmExternalEmails = TRUE
captcha = google
Sus valores de CAPTCHA y correo son marcadores de posición del instalador, por lo que el archivo intacto no puede entregar realmente el correo público de verificación. Las pruebas de regresión nativas representaron solo ese paso de aplicación completado con una fila AuthData equivalente de remitente externo. El código objetivo, los paquetes, el escáner, los permisos y la ruta de explotación no fueron parcheados.
Cree esa única fila de laboratorio y un archivo de token con modo 0600 con:
./scripts/mint-lab-auth.py [email protected]
El valor del token se suprime y se almacena en:
.lab/upload-auth-token.txt
Este asistente local no es una afirmación de que una implementación con subida externa deshabilitada pueda explotarse de forma remota. Si el formulario público de remitente externo está deshabilitado, el PoC se detiene correctamente antes de ClamAV incluso cuando se proporciona un archivo de token.