Sudo Policy Fixes and Fails – Importance of auditing your sudoers policy files.

Wait, what?  Yes.  That is correct.  This week is skipping the SSH series to begin discussions on Sudo policy review.  We will return to the SSH series soon, but I really, really, really want the next post to cover the use of token devices (using the Yubikey 4 for the first discussion on this,) and I’m simply not prepared for it.  I’ve run into several road blocks on getting my new key programmed, all of which will be covered when I write that post.

Since I don’t want to skip a day of content, I decided to introduce the next major topic I’ll go into after wrapping up the SSH series.

Sudo isn’t the only privilege elevation policy engine available.  It isn’t even the only open source privilege elevation policy engine.  It is, however, one of the most popular, and powerful in its own right.  However, it is also one of the most easily misconfigured tools, and this can (and does) lead to very dangerous policy.

For our first foray into what does and does not constitute “Bad Sudo,” we will look at one of the most overlooked utilities provided by the sudo package: sudoedit.

Before we discuss “sudoedit,” we should look at the problem of granting elevated privileges to editors in general.

Let’s start with the classic “edit a file with vi” entry.

Cmnd_Alias EDITFILE = /usr/bin/vi /path/to/file
someuser ALL=(ALL) EDITFILE

The user “someuser” now has permission to call /usr/bin/vi to edit the file /path/to/file as root.  When this happens, sudo calls the /usr/bin/vi command as the root user.  Why is this dangerous?  The “vi” editor allows for calling out to the shell to execute commands.  You can do this by hitting the escape key, then “:!/path/to/bad/command.”

There is a tag that is often used to try to suppress this command from being able to do harm.  The NOEXEC tag can often be seen in configurations where this was attempted.

Cmnd_Alias EDITFILE = /usr/bin/vi /path/to/file
someuser ALL=(ALL) NOEXEC: EDITFILE

Unfortunately, this is a bandaid that may or may not work as intended.  It relies on interrupting a program that was built with dynamically linked libraries.  It also relies on the sudo command itself being compiled with the NOEXEC support built in.  If the command in question were “ed” instead of “vi” (or on older systems, “/bin/vi” instead of “/usr/sbin/vi” where “/bin/vi” was often statically compiled so that it could be used to help repair a bad /etc/fstab for boot issues, and /usr wasn’t mounted properly) this would be useless.  The tag would do nothing to prevent calling out to the shell.

Now let’s look at the correct way to handle this.

Cmnd_Alias EDITFILE = sudoedit /path/to/file
someuser ALL=(ALL) EDITFILE

As you can see, instead of calling “/usr/bin/vi” we call “sudoedit” to modify that file.  What does this do?  It’s simple.  The user will call “sudoedit /path/to/file” instead of “sudo vi /path/to/file.”  The sudoedit command will then obtain elevated privilege to access the file, make a copy of it to a temp file, then open an editor for the user AS THAT USER.  This means in our example, that the editor will be called as if “someuser” had called it himself.  The user can call out to the shell for command execution all day, but it will only run those commands without any more privilege than the user already had.

How does sudoedit know which editor to use?  From the man pages:

The editor specified by the policy is run to edit the temporary files.  The sudoers policy uses the SUDO_EDITOR, VISUAL and EDITOR environment variables (in that order).  If none of SUDO_EDITOR, VISUAL or EDITOR are set, the first program listed in the editor sudoers(5) option is used.

So we need to be sure to set a policy of allowing a handful of editors for our users, and then clean up any policy that is granting access directly to editors to fix bad policy.  In order to do this, we need to set a Defaults directive to list the available permissible editors.

Defaults editor="/usr/bin/vi:/usr/bin/emacs:/bin/ed:/usr/bin/nano"
Cmnd_Alias EDITFILE = sudoedit /path/to/file
someuser ALL=(ALL) EDITFILE

This will let users use either vi, emacs, ed, or nano, depending on preference. There is an “env_editor” option, but if it is set, it lets users set any editor they like. This could be something that isn’t actually an editor, so the safe thing to do is just give the list of approved editors in the option I listed, instead.

I will cover some more “gotchas” like this eventually, but I’m hoping I get all of the kinks worked out of my Yubikey adventure before next week, so I can get back to the SSH posts, first.

I hope this was useful to some of you!

Leave a Reply

Your email address will not be published. Required fields are marked *