Onderzoekers vinden remote code execution-bug in OpenSMTPD-implementatie

Beveiligingsonderzoekers hebben een lek ontdekt in de e-mailimplementatie OpenSMTPD. Daarmee is het mogelijk om op afstand rootcommands uit te voeren in het onderliggende besturingssysteem. OpenSMTPD draait op veel Linux-distributies.

Het lek werd ontdekt door onderzoekers van beveiligingsbedrijf Qualys. De kwetsbaarheid krijgt een 'severe'-rating in de code CVE-2020-8794. De fout zit in de standaardconfiguratie van OpenSMTPD, dat in veel serverbased Unix-systemen zoals FreeBSD en Fedora zit. Het lek kan worden uitgebuit door een mail te sturen waar een bounce op komt. De manier waarop de mta_io()-functie vervolgens wordt geparsed, kan worden uitgebuit om van een afstand code uit te voeren op een server.

Er zijn twee manieren om de kwetsbaarheid uit te voeren. Dat kan client side op afstand doordat OpenSMTPD mail van lokale gebruikers naar remote servers stuurt. Een aanvaller die controle heeft over zo'n server, kan daardoor shellcommands uitvoeren op het systeem. Er kan ook een serversideaanval plaatsvinden door OpenSMTPD te laten crashen en opnieuw op te laten starten.

Voor OpenBSD-versies van ná mei 2018 is het mogelijk de shell-commando's met roottoegang uit te voeren. Voor oudere versies kunnen normale shell-commando's worden uitgevoerd. Er is inmiddels een patch beschikbaar voor het lek. De onderzoekers zeggen een proof-of-concept te hebben gemaakt. Ze brengen dat woensdag pas naar buiten om systeembeheerders de kans te geven hun systemen bij te werken.

Door Tijs Hofmans

Nieuwscoördinator

26-02-2020 • 10:41

35 Linkedin

Submitter: TheVivaldi

Reacties (35)

35
34
23
4
0
5
Wijzig sortering
De fout zit in de standaardconfiguratie van OpenSMTPD, dat in veel serverbased Unix-systemen zoals FreeBSD en Fedora zit.
OpenSMTPd is niet standaard aanwezig in FreeBSD, maar wel beschikbaar als package en port.
OpenSMTPd maakt deel uit van het OpenBSD project, ik vermoed dat de schrijver naar OpenBSD wou refereren ipv FreeBSD?
De ontwikkelaar van OpenSMTPD heeft een mooi achtergrond stuk over de geschiedenis van de kwetsbaarheid. Erg boeiende materie!

https://poolp.org/posts/2...smtpd-advisory-dissected/
Dit is de tweede ernstige bug in OpenSMTPD. Goed dat er wordt ge-audit en Qualys heeft goede mensen in dienst. Toch had ik beter verwacht uit de hoek van OpenBSD, veelal erg goedgeschreven degelijke software.

Merk ook op dat OpenBSD gewoon veel portable software maakt, te runnen op vele andere POSIX operating systems zoals de meeste Linuxdistributies. Voorbeeld: OpenSSH.

Exim had in het verleden ook een aantal ernstige RCE kwetsbaarheden, maar dat verwacht je ook iets meer omdat het uit de wetenschappelijke koker komt wellicht en niet per se altijd de beste defensieve code of architectuur naar voren komt.

Zelf gebruik ik vooral Postfix. Mij niet bekend of die wel een goede gelijksoortige audit heeft gehad.
OpenSMTPD is expres ontworpen/simpel gehouden om makkelijk ge-audit te kunnen worden, terwijl Postfix meer een alleskunner is en daardoor mss moeilijk te auditen. (ook @Tubby)

Maar goed, Postfix is oud en populair en daarmee ook grondig "battle-tested".
Het is al een tijd lang soort van uitontwikkeld (maw er worden ook weinig nieuwe bugs geintroduceerd).
Kijk je naar de CVE lijst dan hebben ze nauwelijks security issues.
Ik kan me er niet druk over maken :)
Tja, postfix is geschreven door een one-eyed mathematician. Ik zet mijn geld op Wietse !
Exim heeft ook wel degelijk een focus op security. Maar een zeer krachtige mailer is ook een lomp grote codebase.

