from Hacker News

LPE and RCE in OpenBSD OpenSMTPD

by aquabeagle on 1/28/20, 11:41 PM with 83 comments

  • by Panino on 1/29/20, 3:08 AM

    I tested this exploit against an unpatched OpenBSD 6.6 machine and it works with the default mbox delivery, but not with maildir delivery (as hinted by the syspatch message). So if you use maildir delivery like me, you weren't exposed to this security hole. This is the sound of the world's quietest sigh of relief. I have some questions:

    Is Qualys getting paid for this excellent work, and if so, by who?

    Is there a plan to do a serious audit of execle related code in OpenBSD?

    As a longtime OpenBSD user, I gotta say that OpenSMTPD is the part of the system I'm least comfortable with from a security standpoint. Too many rewrites, mulligans, CVEs. Very little of the web howtos match the official documentation because there's so much churn, which by itself is a red flag. And even without a logic bug, I'm surprised execle was used at all here. It was unnecessary and naive. I'll be honest, I'm in the middle of transitioning from qmail to OpenSMTPD, and this bug is making me consider notqmail.

    This RCE is trivial and super bad.

  • by brynet on 1/29/20, 12:26 AM

  • by zaroth on 1/29/20, 1:43 AM

    This is such a clean and easy to read write-up on how the control flow led to the bug, and how it’s exploited.

    Of course, that’s partly because it’s so damn easy to exploit. Here’s what an exploit email actually looks like;

      $ nc 127.0.0.1 25
      220 obsd66.example.org ESMTP OpenSMTPD
      HELO professor.falken
      250 obsd66.example.org Hello professor.falken  [127.0.0.1], pleased to meet you
      MAIL FROM:<;sleep 66;>
      250 2.0.0 O.k
      ...
    
    That executes “sleep 66” as root.

    There simply must be a better way to parameterize calls to the MTA that contain remote/attacker provided input than exec’ing a shell. It should not all come down to being “absolutely sure” the input is escaped properly.

  • by angry_octet on 1/29/20, 4:38 AM

    It seems strange that people are blaming C for this. I see the real problem being that it is a unix pattern to use the shell to pass arguments to programs, even when that input is possibly malicious. Obviously doing this as root takes it from RCE to juggling with plutonium, but a non-confined non-root shell is pretty awful.

    The code seems to go out of its way to avoid using the system() call to shell out, but then does exactly what system() would do.

  • by thisrod on 1/29/20, 3:30 AM

    It's worth noting that this couldn't have happened to any mail server running on Plan 9, no matter how buggy it was.

    Mail servers should run as nobody; mail box files are, in fact, world-writable, and their permissions should reflect that. Go ahead, critique the ergonomics of C's conditional expression syntax. But first, consider that this security model for a room full of terminals in the 1970s, where permission to accept connections on port 25 is also permission to format the hard disk, is totally nuts for a network-connected computer in the 2020s.

  • by fao_ on 1/29/20, 1:57 AM

    My main question is why isn't /bin/sh being executed with -r -- restricted mode? It seems weird that a safety-critical piece of code would just call out to /bin/sh without doing that, especially on openBSD?
  • by kelnos on 1/29/20, 12:43 AM

    Ouch. The root of the issue is that they do a validity check for the local and domain part of the recipient email address. If either one (or both) is invalid, they then check to see if the domain part is empty. If it is, they replace the empty domain with the default domain, and then say it's all valid, ignoring the fact that the local part might also be invalid.
  • by codezero on 1/29/20, 12:18 AM

    I love the copious references to the 80s film WarGames in the examples :)
  • by Hello71 on 1/29/20, 1:33 AM

    the PoC can be optimized: after way too much googling, I finally found a way to consume an arbitrary number of non-empty lines without using any special characters. ironically, it uses perl.

        perl -00 -ne exit
    
    unfortunately, the first line afterwards is also eaten. this is easily remedied by inserting one junk line though instead of a slide.
  • by tene on 1/29/20, 5:57 PM

    Can anyone provide some insight into possible motivations for why the authors may have chosen to use a shell here? I'm struggling to understand what value it adds over representing mda_command as an array of strings and execving that.

    I don't mean this sarcastically; I'm genuinely curious about the motivations. The only thing I can come up with is that it's slightly more annoying to free an array of strings than it is to free a single string in C. Is that plausibly the only motivation to involve a shell here?

  • by carlhjerpe on 1/29/20, 11:17 AM

    Theo says Web facing things applications is a good place to start using rust, he proved himself right.
  • by brian_herman on 1/29/20, 2:15 AM

    Dude this rhymes... Could this be the lyrics for next Openbsd release song?
  • by LeonM on 1/29/20, 12:15 AM

    Wow, Openwall has been really at it when it comes to OpenBSD related vulns.

    First with the user authentication vulns [0], now this.

    For those running OpenBSD boxes: the patch is available through syspatch, but you may need to change /etc/updateurl to an official OpenBSD CDN, since the patch is still fresh and not yet distributed to all mirrors.

    [0] https://www.openbsd.org/errata65.html

  • by _wldu on 1/29/20, 12:25 AM

    I really wish the OpenBSD team would consider rewriting some of these internet facing services in Go. It would be much safer than C.