dunno why the strange combination of To/Cc headers so I'll keep bugs@ in Cc:

On Sat, Oct 24 2020, p...@centroid.eu wrote:
>>Synopsis:     a specially crafted packet can set tcpdump into an endless loop
>>Category:     system
>>Environment:
>       System      : OpenBSD 6.8
>       Details     : OpenBSD 6.8 (GENERIC.MP) #98: Sun Oct  4 18:13:26 MDT 2020
>                        
> dera...@amd64.openbsd.org:/usr/src/sys/arch/amd64/compile/GENERIC.MP
>
>       Architecture: OpenBSD.amd64
>       Machine     : amd64
>>Description:
>       I was (un)fortunate enough to have this treat of a bug from a cracker
> on the 'net.  Thanks!  They sent me an infinite loop in tcpdump.  I bug hunted
> and shared my findings on the misc@ mailing list.  I wasn't sure becuase I'm
> not the best code reader so I crafted a DOS to exploit this infinite loop.
> I have mailed OpenBSD off-lists with this proof of concept code.
>>How-To-Repeat:
> before patch:
>
> tcpdump -v -n -i lo0 port 8888
>
> 10:30:54.667969 127.0.0.1.2123 > 127.0.0.1.8888: [udp sum ok]  GTPv1-C (teid 
> 0, len 0) [MBMS Support] [MBMS Support] [MBMS Support] [MBMS Support] [MBMS 
> Support] [MBMS Support] [MBMS Support] [MBMS Support] [MBMS Support] [MBMS 
> Support] [MBMS Support] [MBMS Support] ...
> 2 packets received by filter
> 0 packets dropped by kernel
>
> This was triggered with netcat:
>
> nc -up 2123 localhost 8888 < dos.packet
>
>>Fix:
> after patch:
>
> tcpdump.p: listening on lo0, link-type LOOP
> 10:43:41.005389 127.0.0.1.2123 > 127.0.0.1.8888: [udp sum ok]  GTPv1-C (teid 
> 0, len 0) [|GTPv1-C] (ttl 64, id 58060, len 41)
> ^C
> 2 packets received by filter
> 0 packets dropped by kernel
> spica# tcpdump.p -v -n -i lo0 -Xp-sp1500pport88888
> tcpdump.p: listening on lo0, link-type LOOP
> 10:44:11.956464 127.0.0.1.2123 > 127.0.0.1.8888: [udp sum ok]  GTPv1-C (teid 
> 0, len 0) [|GTPv1-C] (ttl 64, id 18693, len 41)
>   0000: 4500 0029 4905 0000 4011 33bd 7f00 0001        E..)I...@.3.....
>   0010: 7f00 0001 084b 22b8 0015 a2bd 3400 0000        .....K".....4...
>   0020: 0000 0000 0000 0001 00                         .........
>
> ^C
> 2 packets received by filter
> 0 packets dropped by kernel
>
> The patch looks like follows:
>
> Index: print-gtp.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/tcpdump/print-gtp.c,v
> retrieving revision 1.12
> diff -u -p -u -r1.12 print-gtp.c
> --- print-gtp.c       20 May 2020 01:20:37 -0000      1.12
> +++ print-gtp.c       24 Oct 2020 08:56:00 -0000
> @@ -927,6 +927,8 @@ gtp_v1_print(const u_char *cp, u_int len
>  
>                       /* Header length is a 4 octet multiplier. */

I've never seen GTP in the wild but indeed a length of zero is invalid.
In case it can help other reviewers:

  
https://www.etsi.org/deliver/etsi_ts/129000_129099/129060/15.05.00_60/ts_129060v150500p.pdf

>                       hlen = (int)p[0] * 4;
> +                     if (hlen == 0)
> +                             goto trunc;

LGTM, though I'd suggest printing why we're bailing out.


Index: print-gtp.c
===================================================================
RCS file: /d/cvs/src/usr.sbin/tcpdump/print-gtp.c,v
retrieving revision 1.12
diff -u -p -p -u -r1.12 print-gtp.c
--- print-gtp.c 20 May 2020 01:20:37 -0000      1.12
+++ print-gtp.c 24 Oct 2020 22:02:47 -0000
@@ -927,6 +927,11 @@ gtp_v1_print(const u_char *cp, u_int len
 
                        /* Header length is a 4 octet multiplier. */
                        hlen = (int)p[0] * 4;
+                       if (hlen == 0) {
+                               printf(" [Invalid zero-length header %u]",
+                                   nexthdr);
+                               goto trunc;
+                       }
                        TCHECK2(p[0], hlen);
 
                        switch (nexthdr) {

-- 
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE

Reply via email to