De enige die serieus rigoreus vanuit security ontwikkeld is was qmail na een lange periode van issues rond sendmail.
Er is nog steeds een ongeclaimde bounty: https://cr.yp.to/qmail/guarantee.html (d.J. Bernstein).
Postfix heeft een met qmail vergelijkbare architectuur. met behoorlijke privilege separation.
Bijna off-topic, maar misschien interessant: Recent is er een talk geweest over de veiligheid van OpenBSD:
https://www.youtube.com/watch?v=3E9ga-CylWQ , https://isopenbsdsecu.re/
Hoe kan het dat je commando's als root uit kunnen voeren dan (op OpenBSD na mei 2018)? Normaal gesproken draai je je SMTP server toch niet als root? Ik draai zelf postfix, dat start volgens mij als root, maar downgrade dan z'n eigen privileges?

Ik zou in ieder geval zelf geen enkele service die aan het internet hangt als root willen draaien.
De services die daadwerkelijk de poort open houden moeten als root-user draaien. Alleen root mag poorten onder de 1024 openen.
Je zal met de meeste software zien dat ze zelf kindprocessen openen voor de daadwerkelijke afhandeling van taken, maar het moederproces is altijd degene die de poorten onder de 1024 open houden.

Op mijn server op dit moment:
# pstree 9576 -pus
systemd(1)───master(9576)─┬─pickup(29845,postfix)
├─qmgr(9578,postfix)
└─tlsmgr(10103,postfix)

# netstat -anp|grep 9576
tcp 0 0 XXX.XXX.XXX.XXX:25 0.0.0.0:* LISTEN 9576/master
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 9576/master
...
PID 9576 (het master proces) draait als root, en de kinderprocessen pickup,qmgr en tlsmgr draaien als gebruiker 'postfix'. Het master proces zal in de praktijk alle taken direct delegeren aan de kindprocessen, maar als er dus een fout zit in het master-proces en er dus een taak niet wordt gedelegeerd, dan kan je dus dit soort dingen krijgen.

Je ziet bovenstaand voorbeeld voor elk proces dat wil werken met poorten onder de 1024 (Apache, dovecot, noem ze maar op)

Voorbeeld met Apache:
# netstat -anp|grep httpd
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 5713/httpd
...
# pstree -pus 5713
systemd(1)───httpd(5713)─┬─httpd(5714,apache)─┬─{httpd}(5755)
│ ├─{httpd}(5756)
│ ├─{httpd}(5757)
│ ├─{httpd}(5758)
│ └─{httpd}(5759)
├─httpd(5715,apache)─┬─{httpd}(5716)
│ ├─{httpd}(5717)
│ ├─{httpd}(5718)
Edit: Bovenstaande gemeld te hebben, is het in principe onder Linux (en volgens mij UNIXen ook, maar dat weet ik niet zeker) wel mogelijk om bepaalde programma's toegang te geven om als niet-root gebruiker lage poorten te laten openen door middel van 'capabilities'

Zo zou je bijvoorbeeld met
# setcap CAP_NET_BIND_SERVICE=+eip /usr/sbin/httpd
httpd die rechten kunnen geven, maar aangezien het daar niet op ontworpen is, is dat denk ik niet verstandig om te doen.
Voor meer info: http://man7.org/linux/man-pages/man7/capabilities.7.html

[Reactie gewijzigd door lenwar op 26 februari 2020 12:06]

