În proiectul în dezvoltare OpenBSD pentru servere de email a fost identificată (CVE-2020-7247), care permite executarea de comenzi shell de la distanță pe server cu drepturile utilizatorului root. Vulnerabilitatea a fost descoperită în timpul unui audit suplimentar realizat de compania Qualys Security (auditul anterior pentru OpenSMTPD în 2015, iar noua vulnerabilitate este prezentă din mai 2018). Problema este în versiunea OpenSMTPD 6.6.2. Toți utilizatorii sunt sfătuiți să instaleze urgent actualizarea (pentru OpenBSD, corecția poate fi instalată prin syspatch).
Sunt propuse două variante de atac. Prima variantă funcționează în configurația implicită a OpenSMTPD (acceptând doar cereri de la localhost) și permite explozionarea problemei local, atunci când atacatorul are acces la interfața de rețea locală (loopback) pe server (de exemplu, în sistemele de găzduire). A doua variantă apare în cazul configurării OpenSMTPD pentru a accepta cereri externe de rețea (server de email care acceptă emailuri externe). Cercetătorii au pregătit un prototip de exploit, care funcționează cu succes atât cu varianta OpenSMTPD din OpenBSD 6.6, cât și cu versiunea portabilă pentru alte sisteme de operare (testată în Debian Testing).
Problema este cauzată de o eroare în funcția smtp_mailaddr(), apelată pentru a verifica corectitudinea valorilor din câmpurile „MAIL FROM” și „RCPT TO”, care definesc expeditorul/''. destinatarii și sunt transmise în timpul conexiunii cu serverul de email. Pentru a verifica partea adresei de email, care se află înainte de caracterul „@”, în smtp_mailaddr() este apelată funcția
valid_localpart(), care consideră permise (MAILADDR_ALLOWED) caracterele „!#$%&’*\/¿' documentei, conform cerințelor RFC 5322.
În acest context, escaparea directă a șirului se face în funcția mda_expand_token(), care înlocuiește doar caracterele „!#$%&’*?`{|}~” (MAILADDR_ESCAPE). Ulterior, șirul pregătit în mda_expand_token() este utilizat în apelul agentului de livrare (MDA) folosind comanda 'execle("\/bin\/sh", "\/bin\/sh", "-c", mda_command,…'. În cazul în care mesajul este pus în mbox prin \/bin\/sh, se execută șirul „\/usr\/libexec\/mail.local -f %%{mbox.from} %%{user.username}”, unde valoarea „%{mbox.from}” include datele escapate din parametrul „MAIL FROM”.
Vulnerabilitatea constă în faptul că smtp_mailaddr() are o eroare logică, ceea ce face ca, în cazul în care se transmite un domeniu gol în email, funcția să returneze un cod de verificare de succes, chiar dacă partea adresei dinaintea „@” conține caractere invalide. Apoi, în pregătirea șirului de către funcția mda_expand_token(), nu sunt evitate toate caracterele speciale posibile din shell, ci doar caracterele speciale permise în adresa de email. Astfel, pentru a-și executa comanda, este suficient să folosească în partea locală a emailului caracterul „;” și spațiul, care nu fac parte din setul MAILADDR_ESCAPE și nu sunt evitate. De exemplu:
$ nc 127.0.0.1 25
HELO professor.falken
MAIL FROM:<;sleep 66;>
RCPT TO:<root>
DATA
.
QUIT
După această sesiune, OpenSMTPD va lansa comanda prin shell la livrarea către mbox
/usr/libexec/mail.local -f ;sleep 66; root
În acest sens, posibilitățile atacului sunt limitate de faptul că partea locală a adresei nu poate depăși 64 de caractere, iar caracterele speciale ‘$’ și ‘|’ sunt înlocuite cu „:” la evadare. Pentru a ocoli această limitare, s-a utilizat faptul că corpul mesajului este transmis după ce /usr/libexec/mail.local este lansat prin fluxul de intrare, adică prin manipularea adresei se poate lansa doar interpretul de comenzi sh și se poate folosi corpul mesajului ca un set de instrucțiuni. Deoarece la începutul mesajului sunt specificate antetele SMTP, pentru a le sări se sugerează utilizarea apelului comenzii read într-un ciclu. Exploitul funcțional arată aproximativ astfel:
$ 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
Sursa: opennet.ro
