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 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 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 | 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" 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" accounts to have uid "uucp". In fact, the "uu" 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" accounts may depend on the local system environment. In my environment they are group "untrusted".] Having different UIDs for the "uu" 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