tcpdump mailing list archives
more print-bgp issues
From: George Bakos <gbakos () ists dartmouth edu>
Date: Sun, 15 Dec 2002 00:13:54 -0500
A denial of service vulnerability exists in the new (> Dec 11 cvs) print-bgp module in the way IPv4 Withdrawal prefix lengths are validated. If IPv6 is not enabled, the function decode_prefix4() is called to breakout the prefix length and network prefix fields of the UPDATE message. In bgp_update_print, a pointer (i) is incremented with the returned length and thus traverses all withdrawn routes in the UPDATE message. However, if the prefix length is > 32, decode_prefix4() returns -1. As the pointer "i" then decrements, instead of incrementing, an infinite loop is created, halting any further packet analysis and creating a very nice cpu sponge. Correct behavior (and I believe, the original intent) would be to trap the -1 return value and break out of the decode. In the packet below, I have specified a withdrawn route prefix length of 33 bits; clearly nonsensical for IPv4. The commandline tcpdump -nvs0 (or any other snaplen large enough for a full decode), or reading from a file, results in the loop: [gbakos@lt1 gbakos]$ xxd /tmp/bgpkiller 0000000: d4c3 b2a1 0200 0400 0000 0000 0000 0000 ................ 0000010: ffff 0000 0100 0000 2251 fa3d 2a78 0400 ........"Q.=*x.. 0000020: 5900 0000 5900 0000 0004 5a4e e894 0000 Y...Y.....ZN.... 0000030: 39b7 373b 0800 4500 004b e269 4000 6006 9.7;..E..K.i@.`. 0000040: 420d 81aa f989 81aa f957 00b3 0016 e976 B........W.....v 0000050: b7d3 1382 8d2f 8018 16d0 e62e 0000 0101 ...../.......... 0000060: 080a 000d f1c6 0438 2560 ffff ffff ffff .......8%`...... 0000070: ffff ffff ffff ffff ffff 0017 0200 0221 ...............! 0000080: 21 ! Although the loop condition is not seen in the case of silly NLRI prefix lengths (there is a check for retval < 0), the first updated route is still printed, resulting in potentially inaccurate reporting, if not gibberish. The following patch addresses the loop problem, and also intervenes whenever the length exceeds 32 bits (in IPv4) regardless of message type: *** print-bgp.c Wed Dec 11 02:13:58 2002 --- print-bgp.c.fixed Sat Dec 14 21:26:07 2002 *************** *** 876,882 **** case SAFNUM_MULTICAST: case SAFNUM_UNIMULTICAST: advance = decode_prefix4(tptr, buf, sizeof(buf)); ! printf("\n\t %s", buf); break; case SAFNUM_LABUNICAST: advance = decode_labeled_prefix4(tptr, buf, sizeof(buf)); --- 876,885 ---- case SAFNUM_MULTICAST: case SAFNUM_UNIMULTICAST: advance = decode_prefix4(tptr, buf, sizeof(buf)); ! if (advance >= 0) ! printf("\n\t %s", buf); ! else ! printf("\n\t (illegal prefix length)"); break; case SAFNUM_LABUNICAST: advance = decode_labeled_prefix4(tptr, buf, sizeof(buf)); *************** *** 978,984 **** case SAFNUM_MULTICAST: case SAFNUM_UNIMULTICAST: advance = decode_prefix4(tptr, buf, sizeof(buf)); ! printf("\n\t %s", buf); break; case SAFNUM_LABUNICAST: advance = decode_labeled_prefix4(tptr, buf, sizeof(buf)); --- 981,990 ---- case SAFNUM_MULTICAST: case SAFNUM_UNIMULTICAST: advance = decode_prefix4(tptr, buf, sizeof(buf)); ! if (advance >= 0) ! printf("\n\t %s", buf); ! else ! printf("\n\t (illegal prefix length)"); break; case SAFNUM_LABUNICAST: advance = decode_labeled_prefix4(tptr, buf, sizeof(buf)); *************** *** 1287,1292 **** --- 1293,1299 ---- printf("\n\t Withdrawn routes: %d bytes", len); #else char buf[MAXHOSTNAMELEN + 100]; + int wpfx; TCHECK2(p[2], len); i = 2; *************** *** 1294,1301 **** printf("\n\t Withdrawn routes:"); while(i < 2 + len) { ! i += decode_prefix4(&p[i], buf, sizeof(buf)); ! printf("\n\t %s", buf); } #endif } --- 1301,1314 ---- printf("\n\t Withdrawn routes:"); while(i < 2 + len) { ! wpfx = decode_prefix4(&p[i], buf, sizeof(buf)); ! if (wpfx >= 0) { ! i += wpfx; ! printf("\n\t %s", buf); ! } else { ! printf("\n\t (illegal prefix length)"); ! break; ! } } #endif } *************** *** 1340,1349 **** while (dat + length > p) { char buf[MAXHOSTNAMELEN + 100]; i = decode_prefix4(p, buf, sizeof(buf)); ! printf("\n\t %s", buf); ! if (i < 0) break; ! p += i; } } return; --- 1353,1365 ---- while (dat + length > p) { char buf[MAXHOSTNAMELEN + 100]; i = decode_prefix4(p, buf, sizeof(buf)); ! if (i >= 0) { ! printf("\n\t %s", buf); ! p += i; ! } else { ! printf("\n\t (illegal prefix length)"); break; ! } } } return; -- George Bakos Institute for Security Technology Studies Dartmouth College gbakos () ists dartmouth edu voice 603-646-0665 fax 603-646-0666 Key fingerprint = D646 8F91 F795 27EC FF8B 8C95 B102 9EB2 081E CB85 - This is the TCPDUMP workers list. It is archived at http://www.tcpdump.org/lists/workers/index.html To unsubscribe use mailto:tcpdump-workers-request () tcpdump org?body=unsubscribe
Current thread:
- more print-bgp issues George Bakos (Dec 14)
- Re: more print-bgp issues Hannes Gredler (Dec 15)