Bugtraq mailing list archives

fcheck prior to 2.07.59 - vulnerability - improper use of perl 'magic open'


From: btrq <btrq () BOB-N COM>
Date: Tue, 20 Mar 2001 22:26:30 -0600

VULNERABLE:  Probably all versions prior to 2.07.59 - the author of fcheck
can't be bothered to note security fixes in his change log, but most
likely all prior versions had this vulnerability.

Vulnerability: by placing a carefully crafted filename in a directory
checked by vulnerable versions of fcheck, commands caan be executed with
the rights of the user running fcheck.


Discussion:


fcheck is a "poor man's tripwire" - it is a file integrity checker written
in perl.

To accomplish some functions, it uses external programs, such as md5,
md5sum and/or file.

These are accessed by issuing something on the order of:


     open(IN, "$program_name '$filename' |");
     $filesig = <IN>;
     close IN;


The problem is with the open() statement shown above. ?The '|' causes the
rest of the string to be interpolated, then sent to a command interpreter
(a shell, such as sh, csh or bash) for execution, with its output coupled
to the filehandle IN.

In the program under consideration, $program_name is under the control of
the person who configured fcheck (presumably root) but $filename can be the
name of any file placed into any directory which fcheck is instructed to
check.

If one goes to a directory checked by fcheck and issues:

echo "test" >exploit\'\;\`touch\ blah\`\'

as written (this was tested on linux running bash), then runs fcheck, you
will find that the file named blah has been created because the command
'touch blah' contained in the filename created above was executed.  (Using
the echo, rather than just touch'ing the file is needed because fcheck
doesn't run the signatures on zero length files.)

So if this run by root, but checks files/directories writable by other than
root, using the -s switch or checking files which cause the external
$Filefunc command to be used, a problem exists.

The workaround, implmented in good version(s), is to do the following:

     ?if (open(IN, "-|"))
     ?{
     ? ? ? ?$filesig = ?<IN>;
     ? ? ? ?close IN;
?    }
     else
?    {
     ? ? ?exec $program_name, $filename;
     ?}

instead. ?The multiple-argument version of exec wholly avoids any shell and
therefore the interpretation of the metacharacters.


Current thread: