COMMAND

    mirror (Perl)

SYSTEMS AFFECTED

    mirror 2.9

PROBLEM

    Wise Cat found following.  mirror is a Perl script which is widely
    used for making copy of remote FTP site. It's included in  FreeBSD
    packages.  There are security holes, which allows overwrite  local
    files from remote ftp site  with permissions of the user  who uses
    mirror.   Then retrieving  directory listing  mirror doesn't check
    filename or directory name to contain  ".."  or  "\"   This allows
    to  create  or  overwrite   files  in  directory  different   from
    destination.

    To simply test this bug you can create " .." directory on your ftp
    site and mirror your site.  Mirror will create temporary files  in
    directory one level higher then specifyed.  This way you  couldn't
    overwrite  some  useful  information,  but  this  may be used, for
    example, to fill out / directory (if mirror is ran from root).

    But with putting little changes into you ftpd (for example  making
    him  change  '\'  to  '/'  on  listings)  you  can force mirror to
    overwrite  _any_  file  with  permissions  of  mirror user then he
    mirrors your ftp site.

    This was tested with:

        $ mirror -v
        $Id: mirror.pl,v 2.9 1998/05/29 19:01:07 lmjm Exp lmjm $

SOLUTION

    Upgrade.  SuSE:

        ftp://ftp.suse.com/pub/suse/i386/update/5.3/n1/mirror-2.8.f4-89.i386.rpm
        ftp://ftp.suse.com/pub/suse/i386/update/6.1/n1/mirror-2.8.f4-89.i386.rpm
        ftp://ftp.suse.com/pub/suse/axp/update/6.1/n1/mirror-2.8.f4-89.alpha.rpm
        ftp://ftp.suse.com/pub/suse/i386/update/6.2/n1/mirror-2.8.f4-89.i386.rpm

    Debian GNU/Linux 2.1 could be  remotely exploited.  This has  been
    fixed in mirror version 2.9-2.1.

    Anyhow.   A simple  fix to  overcome this  problem is  to add  the
    following  to  your  mirror.defaults  (and  to  any  package  that
    overrides this setting):

        name_mappings=s:\.\./:__/:g

    This should convert names like:

        " ../rot"

    to

        " __/rot"

    Quick patch  to the  mirror.pl script  to warn/log  about attempts
    follows:

    *** mirror.pl	Mon Jun  8 11:55:27 1998
    --- /usr/local/mirror2.9/mirror	Wed Sep 29 16:34:01 1999
    ***************
    *** 2657,2662 ****
    --- 2657,2701 ----
  	    $no_rename = (! $remote_has_rename) || ($remote_fs eq 'macos' && ! $get_file);
    
  	    foreach $src_path ( @xfer_src ){
    +
    + ##
    + #BEGIN jcp@EUnet.pt 1999/09/29
    + #
    + #Date: Tue, 28 Sep 1999 18:27:54 +0400
    + #From: 3APA3A <wise@tomcat.ru>
    + #To: BUGTRAQ@SECURITYFOCUS.COM
    + #Subject: mirror 2.9 hole
    + #
    + #Hello BUGTRAQ@SECURITYFOCUS.COM,
    + #
    + #mirror is a Perl script which is widely used for making copy of remote
    + #FTP site. It's included in FreeBSD packages. There are security holes,
    + #which   allows  overwrite  local  files  from  remote  ftp  site  with
    + #permissions  of  the  user  who uses mirror. Then retrieving directory
    + #listing  mirror  doesn't  check  filename or directory name to contain
    + #".."  or  "\"  This  allows  to create or overwrite files in directory
    + #different from destination.
    + #
    + #To  simply  test  this  bug you can create " .." directory on your ftp
    + #site  and  mirror  your  site.  Mirror  will create temporary files in
    + #directory  one  level  higher  then  specifyed.  This way you couldn't
    + #overwrite  some useful information, but this may be used, for example,
    + #to fill out / directory (if mirror is ran from root).
    + #
    + #But  with putting little changes into you ftpd (for example making him
    + #change '\' to '/' on listings) you can force mirror to overwrite _any_
    + #file with permissions of mirror user then he mirrors your ftp site.
    + #
    + #
    + #Tested with:
    + #$ mirror -v
    + #$Id: mirror.pl,v 2.9 1998/05/29 19:01:07 lmjm Exp lmjm $
    +
    + 		if( $src_path =~ /\w*\.\.\//){
    +                         &msg( $log, "WARNING: BAD dir detected, skipping: $src_path\n" );
    + 			next;
    + 		}
    + #END jcp@EUnet.pt
  		    if( $get_file ){
  			    $srci = $remote_map{ $src_path };
  		    }