De services die daadwerkelijk de poort open houden moeten als root-user draaien. Alleen root mag poorten onder de 1024 openen.
Iets wat we 15 jaar geleden in Solaris 10 oplosten met least-privileges (zie bv. https://blogs.oracle.com/solaris/locking-down-apache-v2). Weet het, het is geen Linux of Open-Source of zo en dus niet cool maar... het loste dit probleem wel op. Waarom gebeurt dat niet in andere OS'sen?
Bedankt voor de info :)
Ik kende dit helemaal niet van Solaris (ook nooit in detail naar gekeken moet ik eerlijk bekennen). Ik weet dat AIX ook dergelijke mechanismen kent. Linux-achtige OSen kennen dit inderdaad helaas niet. (Zoals er zo veel aan te merken is op Linux-achtige systemen voor enterprise doeleinden)
mogelijk moet je ook een kijken naar capabilities... vergelijkbaar met privileges van Solaris.
Daarnaast kent linux ook andere security models zoals MAC. (mogelijk bekender als SELinux).
Daar heeft elk subject (een gebruiker) en elk object (een bestand, poort, what ever) een bepaalde toegangs mogelijkheid: mag wel open, read, write, close maar niet lseek, chmod, chown, unlink... in een bepaalde context(applicatie)
dan mag je een bestand openen/lezen/beschrijven en sluiten en precies alleen dat.
Alle goede/foute opmerkingen worden dan gelogged.
Er is een matrix gemaakt van welke subjecten, welke objecten op welke manier gebruikt mogen worden.

Dat gaat nog een stukje verder. In die context is root gewoon een simpele nono net als alle andere gewone gebruikers. (UID==0, GID==0 niet nergens meer speciaal)
Dat gaat nog een stukje verder. In die context is root gewoon een simpele nono net als alle andere gewone gebruikers. (UID==0, GID==0 niet nergens meer speciaal)
Dat had je ook in Trusted Solaris (later dacht ik Trusted Extensions). Je creeerde labels (bv. privileged, secret, top-secret) en kon zo een root-user hebben met laag label en die dus niks kon doen. :D

Het mooie wat ik mij van Least Privileges herinner is dat dit eigenlijk best simpel en intuitief op te zetten was. Zelfde voor RBAC (Role Based Access Control). Solaris is (naar mijn indruk) zo goed als dood maar ik denk nog vaak terug aan die tijd en de mooie technologien die in Solaris zaten en die ik, als ik nu met Linux werk, enorm mis. Linux heeft misschien iets soortgelijks (meestal zelfs meerdere soortgelijke wat al een probleem is) maar vaak minder handig.
Kijk eens naar FreeBSD. Daar is veel moois uut Solaris heen geport.
Draai het nog maar > 10 jaar :-D
Persoonlijk voel ik mij veel beter thuis bij FreeBSD dan bij Linux. Linux blijft voor mij een uit de hand gelopen hobby-project. FreeBSD is conservatiever.
Oracle heeft Solaris idd omgelegd. en er is noot een positieve reactie gekomen op een vraag om Solaris evt dan maar te opensourcen...
1 van de fouten voor mij was Ian Murdock er bij betrekken. OpenSolaris/Indiana werd niks voor niks intern (ja...) project Iandiana genoemd. Roadmap/toekomst is lange tijd onzeker geweest en dat was de doodsteek. Solaris 11 bevat(te) heel veel mooie dingen die heel goed in elkaar zitten en waar ik in Linux maar kan van droom maar spijtig genoeg heeft iedereen ondertussen voor Linux gekozen.
Oracle heeft er een handje van gehad om allerlei Sun projecten te mollen...

Feitelijk hebben ze Sun gekocht voor de java..., maar dachten ermee weg te komen om onderhoud eens per jaar te blijven doen zoals ze min of meer gewend waren. En hebben bereikt dat java in ieder geval als browser applicatie hulpmiddel om zeep is geholpen. En door het fantastische security beleid de move naar openjava hebben gestart.
OpenOffice is zo lang in limbo geweest dat de opensource kant van de ontwikkelaars een fork met libreoffice begonnen zijn. Daarna is openoffice min of meer in het moeras aan het zakken.
Spark was al snel gesneuveld,
Solaris was gewoon de volgende in het rijtje..

De aankoop van Sun was duidelijk meer dan Oracle aankon.
En waarom bijvoorbeld geen port forwarding?

25 -> 2525.
Dat is ook een optie, maar niet erg gebruikelijk :)

