
ProFTPD 1.3.9d - Alto - Remoto - Crash - RewriteMap int:utf8trans overflow BSS
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · proftpd-rewrite-utf8trans
Write-up: https://abraxaslabs.tech/research/proftpd-rewrite-utf8trans
Classe: Crash Raggiungibilità: Remota
ProFTPD 1.3.9d (f59f248) - ProFTPD (proftpd.org)
Il contrib mod_rewrite include RewriteMap int:utf8trans. Quel builtin copia un argomento FTP del client (fino a CommandBufferSize, 512 KiB) in due buffer BSS da 1024 slot senza alcun limite sulla destinazione. Un lungo nome STOR ASCII provoca un WRITE global-buffer-overflow di ASan di dimensione 8. Il processo figlio della sessione termina in modo anomalo. Il daemon resta attivo. Classe Crash. Non RCE.
| ID | nessuna CVE al momento |
| Classe | Crash |
| Raggiungibilità | Remota (argomento FTP passato 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 se la RewriteRule è pre-auth. Il laboratorio ha usato STOR dopo il login, quindi PR:L è corretto per quella esecuzione (AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H). |
| Prodotto | ProFTPD |
| Affetto | 1.3.9d (f59f248e26bdfa514443e42bf72a145641df635d) contrib mod_rewrite |
| Auth | il laboratorio usa STOR autenticato. Una RewriteRule pre-auth su USER o simile sarebbe PR:N. |
| Licenza | GNU Affero GPL v3.0 |
| Laboratorio | solo 127.0.0.1 |
RewriteEngine è disattivato finché non viene configurato. Il pattern documentato è RewriteRule (.*) ${map:$1}. Una volta che una RewriteRule passa l'argomento del client attraverso int:utf8trans, una chiave più lunga di 1024 byte causa un overflow di due buffer statici nel processo figlio della sessione.
| Metodo | Sink | Privilegio |
|---|---|---|
| Comando FTP il cui argomento è la chiave della mappa utf8trans, lunghezza > 1024 | rewrite_utf8_to_ucs4 poi utf8_val[i] = ucs4_longs[i] | Disponibilità (dimostrata in laboratorio): crash del processo figlio della sessione. ASan: global-buffer-overflow WRITE of size 8, poi ABORTING. Prefork: un nuovo login funzionava ancora; il daemon restava attivo. Uno STOR breve di 200 byte ASCII sopravviveva. L'integrità dei BSS rewrite vicini è dedotta e dipende dal layout del compilatore. |
| RIP / esecuzione di codice | nessuna rivendicata | Escluso. Nessun payload. Classe Crash. Non RCE. |
Impianto di RewriteMap in .ftpaccess | CONF_DYNDIR | Escluso. RewriteMap non è consentito in .ftpaccess. |
shell prg: | nessun tipo di mappa simile | Escluso. La FIFO è I/O per righe. |
Dimostrato in laboratorio vs dedotto: il WRITE ASan di dimensione 8, l'abort del processo figlio della sessione, il controllo con argomento breve che sopravvive e il login dopo il trigger sono dimostrati in laboratorio. RIP/RCE non è rivendicato.
Issue 2173 ha corretto l'OOB di un byte di int:unescape su questo pin. Questo residuo è int:utf8trans. Builtin diverso. Bug diverso.
Ho fissato il tag v1.3.9d di proftpd/proftpd. Il raccolto di CVE del 2026 e le issue pubbliche di GitHub ancora presenti in quel tarball (2170, 2173, 2175, 2180, 2095, 2256, 2286, 2319, 2330, 2301) erano la lista da saltare. Il core FTP predefinito con il basic.conf di esempio non mi ha dato un Crit/High non pubblicato. Il contrib rewrite sì.
rewrite_map_int_utf8trans (contrib/mod_rewrite.c) ha:
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 scrive un unsigned long per ogni byte ASCII senza alcun limite. PR_TUNABLE_CMD_BUFFER_SIZE è 512 KiB. L'issue 2173 ha già corretto l'unescape. Questa mappa non era inclusa in quella correzione.
Vicoli ciechi: considerare la 2173 come questo bug; dichiarare RIP perché ASan ha segnalato WRITE di dimensione 8; sperare che .ftpaccess potesse iniettare RewriteMap. Il primo è una funzione diversa. Il secondo è comunque un Crash. Il terzo è CONF_DYNDIR.
ASan insieme alla libcrypt standard provoca SIGSEGV su PASS prima del sink di rewrite. Il laboratorio precarica un piccolo stub crypt(3) così il login funziona. Quello stub non è un exploit.
python3 proftpd-rewrite-utf8trans-Abraxas-Labs.py
o:
cd lab
./run.sh
Loopback 127.0.0.1:18740 più passive 18741-18750. Progetto Compose proftpd-rewrite-utf8trans. Witness PROFTPD-REWRITE-UTF8TRANS-WITNESS. L'immagine è una build ASan di 1.3.9d mod_rewrite. Il controllo STOR di 200 byte ASCII riesce. Lo STOR di 2048 byte ASCII è un ASan global-buffer-overflow WRITE di dimensione 8 e il processo figlio della sessione termina in modo anomalo. Un nuovo login dopo il trigger funziona ancora.
SUCCESS PROFTPD-REWRITE-UTF8TRANS asan=global-buffer-overflow write=yes child-dead=yes PROFTPD-REWRITE-UTF8TRANS-WITNESS
Limita la lunghezza di destinazione di rewrite_utf8_to_ucs4 a PR_TUNABLE_BUFFER_SIZE-1. Interrompi la scrittura oltre ucs4_longs / utf8_val. Rifiuta o tronca una chiave di mappatura che non rientra.
f59f248e26bdfa514443e42bf72a145641df635d)contrib/mod_rewrite.c rewrite_utf8_to_ucs4 / rewrite_map_int_utf8transint:unescapeGNU Affero GPL v3.0. Vedi LICENSE. Solo laboratorio loopback. Nessuna garanzia.