Ethereal-dev: [ethereal-dev] Fix: malformed ISAKMP packets cause infinite loop in parse

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Jack Keane <jkeane@xxxxxxxxxxxxx>
Date: Thu, 05 Oct 2000 10:21:51 -0400
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Version:

        Ethereal Version 0.8.12(C). Compiled with GTK+1.2.1, with
        libpcap 0.4, with libz 1.1.3, without SNMP.

Problem description:

        Corrupt or malformed ISAKMP packets can cause ethereal to loop
        infinitely on packet parsing.  The problem occurs when
        breaking out values from ISAKMP payloads.  If the LENGTH field
        of the payload is incorrect, and particularly if it is less
        than the payload header length, loops in packet-isakmp.c may
        never terminate.

        This problem has existed since at least version 0.8.

Fix:

        Loop conditions adjusted to account for the possibility of a
        bad length in the packet.

Index: packet-isakmp.c
===================================================================
RCS file: /cvsroot/ethereal/packet-isakmp.c,v
retrieving revision 1.28
diff -u -r1.28 packet-isakmp.c
- --- packet-isakmp.c	2000/10/03 22:49:37	1.28
+++ packet-isakmp.c	2000/10/05 14:13:02
@@ -552,6 +552,7 @@
 
   struct trans_hdr *	hdr	= (struct trans_hdr *)(pd + offset);
   guint16		length	= pntohs(&hdr->length);
+  int                   slength;
   proto_item *		ti	= proto_tree_add_text(tree, NullTVB, offset, length,
"Transform payload");
   proto_tree *		ntree;
 
@@ -590,8 +591,8 @@
   }
   offset += sizeof(hdr->transform_id) + sizeof(hdr->reserved2);
   
- -  length -= sizeof(*hdr);
- -  while (length) {
+  slength -= sizeof(*hdr);
+  while (slength>0) {
     const char *str = NULL;
     int ike_phase1 = 0;
     guint16 type    = pntohs(pd + offset) & 0x7fff;
@@ -611,7 +612,7 @@
 			  str, type,
 			  value2str(ike_phase1, type, val_len), val_len);
       offset += 4;
- -      length -= 4;
+      slength -= 4;
     }
     else {
       guint16	pack_len = 4 + val_len;
@@ -621,7 +622,7 @@
 			  str, type,
 			  num2str(pd + offset + 4, val_len));
       offset += pack_len;
- -      length -= pack_len;
+      slength -= pack_len;
     }
     if (!IS_DATA_IN_FRAME(offset)) {
 	    proto_tree_add_text(ntree, NullTVB, 0, 0,
@@ -940,7 +941,7 @@
     offset += hdr->spi_size;
   }
 
- -  if (length - sizeof(*hdr)) {
+  if (((int)length - sizeof(*hdr)) > 0) {
     proto_tree_add_text(ntree, NullTVB, offset, length - sizeof(*hdr) -
hdr->spi_size,
 			"Notification Data");
     offset += (length - sizeof(*hdr) - hdr->spi_size);
@@ -1048,6 +1049,7 @@
 
   struct cfg_hdr * 	hdr	 = (struct cfg_hdr *)(pd + offset);
   guint16		length	 = pntohs(&hdr->length);
+  int                   slength;
   proto_item *		ti	 = proto_tree_add_text(tree, NullTVB, offset,
length, "Attribute payload");
   proto_tree *		ntree;
 
@@ -1070,9 +1072,9 @@
   proto_tree_add_text(ntree, NullTVB, offset, sizeof(hdr->identifier),
                       "Identifier: %u", pntohs(&hdr->identifier));
   offset += sizeof(hdr->identifier);
- -  length -= sizeof(*hdr);
+  slength -= sizeof(*hdr);
   
- -  while(length) {
+  while(slength>0) {
     guint16 type = pntohs(pd + offset) & 0x7fff;
     guint16 val_len = pntohs(pd + offset + 2);
     
@@ -1080,7 +1082,7 @@
       proto_tree_add_text(ntree, NullTVB, offset, 4,
 			  "%s (%u)",cfgattrident2str(type),val_len);
       offset += 4;
- -      length -= 4;
+      slength -= 4;
     }
     else {
       guint pack_len = 4 + val_len;
@@ -1088,7 +1090,7 @@
       proto_tree_add_text(ntree, NullTVB, offset, 4,
 			  "%s (%se)", cfgattrident2str(type), num2str(pd + offset + 4,
val_len));
       offset += pack_len;
- -      length -= pack_len;
+      slength -= pack_len;
     }
   }
 
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.3 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iEYEARECAAYFAjncjRcACgkQKCFXyIceXHzLPQCeOlsw+uHLrbb48EOCwHT3C7jX
gY4AnRWi0DKt1sXFDmFBx4ElrTdBPGQV
=qnvt
-----END PGP SIGNATURE-----

-- 
Jack Keane                    OpenReach, Inc
jkeane@xxxxxxxxxxxxx          780 Route 18
(732)254-7901 x7109           East Brunswick, NJ

Beginning on 9/25, I will be signing email. You can find my 
PGP public key on babel in /home/keane/PublicKey , or from 
http://www.cs.rutgers.edu/~keane/PublicKey . Beginning
10/15, all sensitive internal email will be encrypted!