Ik ga er vanuit dat je doelt op een firewall die inkomend verkeer op poort 25 doorstuurt naar poort 2525 waar het betreffende proces reageert toch? Zolang je buiten je 'net.ipv4.ip_local_port_range' reeks blijft zal dat in de praktijk weinig tot geen problemen opleveren.

Ik heb het nooit geprobeerd, maar ik zou niet weten of een stuk software als Apache httpd of Postfix wil opstarten als niet-root gebruiker.
Voor apache dat werkt gewoon..
Waarom niet gewoon proberen?... Het kan wel zijn dat sommige paden in configuraties wat aanpassing behoeven.

postfix et.al is wat listiger, bij aflevering met mbox formaat files moet de aflevering onder de naam van de ontvanger lopen. hetzelfde geldt voor afhandeling van .forward etc. etc.
Als je postfix laat afleveren aan dovecot of cyrus-imap oid en alleen IMAP / POP toestaat moet ook dat kunnen werken. Of een andere MDA die het volledige aflever traject organiseert. De MDA heeft dan wel root-rechten.
Volgens mij kun je prima starten als root (of met de juiste capabilites) en daarna je privileges droppen terwijl je de socket open houdt.

Het lijkt me waarschijnlijker dat dit gedaan is om (makkelijker?) mails te kunnen afleveren bij alle gebruikers van het systeem. Zonder speciale rechten mag je vast niet zomaar in de mailspool van andere gebruikers schrijven :)
Nope. De socket blijft aan het proces hangen, en een proces kan niet van eigenaar veranderen. De overige processen handelen de mail aflevering af. Standaard als gebruiker 'postfix' die in de groep 'mail' zit, die groepseigenaar is van /var/spool/mail, waar een setgid bitje op zit.

Effectief dient het proces dat de socket opent ervoor te zorgen dat alle data naar één-op-één over de kinderprocessen verdelen.
Je zegt het zo stellig dat ik ging twijfelen of ik me niet vergiste.
https://xkcd.com/386/
Een half uurtje later een toy example waarmee je het zelf kunt checken:
https://github.com/syzzer...aster/priv-port-drop-priv
Inderdaad, zoals tweaknico inmiddels al meldt, op basis van setuid/setgid. setuid(2) stelt expliciet:
"The setuid() function checks the effective user ID of the caller and if it is the superuser, all process-related user ID's are set to uid. After this has occurred, it is impossible for the program to regain root privileges."
mogelijk je even verdiepen in setuid() & setgid() calls .
https://linux.die.net/man/2/setuid
en
https://linux.die.net/man/2/setgid

voor root processen zijn het trapdoors.
Uitgebreide uitleg! Ik ben bekend met de privileged ports, maar snapte niet hoe een proces bij root komt, zo dus.
Een willekeurig programma kan een specifieke owner/group krijgen van tijdens het starten.

Jij kan niet lopen grutten in de /etc/passwd & /etc/shadow files.
het /bin/passwd programma heeft een paar speciale bitjes aanstaan waarmee de owner van het bestand ook op het lopende sub proces gezet worden.
-rws--x--x 1 root root 60352 3 nov 01:55 /bin/passwd
Ofwel: iedereen die /bin/passwd wordt "uid=0 aka root" tijdens het laten lopen van /bin/passwd
OpenSMTPD (en andere MTA's) hebben root privileges nodig om o.a "privileged ports" te kunnen "openen" onder Linux (Zie https://www.w3.org/Daemon...tion/PrivilegedPorts.html)
Vergeet ook niet dat open OpenBSD de opensmtpd compleet is dichtgetimmerd met pledge(2). Het is meer een gevaar voor niet-OpenBSD systemen.
Ik ben niet bekend met OpenBSD en dus plege, maar volgens het Qualys rapport is de exploit ook werkbaar in OpenBSD:

https://www.qualys.com/20...smtpd-default-install.txt
We developed a simple exploit for this vulnerability and successfully
tested it against OpenBSD 6.6 (the current release), OpenBSD 5.9 (the
first vulnerable release), Debian 10 (stable), Debian 11 (testing), and
Fedora 31. At OpenBSD's request, and to give OpenSMTPD's users a chance
to patch their systems, we are withholding the exploitation details and
code until Wednesday, February 26, 2020.
Ik heb ook even gekeken naar wat Pledge inhoudt: https://man.openbsd.org/pledge (grofweg) en het lijkt er op dat de meeste processen die op lage poorten draaien de 'exec' promise nodig zullen hebben (om kindprocessen op te starten)
Allows a process to call execve(2). Coupled with the proc promise, this allows a process to fork and execute another program. If execpromises has been previously set the new program begins with those promises, unless setuid/setgid bits are set in which case execution is blocked with EACCES. Otherwise the new program starts running without pledge active, and hopefully makes a new pledge soon.
En dit is precies waar de fout zat.

(( n.b. als ik er helemaal naast zit word ik graag gecorrigeerd :) ))
Subprocessen inheriten de promises niet, die moeten dat opnieuw pledgen. Dus dat een child-process door een exec promise is afgetrapt, betekent dat niet dat deze dan gewoon lukraak mag execve(2)en.

