>Synopsis:      wrap of length into the high 4 billion in print-etherip.c
>Category:      system
>Environment:
        System      : OpenBSD 7.2
        Details     : OpenBSD 7.2 (GENERIC.MP) #2: Thu Nov 24 23:53:03 MST 2022
                         
r...@syspatch-72-arm64.openbsd.org:/usr/src/sys/arch/arm64/compile/GENERIC.MP

        Architecture: OpenBSD.arm64
        Machine     : arm64
>Description:
        This is a good bug, good because it can't be exploited via the Internet.
But it was able to be exploited at 7.2 time with NSH to bring tcpdump to seg-
fault on a local LAN.  Luckily NSH is now fixed so I can't demonstrate that 
avenue.  The spoofed frame has an illegal IP len that routers would not carry
along for the hop but tcpdump doesn't care so much about this.

In print-etherip.c much care is taken to check plen from becoming too small but
len is passed to sub-printers after an underflow (wrap).

>How-To-Repeat:
        I changed computers and had to use vether because the old workstation
that I was using is sleeping.  Here is a tcpdump of vether and the spoofery
into it.  Notice the second packet indicates length -20 (it would be in 
print-llc.c).  That's the underflow / wrap of the unsigned integer.

tcpdump -v -n -i vether0 -X -s 1500
tcpdump: listening on vether0, link-type EN10MB
13:03:50.302274 192.168.177.13 > 255.255.255.255: etherip 3 len 0: 
192.168.177.13 > 255.255.255.255: [|udp] (ttl 255, id 0, len 20) (ttl 255, id 
0, len 20)
  0000: 4500 0014 0000 0000 ff61 49d3 c0a8 b10d  E........aI.....
  0010: ffff ffff 3000 ffff ffff ffff 0101 0101  ....0...........
  0020: 0101 0800 4500 0014 0000 0000 ff11 4a23  ....E.........J#
  0030: c0a8 b10d ffff ffff                      ........

13:08:50.234684 192.168.177.13 > 255.255.255.255: etherip 3 len 0: 
01:01:01:01:01:01 > ff:ff:ff:ff:ff:ff sap 00 I (s=0,r=0,C) len=-20 (ttl 255, id 
0, len 20)
  0000: 4500 0014 0000 0000 ff61 49d3 c0a8 b10d  E........aI.....
  0010: ffff ffff 3000 ffff ffff ffff 0101 0101  ....0...........
  0020: 0101 05dc 0000 0000 0000                 ..........
>Fix:
        The fix is rather simple.  instead of passing len to llc_print() (line
116) and ether_encap_print() (line 126 of print-etherip.c) pass snapend - pbuf.
Before that it must be tested whether pbuf is less than snapend.

(excerpt of cat -n of print-etherip.c):

   115          if (etype <= ETHERMTU) {
   116                  if (llc_print(pbuf, len, plen, ESRC(eh), EDST(eh)) == 
0) {
   126          } else if (ether_encap_print(etype, pbuf, len, plen) == 0) {



dmesg:
none.

Reply via email to