The 'Security Digest' Archives (TM)

Archive: About | Browse | Search | Contributions | Feedback
Site: Help | Index | Search | Contact | Notices | Changes

ARCHIVE: Unix 'Security Mailing List' - Archives (1984 - 1987)
DOCUMENT: Unix 'Security Mailing List' #20 1985-08-03 (1 file, 5785 bytes)
SOURCE: http://securitydigest.org/exec/display?f=unix/archive/020.txt&t=text/plain
NOTICE: securitydigest.org recognises the rights of all third-party works.

START OF DOCUMENT


Date: 3 Aug 85 03:02:52 CDT (Sat)
From: ihnp4!ucla-cs!lcc!jbrown
Subject:        ftp & uucp, setuid mv, 4.1bsd mail

(scenario is ftp to victim using your uucp login, corrupt a uucp-owned file,
and proceed from there)

As far as I know, there is no reason for your uucp aliases to be the same
uid as uucp. uucico runs set-user-id uucp, so when uu<somebody> logs in
"normally" they have all the privileges they need, and when they log in
via ftp they have none, or, rather, they have no specific privileges.
(They will still be able to corrupt things that the general public can
write).

(question about mv being setuid on Unix PC)
mv is often suid so that it can move directories.  I just checked our Unix
PC, and found that mv was, indeed, suid.  I tried "mv /etc/passwd
/etc/jbrown", and it worked!  I was shocked!  Then, I looked closely. /etc
was mode 777 - writable by everybody!  When I corrected that by making
/etc 755, mv refused to move /etc/passwd.  The moral is: keep your system
directories write-protected!  I once broke in to a system which had /usr
unprotected by moving in a new /usr/lib which had a modified crontab.

(questions about 4.1bsd mail)
4.1 bsd mail can be suid so that it can make the mail files be owned by
the recipient instead of by the sender.  We had problems with this - if
the sender had a restrictive umask (say 027), he created mail files which
nobody else could write, and so further mail from other users failed.
Making mail suid made it change the ownership of the mail file to the
target, and made the mail-reader not delete the mail file (only truncate
it), which meant that the mail file could be protected against public
reading.  What you describe sure looks like a bug, though.

----------------------------------------------------------------------------

Date: Sat, 3 Aug 85 14:27:25 pdt
From: Mats Wichmann <ihnp4!dual!mats>
Subject: mv on UNIX PC


This got quite a bit of airplay on the net proper; the
answer to the problem (as I posted in response to the
original article) is that there is no problem with mv
being setuid root. However, if some dunderhead happens
to leave /etc, or even better (because it is more invisible), /,
writable by everyone, all other secutiry measures are pretty 
much out the window.

I see the error of leaving / the wrong mode a whole lot.
The scenario seems to be: build a system. After cleaning
everyhthing up, as a fina check do ls -l in /; everything looks okay -
/etc, /bin, /lib, and /usr are all properly mode 755 (or 775
or whatever). In this case, `.' itself (/) does not show up,
but is often mode 777 since this is the way mkfs makes it
unless you use a proto file to tell it otherwise. Then someone
who knows where to look comes along, and while he can't edit
/etc/passwd directly, he can mv /etc out of the way, make
his own /etc, get a copy of passwd over there, add himself
to the password file as root; su to root and restore everything
to pretty much its' original state, except for leaving a
little rathole in the password file. Even better, once one
has become root, is to leave something real invisible, like
make /bin/newgrp be a program that actually execs /bin/csh
with superuser permission (how often does anyone really
run newgrp - this will probably hang around for quite a
while until someone notices it).....and so on and so on.

So make sure `/' is writable only by the right people!!!

By the way, I used this rathole once very usefully. I was
teaching a UNIX course for another company, and the company
putting on the course had provided a Zilog machine, which
was set up all wrong for what I needed - and they had not
provided me with the root password. Fortunately, Zilog had 
not taken care of this problem, so I was able to get in this 
way and salvage the situation.....whew!!!

Mats Wichmann
Dual Systems

----------------------------------------------------------------------------

From: denelcor!allegra!fortune!redwood!rpw3
Date: Sun, 4 Aug 85 17:23:39 pdt
Subject: UIDs of "uu{host}" accounts

In security digest #19, "utzoo!utflis!rayan" says:

+---------------
| Given that one knows the password of an account on the target machine
| with the same uid as uucp (it is common practice to have a uu<host>
| login for each neighboring uucp host)...
+---------------

