Vulnerability Development mailing list archives
Re: Perl exploit (was: Some work needed)
From: Rafal Wojtczuk <nergal () IDEA AVET COM PL>
Date: Mon, 7 Aug 2000 12:37:43 +0200
Hello,
a) If you'll try to fool perl, forcing it to execute one file instead of another (quite complicated condition, refer to source code), it
[cut]
This condition is quite easy to reach - my code is extermely ugly and slow (it's written in bash), so it requires reasonably fast machine (like pII/pIII x86 box). It can be optimized, of course.
At last, some non-fully-trivial local vulnerability to study :) Kudos to its discoverers. There are some interesting points regarding such (pseudo)race conditions. Lets have a look at a fragment of "suidperl ./filename" strace output: open("./filename", O_RDONLY) = 6 fcntl(6, F_SETFD, FD_CLOEXEC) = 0 fstat(6, {st_mode=S_IFREG|S_ISUID|0755, st_size=51, ...}) = 0 setreuid(0, 500) = 0 getuid() = 0 geteuid() = 500 stat("./filename", {st_mode=S_IFREG|S_ISUID|0755, st_size=51, ...}) = 0 Our exploit will succeed, if a context switch happens between open and stat syscalls. The probability is small, but of course its enough if we launch perl sufficient number of times. How can we improve our chances ? Everybody uses nice(1) in scripts exploiting race conditions. Am I the only one who thinks it makes no sense ? On linux (I think on all sane OSes) a niced process receives as large time quantum to execute as other processes, only less often. So, the probability of the time slice to end between "open" and "stat" remains the same. How about making "open" syscall consume all available time quantum (or yield context) ? For instance, one can put "./filename" on NFS mounted filesystem, this should be enough. But its even easier. Lets make a script name (or, more precisely, a symlink which script name will point to) contain a lot of path components, symlinks etc. The following script #!/bin/sh mkdir d cd d DOT=`perl -e 'print "../d/"x200'` ln -s $DOT/2 1 ln -s $DOT/3 2 ln -s $DOT/4 3 ln -s $DOT 4 ONES=`perl -e 'print "1/"x500'` ln -s `which passwd` passwd ln -s $ONES/passwd ourlink creats "ourlink" symlink. Resolved, it would have 400000 path components. On my PC, stat("ourlink",&statbuf) call takes about 0.48 (!) seconds to execute (to compare, a stat on a simple symlink takes about 1/230000 s). So, in lcamtuf/sebastian's script, initially we need to point $FILENAME not directly at $SUIDBIN, but at "ourlink". One more gotcha, we can't use standard rm and ln commands, as they insist on stat-ing the file to be removed (therefore, they're slow). So, instead of ln -sf, we must create a C program, which does simply unlink($FILENAME);symlink("something",$FILENAME); Following these guidelines, I created a script (yes, bash is fast enough :) ), which produces a root shell with only one perl execution - so, this is really a pseudo race condition. Save yourself, Nergal
Current thread:
- Some work needed Michal Zalewski (Aug 06)
- Re: Some work needed Jonathan Leto (Aug 07)
- Re: Some work needed Michal Zalewski (Aug 08)
- Re: Some work needed White Vampire (Aug 09)
- Re: Some work needed Luis Pinto (Aug 08)
- Re: Some work needed White Vampire (Aug 09)
- Re: Perl exploit (was: Some work needed) Rafal Wojtczuk (Aug 08)
- Re: Some work needed Jonathan Leto (Aug 07)