The security hole is actually in the gethostbyname() library
routine and is exploited by overwriting a fixed-size buffer with
SPARC machine code and causing a jump to that code. The original
programming exploiting this code was posted to bugtraq@netspace.org
At that time I was not on that mailing list -- I am now!
The current exploitation requires an account on the machine being
exploited. It is reported to only work on sun4m architectures at present
and only those with patch 103615-01 and up (unconfirmed by me).
I have not notified CERT because this is already public and Sun is aware
of it.
Advice/fixes included:
* get rid of rlogin -- it has frequently turned up as a security
risk
* use my "quick hack" of Linux source for rlogin.c or the binary
located at:
ftp://cs.dal.ca/rlogin.c or
ftp://cs.dal.ca/rlogin
(contrary to some reponses, you can workaround the bug by
restricting the size of hostname used in rlogin)
* use the rlogind that's distributed with Wietse Venema's
logdaemon5.3 package
* Casper Dik <casper@holland.Sun.COM> offers the attached
script which modifies the running image of the kernel so that
the stack no longer has execute permission (see comments in the
script).
Thanks for responses from:
James Hsieh <jhsieh@soemail.ucsd.edu>
"Michael Jastremski" <mjastrem@thunder.ocis.temple.edu>
Fedor Gnuchev <qwe@ht.eimb.rssi.ru>
Rachel Polanskis <rachel@juno.virago.org.au>
Rich Kulawiec <rsk@itw.com>
Frank Pardo <fpardo@tisny.com>
Mark Bergman <bergman@phri.nyu.edu>
Casper Dik <casper@holland.Sun.COM>
David Trueman,
Systems Manager, Dalhousie Math, Stats and Computing Science
Technical Chair, Chebucto Community Net
#!/bin/sh
#
# Protect SPARC stack against unwanted exec access
# Side effect: growth in data segment also loses exec bit.
# This may break some programs.
#
# Install as:
# /etc/init.d/protect_stack
# ln /etc/init.d/protect_stack /etc/rc2.d/S07protect_stack
#
# And all programs except init are protected after the next reboot.
#
# After installing the scripts, first test with:
#
# /etc/init.d/protect_stack start
#
# Then start a new shell and test changes with /usr/proc/bin/pmap.
#
# csh -fi
# % pmap $$
# ......
# 00047000 56K read/write - instead of rwx
# 0004D000 32K [ heap ]
# ......
# EFFFC000 8K read/write - instead of rwx
# EFFFC000 16K [ stack ]
# EFFFE000 8K read/write
#
#
# Seems to work on 2.4/2.5/2.5.1 but this may vary by patchlevel.
# Not all Sun MMUs support this, but it seems to haev effect on sun4m and
# sun4u, probably won't have an effect on sun4c.
#
# The assembly checking may need tweaking depending on OS level and
# patchlevel.
#
# Casper Dik (Casper.Dik@Holland.Sun.COM)
#
# The contents of this file are intended to be read as
# an example. This is not a supported product of Sun
# Microsystems and no hotline calls will be accepted
# which directly relate to this information.
#
# NO LIABILITY WILL BE ACCEPTED BY SUN MICROSYSTEMS FOR
# ANY LOSS (DIRECT OR CONSEQUENTIAL) INCURRED IN ANY WAY
# BY ANY PARTY THROUGH THE USE OF THIS INFORMATION.
#
# NO WARRANTY OF ANY SORT IS IMPLIED OR GIVEN FOR ANY
# CODE DERIVED FROM THIS INFORMATION.
PATH=/usr/bin:$PATH
#
#
# Set/get values using adb.
#
getvalue ()
{
echo $1/$2 | adb -k /dev/ksyms /dev/mem | awk "\"$1:\""' == $1 {print $2}'
}
setvalue ()
{
echo $1/$2$3 | adb -wk /dev/ksyms /dev/mem >/dev/null 2>&1
}
#
# Check whether setting/unsetting is not dangerous.
#
check ()
{
map=`getvalue $mapaddr X`
zfod=`getvalue $zfodaddr x`
if [ "$map" = "$oldmap" -a "$zfod" = "$oldzfod" ]
then
old=true;
else
old=false
fi
if [ "$map" = "$newmap" -a "$zfod" = "$newzfod" ]
then
new=true
else
new=false
fi
}
p=`basename $0`
mapaddr=map_hunk+8
zfodaddr=zfod_segvn_crargs+0xd
#
# Instruction should at $mapaddr should be: mov 0xf,%reg or mov 0xb,%reg
# this is a synthetic instruction that encodes as or %g0,0xf,$reg
# 10rr rrr0 0001 0000 0010 0000 0000 1x11
#
# Try and find it at several locations.
#
for mapaddr in map_hunk+8 map_hunk+0xc
do
mapval=`getvalue $mapaddr X`
case $mapval in
[9ab][02468ace]10200[bf])
reg=`expr $mapval : '\(..\)'`
break;;
esac
done
if [ -z "$reg" ]
then
echo "${p}: Instruction doesn't match" 1>&2
exit 1
fi
echo "${p}: Instruction prefix set to $reg ($mapval@$mapaddr)"
oldmap=${reg}10200f
newmap=${reg}10200b
oldzfod=f0f
newzfod=b0f
case "$1" in
start)
check
if $new
then
echo "${p}: New kernel parameters already set" 1>&2
exit 0
fi
if $old
then
setvalue $mapaddr W $newmap
setvalue $zfodaddr w $newzfod
echo "${p}: Stack protected"
else
echo "${p}: Kernel value mismatch $map != $oldmap or $zfod != $oldzfod" 1>&2
exit 1
fi
;;
stop)
check
if $old
then
echo "${p}: Old kernel parameters already set" 1>&2
exit 0
fi
if $new
then
setvalue $mapaddr W $oldmap
setvalue $zfodaddr w $oldzfod
echo "${p}: Stack no longer protected"
else
echo "${p}: Kernel value mismatch $map != $newmap or $zfod != $newzfod" 1>&2
exit 1
fi
;;
*)
echo "Usage: ${p} [start|stop]" 1>&2
exit 1;;
esac
This archive was generated by hypermail 2.1.2 : Fri Sep 28 2001 - 23:11:16 CDT