Actually, the "common practice" I am familiar with (which is practiced
by most of the sites I know of here in the Bay Area) is to give each
"uu<host>" login a DIFFERENT uid -- different from each other and from uucp.
The reason for giving different logins is only partially to have different
passwords; it's also to have different UIDs for tracking uux decendents.
Since uucico runs "setuid uucp" anyway, there is no need at all for the
"uu<host>" accounts to have uid "uucp". In fact, the "uu<host>" accounts
need have NO priviledges at all, including no home directory (or, a junk
directory not owned by them that they can't read/write/search!).

[Note: the group priviledges needed by the "uu<host>" accounts may depend on
the local system environment. In my environment they are group "untrusted".]

Having different UIDs for the "uu<host>" accounts solves the problem, I think
(unless I've missed something). Comments?


Rob Warnock
Systems Architecture Consultant

UUCP:	{ihnp4,ucbvax!dual}!fortune!redwood!rpw3
DDD:	(415)572-2607
USPS:	510 Trinidad Lane, Foster City, CA  94404

----------------------------------------------------------------------------

Date: Tue, 6 Aug 85 09:21:59 cdt
From: ihnp4!infoswx!bees (Ray Davis)
Subject: Re: Unix PC's mv has the uid bit set (rob@nitrex)

System V and System V Release 2 (which the UNIX PC is) are supposed to
have /bin/mv owned by root with the setuid bit on.  The code uses the
notion of real uid and effective uid.  Permission checking is done
relative to the real uid, but the actual link and unlink is done with
the effective uid of root.

If indeed the code for /bin/mv on the UNIX PC does not behave the same
way, this is a major bug and should be reported.

Ray Davis
Teknekron Infoswitch, Richardson
infoswx!bees, (214)644-0570

----------------------------------------------------------------------------

Date: Wed, 7 Aug 85 10:58:26 cdt
From: ut-sally!jsq (John Quarterman)
Subject: ftpd and uucp logins

Here is a fix to the security hole in ftpd caused by multiple uucp
logins.  If an additional parameter file, /etc/ftpshells, exists, it is
expected to be a list of login shells, one per line, as they would
appear in /etc/passwd.  Ftp logins will then only be permitted for
shells in that list.  Note the blank line in the example:  it permits
the Bourne shell.  If /etc/ftpshells does not exist, ftpd acts exactly
as before this mod, i.e., any shell is permitted.

Another possibility is to just build the list of shells into ftpd.
I believe this is what seismo does.  Either way, checking for permitted
shells will automatically pick other problem logins such as one for who
or w, while a check for uid of prohibited users in /etc/ftpusers will
not, unless somebody remembers to update /etc/ftpusers for who or w.
It's a good idea to still have /etc/ftpusers, though, if only to
disallow ftp logins by root.

4.3BSD does not appear to have any fix to this problem.  I will submit
this one as a bug fix and see what happens.  (I could have sworn I or
somebody at seismo submitted a fix to Berkeley for this a year or so ago.)

The following shar archive also contains a fix (idea from cak) so that
guest logins are logged in /usr/adm/wtmp (there was a conflict with
chroot).  And it sets the default intercommand timeout to match the
manual entry.

: This is a shar archive.  Extract with sh, not csh.
echo x - ftpshells
sed -e 's/^X//' > ftpshells << '!RoNnIe!RaYgUn!'
X
X/bin/csh
X/bin/oldcsh
X/usr/new/csh
!RoNnIe!RaYgUn!
echo x - ftpcmd.y.diff-c
sed -e 's/^X//' > ftpcmd.y.diff-c << '!RoNnIe!RaYgUn!'
X*** ftpcmd.y.dist	Wed Aug  7 10:29:08 1985
X--- ftpcmd.y	Wed Jul 25 09:52:57 1984
X***************
X*** 81,86
X  			} else if (checkuser($3)) {
X  				guest = 0;
X  				pw = getpwnam($3);
X  				reply(331, "Password required for %s.", $3);
X  			}
X  			if (pw == NULL)
X
X--- 81,89 -----
X  			} else if (checkuser($3)) {
X  				guest = 0;
X  				pw = getpwnam($3);
X+ 				if (!checkshell(pw->pw_shell))
X+ 					pw = NULL;
X+ 				else
X  				reply(331, "Password required for %s.", $3);
X  			}
X  			if (pw == NULL)
!RoNnIe!RaYgUn!
echo x - ftpd.c.diff-c
sed -e 's/^X//' > ftpd.c.diff-c << '!RoNnIe!RaYgUn!'
X*** ftpd.c.dist	Wed Aug  7 10:25:46 1985
X--- ftpd.c	Wed Aug  8 21:32:45 1984
X***************
X*** 30,35
X   * Commonly used to disallow uucp.
X   */
X  #define	FTPUSERS	"/etc/ftpusers"
X  
X  extern	int errno;
X  extern	char *sys_errlist[];
X
X--- 30,41 -----
X   * Commonly used to disallow uucp.
X   */
X  #define	FTPUSERS	"/etc/ftpusers"
X+ /*
X+  * File containing a list of shells PERMITTED in /etc/passwd entries.
X+  * Useful when there is a different uucp login per UUCP link, as it
X+  * doesn't require /etc/ftpusers to be updated for each.
X+  */ 
X+ #define FTPSHELLS	"/etc/ftpshells"
X  
X  extern	int errno;
X  extern	char *sys_errlist[];
X***************
X*** 51,57
X  int	logged_in;
X  struct	passwd *pw;
X  int	debug;
X! int	timeout;
X  int	logging;
X  int	guest;
X  int	type;
X
X--- 57,63 -----
X  int	logged_in;
X  struct	passwd *pw;
X  int	debug;
X! int	timeout = 60;
X  int	logging;
X  int	guest;
X  int	type;
X***************
X*** 234,242
X  			pw->pw_name, pw->pw_dir);
X  		goto bad;
X  	}
X! 	if (guest && chroot(pw->pw_dir) < 0) {
X! 		reply(550, "Can't set guest privileges.");
X! 		goto bad;
X  	}
X  	if (!guest)
X  		reply(230, "User %s logged in.", pw->pw_name);
X
X--- 240,252 -----
X  			pw->pw_name, pw->pw_dir);
X  		goto bad;
X  	}
X! 	if (guest) {
X! 		dologset(1);
X!  		if (chroot(pw->pw_dir) < 0) {
X! 			dologset(0);
X! 			reply(550, "Can't set guest privileges.");
X! 			goto bad;
X! 		}
X  	}
X  	if (!guest)
X  		reply(230, "User %s logged in.", pw->pw_name);
X***************
X*** 716,721
X  
X  #define	SCPYN(a, b)	strncpy(a, b, sizeof (a))
X  struct	utmp utmp;
X  
X  /*
X   * Record login in wtmp file.
X
X--- 726,732 -----
X  
X  #define	SCPYN(a, b)	strncpy(a, b, sizeof (a))
X  struct	utmp utmp;
X+ int wtmp = -1;
X  
X  /*
X   * Open or close wtmp.
X***************
X*** 718,723
X  struct	utmp utmp;
X  
X  /*
X   * Record login in wtmp file.
X   */
X  dologin(pw)
X
X--- 729,751 -----
X  int wtmp = -1;
X  
X  /*
X+  * Open or close wtmp.
X+  */
X+ dologset(flag)
X+ 	int flag;
X+ {
X+ 	if (flag) {
X+ 		if (wtmp < 0)
X+ 			wtmp = open("/usr/adm/wtmp", O_WRONLY|O_APPEND);
X+ 		return;
X+ 	}
X+ 	if (wtmp < 0)
X+ 		return;
X+ 	(void) close (wtmp);
X+ 	wtmp = -1;
X+ }
X+ 
X+ /*
X   * Record login in wtmp file.
X   */
X  dologin(pw)
X***************
X*** 723,729
X  dologin(pw)
X  	struct passwd *pw;
X  {
X- 	int wtmp;
X  	char line[32];
X  
X  	wtmp = open("/usr/adm/wtmp", O_WRONLY|O_APPEND);
X
X--- 751,756 -----
X  dologin(pw)
X  	struct passwd *pw;
X  {
X  	char line[32];
X  
X  	dologset(1);
X***************
X*** 726,732
X  	int wtmp;
X  	char line[32];
X  
X! 	wtmp = open("/usr/adm/wtmp", O_WRONLY|O_APPEND);
X  	if (wtmp >= 0) {
X  		/* hack, but must be unique and no tty line */
X  		sprintf(line, "ftp%d", getpid());
X
X--- 753,759 -----
X  {
X  	char line[32];
X  
X! 	dologset(1);
X  	if (wtmp >= 0) {
X  		/* hack, but must be unique and no tty line */
X  		sprintf(line, "ftp%d", getpid());
X***************
X*** 735,741
X  		SCPYN(utmp.ut_host, remotehost);
X  		utmp.ut_time = time(0);
X  		(void) write(wtmp, (char *)&utmp, sizeof (utmp));
X! 		(void) close(wtmp);
X  	}
X  }
X  
X
X--- 762,769 -----
X  		SCPYN(utmp.ut_host, remotehost);
X  		utmp.ut_time = time(0);
X  		(void) write(wtmp, (char *)&utmp, sizeof (utmp));
X! 		if (!guest)
X! 			dologset(0);
X  	}
X  }
X  
X***************
X*** 746,753
X  dologout(status)
X  	int status;
X  {
X- 	int wtmp;
X- 
X  	if (!logged_in)
X  		_exit(status);
X  	seteuid(0);
X
X--- 774,779 -----
X  dologout(status)
X  	int status;
X  {
X  	if (!logged_in)
X  		_exit(status);
X  	seteuid(0);
X***************
X*** 751,757
X  	if (!logged_in)
X  		_exit(status);
X  	seteuid(0);
X! 	wtmp = open("/usr/adm/wtmp", O_WRONLY|O_APPEND);
X  	if (wtmp >= 0) {
X  		SCPYN(utmp.ut_name, "");
X  		SCPYN(utmp.ut_host, "");
X
X--- 777,784 -----
X  	if (!logged_in)
X  		_exit(status);
X  	seteuid(0);
X! 	if (!guest)
X! 		dologset(1);
X  	if (wtmp >= 0) {
X  		SCPYN(utmp.ut_name, "");
X  		SCPYN(utmp.ut_host, "");
X***************
X*** 757,763
X  		SCPYN(utmp.ut_host, "");
X  		utmp.ut_time = time(0);
X  		(void) write(wtmp, (char *)&utmp, sizeof (utmp));
X! 		(void) close(wtmp);
X  	}
X  	/* beware of flushing buffers after a SIGPIPE */
X  	_exit(status);
X
X--- 784,790 -----
X  		SCPYN(utmp.ut_host, "");
X  		utmp.ut_time = time(0);
X  		(void) write(wtmp, (char *)&utmp, sizeof (utmp));
X! 		dologset(0);
X  	}
X  	/* beware of flushing buffers after a SIGPIPE */
X  	_exit(status);
X***************
X*** 867,873
X  }
X  
X  /*
X!  * Check user requesting login priviledges.
X   * Disallow anyone mentioned in the file FTPUSERS
X   * to allow people such as uucp to be avoided.
X   */
X
X--- 894,900 -----
X  }
X  
X  /*
X!  * Check user requesting login privileges.
X   * Disallow anyone mentioned in the file FTPUSERS
X   * to allow people such as uucp to be avoided.
X   */
X***************
X*** 893,896
X  	}
X  	fclose(fd);
X  	return (!found);
X  }
X
X--- 920,951 -----
X  	}
X  	fclose(fd);
X  	return (!found);
X+ }
X+ 
X+ /*
X+  * Check user requesting login privileges.
X+  * Allow only shells mentioned in FTPSHELLS.
X+  */
X+ checkshell(shell)
X+ 	register char *shell;
X+ {
X+ 	char line[BUFSIZ], *index();
X+ 	FILE *fd;
X+ 	int found = 0;
X+ 
X+ 	fd = fopen(FTPSHELLS, "r");
X+ 	if (fd == NULL)
X+ 		return (1);
X+ 	while (fgets(line, sizeof (line), fd) != NULL) {
X+ 		register char *cp = index(line, '\n');
X+ 
X+ 		if (cp)
X+ 			*cp = '\0';
X+ 		if (strcmp(line, shell) == 0) {
X+ 			found++;
X+ 			break;
X+ 		}
X+ 	}
X+ 	fclose(fd);
X+ 	return (found);
X  }
!RoNnIe!RaYgUn!
exit

----------------------------------------------------------------------------

Date: 9 Aug 85 18:14:48 CDT (Fri)
From: ihnp4!utzoo!henry
Subject: restriction of uuxqt-run commands

> The simple fix to rmail.c is to check for (and throw away - or bring to
> the attention of root) mail that contains a $ sign anywhere in the From line.

Quite some time ago we observed that uuxqt is set up as a general remote-
execution facility, but this is far more general than is really needed
for its normal uses (news and mail).  We modified our uuxqt to reject any
attempt at remote execution of a command line containing any suspicious
characters (the list of "suspicious" characters includes anything non-ascii
and everything that is special to the shell).  This closes a fair number of
security holes with one stroke.

				Henry Spencer @ U of Toronto Zoology
				{allegra,ihnp4,linus,decvax}!utzoo!henry

END OF DOCUMENT