Back to /comp/

While I prefer and stick to OpenBSD most often these days (and thus doas(1)): I still support sudo on Linux for work (as well as on OSX for my work workstation).

This is simply to make some notes of style-guide and some fun "Gotchas" that I've encountered along the way with sudo.

Contents

Gotchas

Shell-globbing

Case

Provided users with the ability to modify zone files on an antique DNS system (via sudo). They'll be editing files in /var/named/master and can ls, grep, vi, rcsdiff, co, & ci any files within that directory; however, their users cannot read into /var/named/master/ otherwise.

Failure

A user tried to do the following - in order to find any DNS/TXT record where the MAC address of a device was noted:

sudo /bin/grep '52:54:00' /var/named/master/*

Seems reasonable, right? This System Administrator has the permissions to run /bin/grep with any arguments on this machine. So why didn't this work? Instead, the user received the error:

grep: /var/named/master/*: No such file or directory

Diagnosis

What ends up being passed to sudo is:

COMMAND=/bin/grep 52:54:00 /var/named/master/*

Here, the shell-glob provided to this bash session in: "/var/named/master/*" was expanded at the user-level before the command is handed-to sudo. Shell globs are always evaluated first and this must be considered with sudo.

Back to Contents

When command doesn't exist

Case

Provided a remote user the ability to run /usr/sbin/dmidecode with particular arguments.

Failure

User could not run that command with those arguments. Listing available-commands-on-host with "sudo -u user -l" showed the command as allowed.

Diagnosis

The command of /usr/sbin/dmidecode was indeed allowed to be run on these OpenBSD hosts by our _nrpe user; however, the command lives in /usr/local/sbin/dmidecode (which was also explicitly listed in the policy).

Since the other team's code was referencing only /usr/sbin/dmidecode (which does not exist) - the command was refused.

Final: I wish sudo used an error more akin to "command not present" or "no such file" rather than:

Jan 24 08:26:34 randommachine sudo:    _nrpe : command not allowed ; TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/usr/sbin/dmidecode -s bios-release-date

Of course, none of this would have mattered if they'd a) checked path in their code b) properly done a sudo -l /usr/sbin/dmidecode -s bios-release-date and verified its output (even if just with &&) before trying to run it with that path.

Back to Contents

Negating Spaces in wildcards

Case

User wants to be able to run /usr/bin/yum install myproject-* where * is the ever-changing version/sub/path number

Failure

If user is provided with:

user host=(root) /usr/bin/yum install myproject-*

They would be able to call: "sudo -u root /usr/bin/yum install myproject-*" they would also be able to install non-approved software via: "sudo -u root /usr/bin/yum install myproject-1.21 nmap openssh-server", etc.

Diagnosis

Initial diagnosis points to removing the ability to use space in the glob. This appears to be able to be done by negating the character field with [!\ ] or [! ]. However, since more characters are needed, the * is still necessary, which would result in something like:

user host=(root) /usr/bin/yum install myproject-[! ]*

While that appears reasonable and would work for a true regular expression, in glob-form that still would allow the user to pass in "myproject-1.2 nmap", etc.

True Fix

In order to support the development cycle for this user, instead we allow their wildcard/glob match, but then specifically also deny the ability to call the same with a space anywhere in it:

user host=(root) /usr/bin/yum install myproject-*, ! /usr/bin/yum install myproject-*[ ]*

Back to Contents

Dangerous Commands

Basic danger: cp

So it's well known that giving root-access to use "cp" is extremely dangerous with sudo, but to review, a quick example:

$ sudo -l
User may run the following commands on this host:
(root) /usr/local/bin/backupmodify.py
(root) /bin/cp
$ sudo cp /usr/local/etc/backupconfig.cfg /usr/local/etc/backupconfig.cfg.old
$ sudo cp /usr/local/etc/backupconfig.cfg.new /usr/local/etc/backupconfig.cfg

While we may all agree this is not preferred, likely you can recognize that things similar to this exist in many machines. Now for the problem:

$ sudo cp /usr/local/bin/backupmodify.py /tmp/.hidden
$ sudo cp /bin/bash /usr/local/bin/backupmodify.py
$ sudo /usr/local/bin/backupmodify.py
$ sudo cp /tmp/.hidden /usr/local/bin/backupmodify.py

...and privilege escalation!

Certainly the above was just possible because the user could also run backupmodify.py, right?

$ sudo -l
User may run the following commands on this host:
(root) /bin/cp
$ cat ~/my-custom-sudoers
myuser ALL=(root) NOPASSWD: ALL
$ sudo cp ~/my-custom-sudoers /etc/sudoers

...and privilege escalation!

Back to Contents