Vulnerabilità in OpenSMTPD che consente di eseguire codice remoto con privilegi di root

Nel progetto in evoluzione del server di posta OpenBSD OpenSMTPD è stata rilevata vulnerabilità critica (CVE-2020-7247), che consente di eseguire comandi shell da remoto sul server con i privilegi dell'utente root. La vulnerabilità è stata rilevata durante un audit di follow-up condotto da Qualys Security (il precedente audit di OpenSMTPD è stato effettuato nel 2015, e la nuova vulnerabilità è presente da maggio 2018). Il problema risolto è stato corretto nella versione OpenSMTPD 6.6.2. Si raccomanda a tutti gli utenti di installare urgentemente l'aggiornamento (per OpenBSD, la correzione può essere installata tramite syspatch).

Sono state proposte due varianti di attacco. La prima variante funziona con la configurazione predefinita di OpenSMTPD (accettazione delle richieste solo da localhost) e consente di sfruttare il problema localmente, quando l'attaccante ha la possibilità di accedere all'interfaccia di rete locale (loopback) sul server (ad esempio, nei sistemi di hosting). La seconda variante appare nel caso di configurazione di OpenSMTPD per accettare richieste di rete esterne (server di posta che accetta email da terze parti). I ricercatori hanno preparato un prototipo di exploit che funziona con successo sia con la versione di OpenSMTPD inclusa in OpenBSD 6.6, sia con la versione portabile per altri sistemi operativi (testato in Debian Testing).

Il problema è causato da un errore nella funzione smtp_mailaddr(), chiamata per verificare la correttezza dei valori nei campi "MAIL FROM" e "RCPT TO", che definiscono il mittente / destinatario e sono trasmessi durante la connessione al server di posta. Per controllare la parte dell'indirizzo email che precede il simbolo "@", nella funzione smtp_mailaddr() viene chiamata la funzione
valid_localpart(), che considera ammissibili (MAILADDR_ALLOWED) i seguenti caratteri: "!#$%&’*/?^`{|}~+-=_", in conformità ai requisiti RFC 5322.

Tuttavia, l'effettivo escaping della stringa è effettuato nella funzione mda_expand_token(), che sostituisce solo i caratteri "!#$%&’*?`{|}~" (MAILADDR_ESCAPE). In seguito, la stringa preparata in mda_expand_token() viene utilizzata quando si chiama l'agente di consegna (MDA) tramite il comando 'execle("/bin/sh", "/bin/sh", "-c", mda_command,…'. Nel caso di inserimento di un'email in mbox tramite /bin/sh viene eseguito il comando "/usr/libexec/mail.local -f %%{mbox.from} %%{user.username}", dove il valore "%{mbox.from}" include i dati escaped dal parametro "MAIL FROM".

La sostanza della vulnerabilità è che smtp_mailaddr() ha un errore logico, per cui nel caso venga passato un dominio vuoto nell'email, la funzione restituisce un codice di verifica positivo, anche se la parte dell'indirizzo prima di "@" contiene caratteri non validi. Successivamente, durante la preparazione della stringa nella funzione mda_expand_token(), non tutti i possibili caratteri speciali della shell vengono escapati, ma solo i caratteri speciali ammissibili nell'indirizzo email. Così, per eseguire il proprio comando è sufficiente utilizzare nel campo locale dell'email il carattere ";" e uno spazio, che non appartengono al set MAILADDR_ESCAPE e non vengono escapati. Ad esempio:

$ nc 127.0.0.1 25

HELO professor.falken
MAIL FROM:<;sleep 66;>
RCPT TO:<root>
DATA
.
QUIT

Dopo questa sessione, OpenSMTPD avvierà tramite shell il comando durante la consegna in mbox

/usr/libexec/mail.local -f ;sleep 66; root

Le possibilità di attacco sono limitate dal fatto che la parte locale dell'indirizzo non può superare i 64 caratteri, e i caratteri speciali ‘$’ e ‘|’ vengono sostituiti con “:” durante l'escaping. Per eludere questa limitazione, è stato utilizzato il fatto che il corpo dell'email viene trasmesso dopo l'esecuzione di /usr/libexec/mail.local tramite il flusso di input, cioè con manipolazioni dell'indirizzo si può avviare solo il comando interprete sh e utilizzare il corpo dell'email come un insieme di istruzioni. Poiché all'inizio dell'email sono indicati gli header SMTP, per saltarli si suggerisce di usare il comando read in un ciclo. L'exploit funzionante assume approssimativamente la seguente forma:

$ nc 192.168.56.143 25

HELO professor.falken
MAIL FROM:<;for i in 0 1 2 3 4 5 6 7 8 9 a b c d;do read r;done;sh;exit 0;>
RCPT TO:<root@example.org>
DATA
#0
#1

#d
for i in W O P R; do
echo -n "($i) " && id || break
done > /root/x."`id -u`"."$$"
.
QUIT

Fonte: opennet.ru

Acquista hosting affidabile per siti web con protezione DDoS, server VPS VDS 🔥 Acquista hosting affidabile per siti web con protezione DDoS, server VPS VDS | ProHoster