Vulnerabilitatea în OpenSMTPD care permite executarea codului de la distanță ca root

În serverul de mail dezvoltat de proiectul OpenBSD OpenSMTPD identificat vulnerabilitate critică (CVE-2020-7247) care vă permite să executați de la distanță comenzi shell pe un server cu drepturi de utilizator root. Vulnerabilitatea a fost identificată în timpul unui re-audit efectuat de Qualys Security (auditul anterior al OpenSMTPD a fost tinut în 2015, iar noua vulnerabilitate este prezentă din mai 2018). Problemă eliminat în lansarea OpenSMTPD 6.6.2. Toți utilizatorii sunt sfătuiți să instaleze de urgență actualizarea (pentru OpenBSD, patch-ul poate fi instalat prin syspatch).

Au fost propuse două tipuri de atac. Prima opțiune funcționează în configurația implicită OpenSMTPD (primind solicitări doar de la localhost) și vă permite să exploatați problema local, atunci când atacatorul este capabil să acceseze interfața de rețea locală (loopback) pe server (de exemplu, pe sistemele de găzduire) . A doua opțiune apare atunci când OpenSMTPD este configurat să accepte solicitări de rețea externă (un server de e-mail care acceptă e-mailuri terțe). 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 o versiune portabilă pentru alte sisteme de operare (realizată în Debian Testing).

Problema este cauzată de o eroare în funcția smtp_mailaddr(), care este apelată pentru a verifica corectitudinea valorilor din câmpurile „MAIL FROM” și „RCPT TO” care determină expeditorul/destinatarul și care sunt transmise în timpul conexiunii la serverul de mail. Funcția smtp_mailaddr() este apelată în smtp_mailaddr() pentru a verifica partea din adresa de e-mail care vine înaintea caracterului „@”.
valid_localpart(), care ia în considerare caracterele „!#$%&'*/?^`{|}~+-=_” ca fiind permise (MAILADDR_ALLOWED), conform cerințelor RFC 5322.

În acest caz, șirul este direct eliminat în funcția mda_expand_token(), care înlocuiește doar caracterele „!#$%&'*?`{|}~” (MAILADDR_ESCAPE). Mai mult, șirul pregătit în mda_expand_token() este utilizat atunci când se apelează agentul de livrare (MDA) folosind comanda „execle(”/bin/sh”, „/bin/sh”, „-c”, mda_command,…'. mail la mbox prin /bin/sh, se rulează linia „/usr/libexec/mail.local -f %%{mbox.from} %%{user.username}”, unde valoarea „%{mbox.from}” include date scăpate din parametrul „MAIL FROM”.

Esența vulnerabilității este că smtp_mailaddr() are o eroare logică din cauza căreia, dacă un domeniu gol este transmis către e-mail, funcția returnează un cod de verificare reușit, chiar dacă partea din adresa de dinaintea „@” conține caractere nevalide. Mai mult, atunci când se pregătește un șir cu funcția mda_expand_token(), nu toate caracterele speciale de shell posibile sunt escape, ci doar caracterele speciale permise în adresa de e-mail. Astfel, pentru a rula comanda, este suficient să folosiți simbolul „;” în partea locală a e-mailului. și spațiu, care nu sunt în setul MAILADDR_ESCAPE și nu sunt escape. De exemplu:

$nc 127.0.0.1 25

HELO profesor.falken
POSTA DE LA:<;sleep 66;>
RCPT către:
DATE
.
PĂRĂSI

După această sesiune, OpenSMTPD, când este livrat către mbox, va rula comanda prin shell

/usr/libexec/mail.local -f ;sleep 66; rădăcină

În același timp, posibilitățile de atac 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 evita această limitare, faptul că corpul mesajului este transmis după rularea /usr/libexec/mail.local prin fluxul de intrare, adică. prin manipulare cu adresa, puteți lansa doar interpretul de comandă sh și puteți utiliza corpul scrisorii ca un set de instrucțiuni. Deoarece anteturile SMTP ale serviciului sunt specificate la începutul scrisorii, este sugerat să folosiți apelul de comandă de citire într-o buclă pentru a le ignora. Exploitația de lucru arată cam așa:

$nc 192.168.56.143 25

HELO profesor.falken
MAIL FROM:<;pentru i în 0 1 2 3 4 5 6 7 8 9 abcd;do read r;done;sh;exit 0;>
RCPT către:[e-mail protejat]>
DATE
#0
#1
...
#d
pentru i în WOPR; do
echo -n "($i) " && id || pauză
terminat > /root/x."`id -u`"."$$"
.
PĂRĂSI

Sursa: opennet.ru

Adauga un comentariu