Six months ago, we wrote about a risky bug in the sudo command, the Unix equivalent of Run As... on Windows.
You use sudo to run an operating system command as a different user, usually root, the all-powerful Unix administrator account.
This means that bugs in sudo are not to be sniffed at, and we were happy, back in March, to be able to praise the curators of the Sudo project for their rapid response.
The bug revisited
Our comprehensive analysis of the bug, and why the sort of programming that caused it (in-band signalling) is probably best avoided, can be summarised as follows:
- When you first use sudo, it creates a directory called /var/db/sudo/username to record when you last ran it.
- If you run sudo again within five minutes of the timestamp on /var/db/sudo/username, by default sudo doesn’t ask for your password, as a convenience.
- If you run sudo -k , it sets the timestamp back to 01 January 1970, which forces sudo to ask you for a password next time, no matter how soon you run it.
You may wonder why sudo -k resets the timestamp to 01 January 1970 (the earliest date Unix cares about, represented as zero in numeric terms), rather than simply deleting the /var/db/sudo/username directory altogether, which would be a simpler and safer approach.
The reason is that if you have never run sudo before, it doesn’t just ask for your password, but gives you a little “pep talk for newbies” first.
On OS X, it’s terribly businesslike, and looks something like this:
Linux is a bit more community oriented, and wanders into social ethics:
Without the file /var/db/sudo/username, you get the pep talk every time.
Apparently, being confronted with a helpful warning when you are no longer a newbie is considered infra dignitatem, so anyone who deliberately gives up their five-minute sudo privilege window with the -k option is treated with kid gloves.
Thus the special meaning of 01 January 1970: it suppresses the mini-lecture, but still asks for your password.
Anyway, the risky bug, which existed until February 2013, was that if the clock ever actually did get set to 01 January 1970, anyone who had run sudo before would seem to have run it within the last five minutes.
As a result, they could run anything they wanted as root without entering a password.
A risky vulnerability indeed.
Six months on
If you’re an Apple OS X user:
- Apple still hasn’t updated the version of sudo that is part of OS X.
- The time and date can easily be changed on OS X, without entering an administrative password, using the systemsetup utility.
- A module has recently been published for the do-it-yourself break-and-enter toolkit Metasploit to exploit these holes.
That’s a bad combination.
What can you do about it?
• Deauthenticate yourself with sudo -K rather than sudo -k.
Instead of setting your timestamp to the special value of 01 January 1970, this option removes the timestamp directory altogether, as if you had never run sudo before.
Next time you run sudo you’ll get the mini-lecture and be asked for your password.
Even if the 01 January 1970 bug isn’t patched, it can’t be exploited if the /var/db/sudo/username file doesn’t exist.
• Consider setting the timestamp_timeout value to zero in the sudo configuration file.
This means that there is no convenience period within which you can run sudo again without being asked for a password.
You will require a password every time.
• Reduce the number of users in the OS X admin group.
If you aren’t in admin then you aren’t allowed to use sudo, which reduces the overall attack surface area.
You can see the group members with the command:
duck@ret:~$ dseditgroup -o read admin . . . dsAttrTypeStandard:GroupMembership - root duck another
You can remove unwanted users (but don’t delete yourself if you are the administrator!) like this:
duck@ret:~$ sudo dseditgroup -o edit -d another admin
• Consider installing the Macports version of sudo.
Macports is not an undertaking to be entered into lightly, but it does give your OS X computer access to a huge range of handy open source goodies that you’ll wonder how you ever managed without.
The Macports version of sudo isn’t bang up to date, but it is patched against the 01 January 1970 flaw.
How can you tell if you’re OK?
Run the command sudo -V to show you the version string.
You should have 1.7.10p7or later, if your version string starts with 1.7; or 1.8.6p7 or later if you’re on 1.8.
Should you say something to Apple?
Why on earth not?
You’re probably surprised to learn that the same company that excels at bringing completely new and funky products to market in just a couple of years can’t update within six months an open source tool that it chose to include with its operating system.
So, why not mention that to Apple?
Image of bullet through apple courtesy of Shutterstock.
9 comments on “Apple neglects OS X privilege escalation bug for six months, gets Metasploit on its case…”
The current OS X Mavericks Developer Preview ships with Sudo version 1.7.10p7, so at least it's updated on new releases. Disappointing that production releases haven't received updates yet though…
I guess this is why Linux uses a “~/.sudo_as_admin_successful” file in your home directory for controlling whether to display the nag screen — completely separate from the authorisation data in “/var/lib/sudo”.
So I have a brand new MBP that apparently shipped with version 1.7.4p6. How can I update it ?
See the article for my suggested mitigations. I use Macports (I use utilities like Graphics Magick and FFMPEG a lot), and installed their build to check its version. But you need to remove the OS X version (or put the binary somewhere out of harm's way, with the setuid bit turned off) if you want to make the Macports build the only sudo on the system…
More generally, does it mean that I just need to set my clock to H+x minutes where H is the last time I ran sudo and x < 5 minutes to have admin privileges again ?
Problem with that is: you can't read your own timestamp directory (/var/db/sudo/username) to work out the value of H, because of restrictive permissions on /var/db/sudo:
$ ls -l /var/db/sudo/duck
ls: /var/db/sudo/duck: Permission denied
But you *can* run "sudo -k" without entering a password, and once you've done that you *know* the value of H, since it's always the start of the Unix epoch:
$ sudo -k
. . . .
# ls -l /var/db/sudo/duck
drwx—— 2 root wheel 68 Jan 1 1970 duck
(And an irony that sudo -k is intended to be a feature that increases security.)
As suggested above, setting timestamp_timeout=0 in /etc/sudoers is a good approach, since it means you *always* need to enter a password, regardless of any timestamp trickery.
I only wish I had any idea what you are talking about…
I find the Linux sudo lecture more business-like since it talks of lectures from local sys admins and respecting the privacy of others. Businesses running Linux will have local sys admins, not individual users or “community” members. Many members of online “communities” won’t have local sys admins. Respecting the privacy of others is also very business-like in my mind. With sudo you could snoop on other users you’re working with. on the same machine. If you’re all part of a trusting “community” do you really need that lecture? The Mac OS lecture is much more individual user-oriented, and basically says you could screw up your system. I think it is totally appropriate for the average Mac OS terminal user. I don’t see anything business-like in it.
The security hole has workarounds as you helpfully pointed out. This probably lowered the priority. I’m guessing it’s not simple for Apple to push updates to packages like sudo outside of their yearly OS updates. A security patch is useless unless it is applied. One thing Apple does well is to make upgrades simple for most users, and encourage users to update. They are market leaders in reducing version fragmentation for operating systems (both desktop and mobile). Many corporate systems and servers running Linux can take sometime for the patches to actually be installed on servers and workstations.
Newer versions of Mac OS have updated versions of sudo.