Nou hebben de andere BSD's en Linuxen dit vangnet niet, en daar moet je het zeker gaan patchen. Als je OpenSMTPd op OpenBSD draait, heeft dat niet zo'n haast (maar toch wel doen, want bij een broken pledge killt OpenBSD gewoon je mailserver, dus sowieso DoS mogelijkheid).
Het lijkt me dat Capsicum(4) op FreeBSD dit wel zou moeten kunnen opvangen.
Nadat de socket geopend is kunnen ook de privileges omlaag door een andere UIC te kiezen.
Dan is alleen tijdens het eerste starten van een daemon root access nodig voor bv. logging activere, privileged ports en daarna downgrade naar normale gebruiker).

De resultaten van een listen() komen toch door, de socket is immers al open. Na open() / socket() is er geen access check meer.

Op dit item kan niet meer gereageerd worden.

Tweakers maakt gebruik van cookies

Tweakers plaatst functionele en analytische cookies voor het functioneren van de website en het verbeteren van de website-ervaring. Deze cookies zijn noodzakelijk. Om op Tweakers relevantere advertenties te tonen en om ingesloten content van derden te tonen (bijvoorbeeld video's), vragen we je toestemming. Via ingesloten content kunnen derde partijen diensten leveren en verbeteren, bezoekersstatistieken bijhouden, gepersonaliseerde content tonen, gerichte advertenties tonen en gebruikersprofielen opbouwen. Hiervoor worden apparaatgegevens, IP-adres, geolocatie en surfgedrag vastgelegd.

Meer informatie vind je in ons cookiebeleid.

Sluiten

Toestemming beheren

Hieronder kun je per doeleinde of partij toestemming geven of intrekken. Meer informatie vind je in ons cookiebeleid.

Functioneel en analytisch

Deze cookies zijn noodzakelijk voor het functioneren van de website en het verbeteren van de website-ervaring. Klik op het informatie-icoon voor meer informatie. Meer details

janee

    Relevantere advertenties

    Dit beperkt het aantal keer dat dezelfde advertentie getoond wordt (frequency capping) en maakt het mogelijk om binnen Tweakers contextuele advertenties te tonen op basis van pagina's die je hebt bezocht. Meer details

    Tweakers genereert een willekeurige unieke code als identifier. Deze data wordt niet gedeeld met adverteerders of andere derde partijen en je kunt niet buiten Tweakers gevolgd worden. Indien je bent ingelogd, wordt deze identifier gekoppeld aan je account. Indien je niet bent ingelogd, wordt deze identifier gekoppeld aan je sessie die maximaal 4 maanden actief blijft. Je kunt deze toestemming te allen tijde intrekken.

    Ingesloten content van derden

    Deze cookies kunnen door derde partijen geplaatst worden via ingesloten content. Klik op het informatie-icoon voor meer informatie over de verwerkingsdoeleinden. Meer details

    janee