[sf-lug] ... sudo "vs." su, SUID/SGID, ...

Michael Paoli Michael.Paoli at cal.berkeley.edu
Sat May 16 03:13:07 PDT 2020


> From: "Rick Moen" <rick at linuxmafia.com>
> Subject: Re: [sf-lug] /usr/sbin and now 'sudo -' vs 'su -'
> Date: Fri, 15 May 2020 22:13:59 -0700

> Quoting aaronco36 (aaronco36 at SDF.ORG):
>
>> At the same time, there _are_ some sysadmins who would rather
>> heatedly promote the use of 'sudo su -' for non-root users to "run
>> something in /sbin or /usr/sbin" as opposed to staying logged in as
>> the root-user via 'su -' :-|
>
> Use or non-use of sudo is actually an entirely _different_ discussion.

> I've noticed it's mostly the *buntu-oriented novices who're obsessed
> with sudo and want to discuss and debate its usage on *ix.  (For present
> discussion, I'm disregarding edge cases where sudo, used carefully, is a
> reasonable solution for particular usage models.)  Personally, I'm just
> don't find such discussions interesting.

And, defaults matter!

I think one of the reasons many who've used Ubuntu
and similar (*buntu, probably some other distros too, etc.),
and particularly heavily so and/or most familiar with it (more so than
others) is that BY DEFAULT, it creates an otherwise (mostly)
unprivileged default/initial login user, and then also sets that user up
to have sudo access to, via sudo, ... well, not just su - [root], but
typically to even directly run any command as any user and/or group.
And additionally, again, by default, having created such a user,
also generally sets up the root account with no (unmatchable) password,
so one cannot use a password to login as root or su to root from a
non-root user.
So, again, defaults matter ... folks then get used to doing, most all
the time, stuff like:
$ sudo su - ...
$ sudo su ...
$ sudo command ...
etc.
And quite to the exclusion of using su without sudo, and especially in
the case of to root - notably again, as there being by default no
matchable password for root.
So, they not only get used to that, but drink the *buntu Kool-Aid,
reading/hearing Ubuntu's and other's arguments/justifications as to why
*buntu did it that way, and tend to mostly presume all is well
and good, and it is or most likely is the "best" way.
I'm not saying there are *no* valid arguments to do it
that way ... but there are also many good reasons why
*not* to do it that way ... or not to so leverage it so
frequently (and relatively heavily/haphazardly) in that manner.

I believe also some other distros will install and behave that way by
default *if* one creates a "regular" user and does *not* set a password
for root (which, may or may not be the way the install typically
proceeds by default).

And ... judicious careful use of sudo.

sudo *can* be highly useful for judiciously allowing very select limited
additional privilege to specific user(s)/group(s), and well managing
that.

Here's recent practical example from the balug Virtual Machine (VM).

# grep '^mycert:' /etc/shadow
mycert:!*:18391:0:99999:7:::
#

We see above the user mycert not only has unmatchable password, but that
it's also locked.  So that user can never use password authentication
(as, for passwords, we're only set up for local file-based
authentication).

That user mycert can't even use sudo -l to list the commands it can
run via sudo!  And why?  Because it has unmatchable password,
thus can never pass the password authentication to even list the
sudo access.

$ id; sudo -l
uid=16914(mycert) gid=16914(mycert) groups=16914(mycert)

We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:

     #1) Respect the privacy of others.
     #2) Think before you type.
     #3) With great power comes great responsibility.

[sudo] password for mycert:

# sudo -l -U mycert | sed -ne '/may run/,$p'
User mycert may run the following commands on balug-sf-lug-v2:
     (mycert : bind) NOPASSWD: /usr/local/bin/_acme-challenge_helper
#

Above, however, we see that the user mycert can run a command with
sudo ... but only with group bind, and is able to do so without
entering a password ... which need be the case to be useful for that
user, as that user has no matchable password.

$ id; sudo -g bind /usr/local/bin/_acme-challenge_helper
uid=16914(mycert) gid=16914(mycert) groups=16914(mycert)
usage:
_acme-challenge_helper add CERTBOT_DOMAIN CERTBOT_VALIDATION
_acme-challenge_helper { del | delete } CERTBOT_DOMAIN [CERTBOT_VALIDATION]
$

