vsftpd 3.0.5 - Alto - Remoto - Privilegio residuo - FTPS data accetta qualsiasi ticket ripreso
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · vsftpd-ssl-data-any-ticket
Classe: Privilegio residuo Raggiungibilità: Remota
vsftpd 3.0.5 (Chris Evans) - tarball ufficiale SHA-256 26b602ae454b0ba6d99ef44a09b6b9e0dfa7f67228106736df1f278c70bc91d3. Le build FTPS delle distribuzioni compilano #define VSF_BUILD_SSL (il tarball stock ha #undef) e gli operatori impostano ssl_enable=YES. La modalità standalone listen=YES è il default compilato e di esempio.
ssl_accept (ssl.c:494-501) è il bind del canale dati. Verifica solo SSL_session_reused(). Non c'è alcun confronto di SSL_SESSION con l'SSL di controllo. L'SSL dati non ha USER/PASS FTP. In modalità standalone ssl_init viene eseguito nel listener prima della fork (main.c:147-150), quindi i figli ereditano un unico SSL_CTX. SSL_CTX_set_timeout(INT_MAX) (ssl.c:182-186). Nessun SSL_OP_NO_TICKET. SSL_session_reused()==1 significa che questo ClientHello trasportava un ticket che questo processo è in grado di decifrare, non che si tratti della sessione di controllo di Alice.
La pagina man di require_ssl_reuse afferma che il riuso prova lo stesso master secret del canale di controllo. Il codice C no. Diverso dal kill-on-reuse-fail di Tim Kosse in 3.0.3 (ftpdataio.c:184-187), che comunque risponde 522 a un handshake nuovo e non impedisce a Mallory di riprendere un ticket emesso su un controllo diverso.
Questo residuo è un singolo trasferimento FTPS. Non è un bypass di USER/PASS, non è una shell e non è un'evasione dal chroot.
| ID | nessuna CVE al momento |
| Classe | Privilegio residuo (il canale dati FTPS accetta qualsiasi ticket ripreso) |
| Raggiungibilità | Remota (PASV stesso IP; NAT condiviso è AC:H) |
| CWE | CWE-345, CWE-287 |
| CVSS | Alto: 7.4 CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N |
| Prodotto | vsftpd (Chris Evans) |
| Affetto | 3.0.5 con VSF_BUILD_SSL e ssl_enable=YES. require_ssl_reuse=YES (default). require_cert=NO (default) |
| Auth | Mallory: solo AUTH TLS (nessun USER/PASS). Alice: PBSZ/PROT P anonimo |
| Licenza | GNU Affero GPL v3.0 |
| Lab | 127.0.0.1:18700 controllo, PASV 18701-18708. Compose vsftpd-ssl-data-any-ticket |
Chi: un altro client FTPS (o un attaccante on-path) che condivide l'IP sorgente di Alice. L'accept PASV richiede comunque l'IP del peer di controllo (privops.c:212-218) a meno che non sia attivo pasv_promiscuous. Il NAT condiviso è il caso FTPS tipico che require_ssl_reuse è stato aggiunto per fermare. Mallory non effettua mai il login.
| Metodo + sink | Privilegio |
|---|---|
Mallory solo AUTH TLS, TLS 1.2 ALPN ftp, conserva il session ticket dall'SSL_CTX del listener. Alice anonima PBSZ/PROT P, PASV, RETR secret.txt bloccato in get_remote_transfer_fd fino all'accept. Mallory PASV stesso IP, riprende il suo ticket (session_reused=True) | Decifra quel singolo RETR. Lab: socket dati 35 byte VSFTPD-SSL-DATA-ANY-TICKET-WITNESS. Alice 150 poi 226. Il TLS di controllo e la password restano di Alice. Nessuna esplorazione di directory oltre quel trasferimento. |
ssl_accept; il lab era furto di RETR)| Metodo + sink | Privilegio |
|---|---|
Stessa ripresa del ticket mentre Alice esegue STOR / APPE | Il file nominato di Alice viene scritto dal plaintext TLS di Mallory, con l'uid di Alice / uid ftp anonimo, all'interno del chroot esistente |
| Metodo + sink | Privilegio |
|---|---|
Handshake dati nuovo (reused=False) | 522 session reuse required (kill di 3.0.3). Quel trasferimento muore. Il controllo resta di Alice |
privops.c:212-218)require_cert=YES più un certificato presentato vincola i digest SHA-256PROT C in chiaro per utenti locali (force_local_data_ssl default YES)ssl_init dal listener)ftp (vsftpd va in FATAL)Ho fissato il tarball ufficiale di vsftpd 3.0.5 invece di un mirror GitHub o di un albero Debian/Fedora. Diciannove ricerche nel sorgente. La ricerca SSL si è fermata su ssl_accept: il riuso è un booleano, non un bind a questo SSL_SESSION di controllo. L'SSL_CTX del listener più la durata del ticket INT_MAX sono il resto.
Vicoli ciechi: ALPN deve essere ftp o vsftpd va in FATAL (il residuo ALPACA di 3.0.4 è già chiuso). Il link su Arm64 richiedeva -lpam -lcap espliciti; lo script stock vsf_findlibs.sh sonda solo i percorsi x86_64. Considerare il kill di Tim Kosse in 3.0.3 come questo bug: risponde 522 a un handshake nuovo sul fd dati di Alice e non ferma un ticket emesso su un controllo diverso.
cd lab
./run.sh
3.0.5 ufficiale con #define VSF_BUILD_SSL. Conf: ssl_enable=YES, allow_anon_ssl=YES, force_anon_logins_ssl=YES, force_anon_data_ssl=YES, require_ssl_reuse=YES, require_cert=NO. Docker su loopback. Due client con lo stesso IP. Ticket TLS 1.2. ALPN ftp. Controllo 127.0.0.1:18700, PASV 18701-18708. Compose vsftpd-ssl-data-any-ticket. Witness VSFTPD-SSL-DATA-ANY-TICKET-WITNESS. Ultima riga:
SUCCESS vsftpd-ssl-data-any-ticket reused-ticket=yes fresh-handshake=522 VSFTPD-SSL-DATA-ANY-TICKET-WITNESS
Vincolare l'SSL_SESSION dei dati all'SSL_SESSION di controllo (confrontare session id / master secret). Limitare la durata del ticket alla connessione di controllo. Oppure SSL_OP_NO_TICKET più una cache di sessione indicizzata per controllo. ProFTPD 1.3.9d confronta le sessioni.
Il canale di segnalazione al vendor è [email protected] (security.appspot.com/vsftpd.html). Non aprire una issue pubblica su GitHub su alcun mirror di vsftpd.
Abraxas Labs - abraxaslabs.tech - github.com/abraxas - @abraxas_null - [email protected]