Fellow Naked Security writer Graham Cluley recently pointed out an intriguing bug in the program sudo.
If you're not a Unix-flavoured user (and I include Linux and OS X users in that category), then you may not have come across sudo before.
It's very similar in concept to the Run As... feature in Windows. It allows you, assuming you are authorised, to run commands as someone else.
Although you can use both Run As... and sudo to reduce your privileges for safety, you'll mostly find yourself using them to boost your power so you can perform one-off administrative tasks without actually having to login as an administrator.
You can probably see why this is a good idea.
When you login as an administrator, especially on Unix-like systems, the administrator's almighty authority applies to everything you do.
Even if you just start NOTEPAD to edit one of your own files, you're doing so as the superuser.
It's even worse having unnecessary powers if you need to run more complex software, such as a browser or a word processor. Any vulnerability that gets exploited will probably be able to take over the whole system, not just one user's part of it.
So sudo is intended to reduce, or even to remove, the need ever to login as the superuser, also known as root, on Unix systems.
And the name of sudo reflects this fact, standing as it does for "do as superuser".
Many modern Unix-like systems - Linux distributions such as the Ubuntu family, for instance, and UNIX derivatives such as OS X - don't even have the root login enabled by default. Using sudo is the only way to perform administrative tasks.
By default, sudo asks you for your password (or, if you prefer, for root's password) whenever you want to do something as the superuser.
If you haven't run sudo before, it also spits out what the source code calls a lecture:
Of course, system administration rarely involves just one command at a time.
So sudo has a grace period, five minutes by default, within which it doesn't ask for your password again:
You can probably guess where this is going.
As soon as you start adding get-out-of-jail-free components into your security software, you add the risk of introducing exploitable holes.
For example, what if you log out and log back in? Should your sudo authority survive or not?
How do you reliably keep track of elapsed time? What if another user fiddles with the system clock?
And what if a security-conscious administrator uses sudo for one or two commands and deliberately wants to revoke his authority by discarding the rest of his five-minute no-password-needed window?
The authors of sudo dealt with the last case by providing the sudo -k option, which, in the words of sudo's manual page, "invalidates the user's timestamp."
At first, this was done simply by removing the database entry used to keep track of the last time the user authenticated. (The "database entry" is handled elegantly and simply by using the filesystem's timestamp on a protected directory called /var/db/sudo/username.)
But deleting the timestamp data completely meant that sudo couldn't tell, when next you used it, that you'd ever run it before. So you'd get the "lecture" all over again next time.
And in turns out that the sort of system administrator who is conscientious enough to use sudo -k in the first place doesn't like repetitious and mildly patronising advice from the operating system he's administering.
So the authors of sudo added another get-out-of-jail-free component, namely that deauthorising yourself wouldn't delete your timestamp entry altogether, as though you were a complete newbie.
Instead, when you run sudo -k the program simply forces your timestamp to a value that is certain (and I'm sure you can see where this is going) to be more than five minutes in the past.
However, the authors used what is known as an in-band signal.
→ We've written about the risk of in-band signalling before, in the context of mobile phones processing some phone numbers as special commands, not as numbers to be dialled. Whenever a specific input can have two meanings, ambiguity is bound to arise.
To invalidate your current timestamp, sudo sets it back to the beginning of the Epoch, which is literary geek-speak for the earliest timestamp possible on your operating system.
For historical reasons, a timestamp of zero comes out on Unix-like systems as the beginning of 01 January 1970, as shown in the timestamp image above.
Clearly, that is certain to be more than five minutes in the past, if your clock is correct.
But what if it isn't? What if your system clock has been deliberately reset to zero by a miscreant? Or even accidentally, for example by a power failure?
Of all the incorrect timestamps that might arise by accident, you'd want to hazard a guess that midnight on 01 January 1970 is the most likely, for the simple reason that it is represented by the value zero.
And if ever someone or something could reset the clock, any cautious administrator who had deliberately relinquished his sudo authority by carefully running sudo -k would be hoist by his own petard.
(That sort of irony is not unusual in security circles: bugs can end up more severe for those who try to do the right thing than for those who simply "let the system choose".)
This flaw should be a reminder that even simple-sounding security software like sudo, which is at its heart just a programmatic wrapper around Unix's setuid() family of system calls, can go wrong.
Adding features, especially ones that tweak your enforcement of security, always carries the risk of making security worse.
This bug, I am happy to tell you, was quickly fixed.
The authors of sudo simply removed the ambiguity in interpreting the zero timestamp.
If the timestamp of your last use of sudo is the start of the Epoch, it means that you are deauthorised but have used sudo before.
It can no longer also be interpreted to mean that you actually used sudo at the stroke of midnight on New Year's Day, 1970.
NB. The sudo versions affected by this flaw are 1.6.0 to 1.7.10p6 inclusive and 1.8.0 to 1.8.6p6 inclusive. The first versions patched against the bug are 1.7.10p7 and 1.8.6p7.