Above, we see the user mycert "successfully" ran the command (well,
notwithstanding improper syntax, but passing the other portions to that
point), and having done so as group bind.

And, why set something up like that?
This prevents mycert from being able to run commands as root
(excessive), or even other user(s) (again, excessive), or to even run
arbitrary commands as the privileged group bind (which could otherwise
be able to muck about with DNS).
https://en.wikipedia.org/wiki/Principle_of_least_privilege
But rather, the only thing mycert can do as group bind, is run that
one exact specified command ... and that command in fact even much
further restricts exactly what can and can't be done as group bind.
So, for example, this allows user mycert, via sudo, to be able to
use a key that can be read by group bind, but
can't be read by most all users (just user root and group bind can read
it).  It also prevents the mycert user from being able to directly read
the key and do more arbitrary things with it (like sharing it or giving
it away, yes, sometimes users share passwords and access credentials
when they shouldn't ... but if they can't access those credentials,
that's one less thing they can do wrong), but is instead, restricted
just to how that program uses access to be able to read the key,
to allow the mycert user, via sudo, to be able to only do what's
appropriate and needed (for that user's function), with that modest
bit of selective restrictive privilege escalation.

And alternatives?  Use su, and give mycert a password, to use su
to access some other ID - notably root, or a user with group of bind?
Well, then mycert would, via that, be able to do anything that
user/group could do, rather than just being restricted to the needed.
What if we created a Set User ID (SUID) or Set Group ID (SGID)
program, so the mycert user could execute that?  Well, several problems
and disadvantages with that.  First of all, SUID/SGID programs are
notoriously difficult to write securely ... many many many repeated
security problems come up from folks writing such and not getting it
exactly right and secure (heck, the very first security vulnerability
I ever informed a vendor of, was a security issue they had in a
SGID (or SUID? - I'd have to review some ancient dead tree system
logs to confirm) program.  Also, any user executing that would
have that same privilege - so it wouldn't restrict to the mycert
ID (though there would be other ways we could do that).
It also wouldn't have as good a logging/audit trail.

Anyway, those are some bits about when and how to use sudo,
and how it can be very well used for some purposes.

Now lets look at one of the far too common ways folks screw up
way too commonly with sudo.  And here, I'm not talking about
e.g. *buntu, where they orient folks to using sudo to root
far too frequently and without careful regard (that's
another issue, and not exactly "sudo"'s fault).

Insecure sudoers configuration.  Writing good secure sudoers
configurations isn't a trivially easy task.  Far far far too often,
folks screw it up badly - opening (often huge) security holes.

I'll give some examples - though they're really quite countless (but
probably countable if one just classified them all into categories of
security mistakes and counted up just the categories).

So, somebody wants user to be able to edit a file, needs escalated
privileges to do so.  How not to do it:
user ALL= /usr/bin/vi /path/to/some/file
Even if the target user and/or group, or host from which it can be run,
are specified differently, we still have a problem.
Why?
Let's say it's set up like that,
user does:
$ sudo vi /path/to/some/file
And then in their vi session, does:
:sh
They're then at a shell, able to do anything that user/group can do.

Here's one I bumped into years ago.  Production problem.
I've got user login to the host, but my sudo access to root wasn't set
up there (it should've been).  It's o'dark-thirty-something in the
morning.  Do I have to go wake someone else up?  Need to get to root to
investigate/fix the particular issue.  Let's see ... what sudo access
do I have? ...
$ sudo -l
...
I have sudo access to get to a monitoring/alarming user.
Okay, I sudo to that user.  And what sudo access does that user have?
$ sudo -l
...
Among other things, I spot that user also has passwordless sudo access
to run find as root, with arbitrary options/arguments ... cool, I'm in!:
$ sudo find / \( -type d -exec /bin/sh \; -prune \) -o -prune
#

More recently, silly environment, somebody thinks they're being
"secure".  It's a laptop with a Unix/Linux/BSD-like operating system.
$ sudo -l
... and I get a huge long list of ... mostly what it disallows (!).
So, like everything but ... about 100 or 200 commands or so.  Easy
Peasy.
$ cp /bin/sh foo && sudo `pwd -P`/foo
# visudo
And I "fix" that silly insecurity annoyance.
Yeah, they wouldn't want me to run sh or bash or csh or tcsh or zsh ...
or any of about 100 or 200 or so other commands.
Oh, but they're fine with me running any arbitrary command/string they
didn't think of to exclude ... "oops".
Heck, it's so common a mistake, sudoers(5) even explicitly calls it out:
"
SECURITY NOTES
    Limitations of the '!' operator
      It is generally not effective to ``subtract'' commands from ALL using the
      '!' operator.  A user can trivially circumvent this by copying the
      desired command to a different name and then executing that.  For exam-
      ple:
"

So, yes, one needs be careful writing sudoers entries.  They really
ought go through proper security review.  I know about 80 to 90% of the
time, in pretty much all the environments I've ever worked in, when I
look over the sudoers stuff, I find holes that generally allow one to
directly or indirectly run arbitrary commands as the user/group
permitted by the sudoers entry.  Pretty much all?  Yeah.
Those that really should've been much more secure, had a significantly
lower percentage and better review process, but I'd typically find
a very non-trivial percentage still had such flaws - and this was well
past review when they were already in production.

And, compared to SUID/SGID?  Sure, sudoers, relatively hazardous -
notably easy to goof and allow the unintended.  But generally compared
to SUID/SGID, sudoers is about a decimal order of magnitude or more
"safer" (more clear/intuitive) and "harder" to screw up than  
SUID/SGID.  So, for
the most part, sudo(ers) is generally much better/safer than doing some
custom one-off SUID/SGID binary.  In general, with SUID/SGID binary,
almost *any* bug is often easily turned into a SUID/SGID exploit,
that's a key reason why they're much more hazardous and much less
likely to be secure, not to mention also, to securely write a
SUID/SGID program, one must not only be highly competent in
the language it's written in, but also highly competent in
the security of that language, and SUID/SGID in the context
of the security of that language.  Way too easy to screw up,
and far too many do.  Okay, maybe not *quite* as hard as
inventing a new secure encryption algorithm from scratch that
the world has never seen before, but ... still, way too
easy to screw up - and far too many do - and yes, even including
most quite competent well skilled programmers often making such
mistakes and introducing such security bugs.

And, have I ever written SUID/SGID programs?  Yes, I've written exactly
one.  Does it have SUID/SGID exploits in it?  Probably.  It has at
least one bug, and that might well be exploitable.  Once in a great
while, sometimes the program will crash.  That shouldn't happen.  It's
a bug - possibly an exploitable one.  And there may be other bugs -
potentially exploitable - that I'm unaware of.

So, back to (more secure) sudoers.  There's lots to watch out for,
but the key general things, is there *any* way at all possible the
invoking user can leverage what's specified in sudoers to be able to
do other than what one is intending to restrict them to.  E.g. are there
shell escapes or other ways to "get out of" the program?  Can they
manipulate file(s) to gain privilege.
E.g. let's say you give a user ability to run tcpdump as root via sudo.
You know, tcpdump not only can read network traffic, and including
generally localhost network traffic (stuff that's never "on the wire",
and generally presumed a secure location / network transport/location),
but tcpdump can also write files and read files.  Did you also
fully restrict that?  What if they read privileged files (say, like keys
or access tokens), virtual/memory "files", or write to files that
control security access?  What about options/arguments and what
you allow?  Can those be manipulated to do unintended things?
Random-ish and related: remember, Unix (and quite similar Linux ...),
filenames can be composed of any ASCII characters, except for the ASCII
NUL character.  How will those things behave if they contain spaces,
newlines, characters special to shell or perhaps other program(s),
etc.?  One needs (or at least ought) be quite careful, and preferably
have things appropriately security reviewed.

"Of course" if one is merely using sudo(1) as a gateway to get to
particular user/group IDs, and not restrict what they can then do with
those IDs, well, then the security situation may be quite a bit simpler.




More information about the sf-lug mailing list