
ProFTPD 1.3.9d - Alta - Remoto - Crash - RewriteMap int:utf8trans desbordamiento BSS
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · proftpd-rewrite-utf8trans
Análisis: https://abraxaslabs.tech/research/proftpd-rewrite-utf8trans
Clase: Caída Alcance: Remoto
ProFTPD 1.3.9d (f59f248) - ProFTPD (proftpd.org)
El contrib mod_rewrite incluye RewriteMap int:utf8trans. Ese builtin copia un argumento FTP del cliente (hasta CommandBufferSize, 512 KiB) en dos búferes BSS de 1024 ranuras sin límite de destino. Un nombre STOR ASCII largo provoca un WRITE de global-buffer-overflow en ASan de tamaño 8. El proceso hijo de la sesión aborta. El demonio permanece activo. Clase Caída. No es RCE.
| ID | aún sin CVE |
| Clase | Caída |
| Alcance | Remoto (argumento FTP enviado a int:utf8trans) |
| CWE | CWE-120 |
| CVSS | Alto: 7.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H si la RewriteRule es pre-autenticación. El laboratorio usó STOR tras el inicio de sesión, por lo que PR:L es lo honesto para esa ejecución (AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H). |
| Producto | ProFTPD |
| Afectado | 1.3.9d (f59f248e26bdfa514443e42bf72a145641df635d) contrib mod_rewrite |
| Autenticación | el laboratorio es STOR autenticado. Una RewriteRule pre-autenticación sobre USER o similar sería PR:N. |
| Licencia | GNU Affero GPL v3.0 |
| Laboratorio | solo 127.0.0.1 |
RewriteEngine está desactivado hasta que se configura. El patrón documentado es RewriteRule (.*) ${map:$1}. Una vez que una RewriteRule envía el argumento del cliente a través de int:utf8trans, una clave de más de 1024 bytes desborda dos búferes estáticos en el proceso hijo de la sesión.
| Método | Sumidero | Privilegio |
|---|---|---|
| Comando FTP cuyo argumento es la clave del mapa utf8trans, longitud > 1024 | rewrite_utf8_to_ucs4 luego utf8_val[i] = ucs4_longs[i] | Disponibilidad (probado en laboratorio): provoca la caída del proceso hijo de la sesión. ASan: global-buffer-overflow WRITE of size 8, luego ABORTING. Prefork: un nuevo inicio de sesión seguía funcionando; el demonio permaneció activo. Un STOR corto de 200 bytes ASCII sobrevivió. La integridad de la BSS de rewrite cercana se infiere y depende del diseño del compilador. |
| RIP / ejecución de código | ninguno reclamado | Descartado. Sin payload. Clase Caída. No es RCE. |
Plantado de RewriteMap en .ftpaccess | CONF_DYNDIR | Descartado. RewriteMap no está permitido en .ftpaccess. |
Shell prg: | no existe ese tipo de mapa | Descartado. FIFO es E/S por líneas. |
Probado en laboratorio vs inferido: el WRITE de tamaño 8 en ASan, el aborto del proceso hijo de la sesión, el control con argumento corto que sobrevive y el inicio de sesión posterior al disparo están probados en laboratorio. RIP/RCE no se reclama.
Issue 2173 parcheó el OOB de un byte en int:unescape en este pin. Este remanente es int:utf8trans. Builtin distinto. Bug distinto.
Fijé el tag v1.3.9d de proftpd/proftpd. La cosecha de CVE de 2026 y los issues públicos de GitHub que aún permanecían en ese tarball (2170, 2173, 2175, 2180, 2095, 2256, 2286, 2319, 2330, 2301) eran la lista de omisión. El FTP core por defecto con el basic.conf de ejemplo no me dio un Crit/High no publicado. El contrib rewrite sí.
rewrite_map_int_utf8trans (contrib/mod_rewrite.c) tiene:
static unsigned char utf8_val[PR_TUNABLE_BUFFER_SIZE]; /* 1024 */
static unsigned long ucs4_longs[PR_TUNABLE_BUFFER_SIZE]; /* 1024 */
ucs4strlen = rewrite_utf8_to_ucs4(ucs4_longs, strlen(key), (unsigned char *) key);
rewrite_utf8_to_ucs4 escribe un unsigned long por cada byte ASCII sin límite. PR_TUNABLE_CMD_BUFFER_SIZE es de 512 KiB. El issue 2173 ya corrigió el unescape. Este mapa no estaba en esa corrección.
Pistas falsas: tratar el 2173 como este bug; afirmar RIP porque ASan indicó WRITE de tamaño 8; esperar que .ftpaccess pudiera plantar un RewriteMap. El primero es una función distinta. El segundo sigue siendo Crash. El tercero es CONF_DYNDIR.
ASan junto con la libcrypt estándar provoca SIGSEGV en PASS antes del sink de rewrite. El laboratorio precarga un pequeño stub de crypt(3) para que el login funcione. Ese stub no es un exploit.
python3 proftpd-rewrite-utf8trans-Abraxas-Labs.py
o:
cd lab
./run.sh
Loopback 127.0.0.1:18740 más pasivo 18741-18750. Proyecto de Compose proftpd-rewrite-utf8trans. Testigo PROFTPD-REWRITE-UTF8TRANS-WITNESS. La imagen es una compilación ASan de mod_rewrite de 1.3.9d. El STOR de control de 200 bytes ASCII tiene éxito. El STOR de 2048 bytes ASCII es un global-buffer-overflow WRITE de tamaño 8 en ASan y el proceso hijo de la sesión aborta. Un inicio de sesión nuevo tras el desencadenante sigue funcionando.
SUCCESS PROFTPD-REWRITE-UTF8TRANS asan=global-buffer-overflow write=yes child-dead=yes PROFTPD-REWRITE-UTF8TRANS-WITNESS
Limitar la longitud de destino de rewrite_utf8_to_ucs4 a PR_TUNABLE_BUFFER_SIZE-1. Dejar de escribir más allá de ucs4_longs / utf8_val. Rechazar o truncar una clave de mapa que no encaje.
f59f248e26bdfa514443e42bf72a145641df635d)contrib/mod_rewrite.c rewrite_utf8_to_ucs4 / rewrite_map_int_utf8transint:unescapeGNU Affero GPL v3.0. Véase LICENSE. Solo para laboratorio de loopback. Sin garantía.