Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missing link-local checks in Avahi makes DDoS with mDNS traffic reflection possible #203

Closed
burghardt opened this issue Nov 8, 2018 · 3 comments
Assignees

Comments

@burghardt
Copy link

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.

@lathiat lathiat self-assigned this Dec 22, 2018
@lathiat
Copy link
Contributor

lathiat commented Dec 22, 2018

Thanks for the report. CVE-2018-1000845 appears to have been assigned for this issue.

The total amplification ability of this issue is somewhat tempered by the fact that some distro default installations (e.g. Ubuntu) do not publish any services by default (which results in no response at all) and the fact that avahi ratelimits the rate of outgoing packets to 1000/second maximum. However the issue is valid and can result in response amplification to a spoofed source.

At first glance it appears that the link local check or conversion to multicast response as specified in RFC6762 Section 11 is not being performed and needs to be added. I am investigating that further now.

@lathiat
Copy link
Contributor

lathiat commented Dec 22, 2018

CVE-2018-1000845 appears to be a duplicate of the existing CVE-2017-6519

For some reason in some cases (e.g. CVE-2017-6519) it claims the issue is valid only over IPv6, however that was not the case in my testing. The responder in https://bugzilla.redhat.com/show_bug.cgi?id=1426712 also claimed that was the case in their testing. I wonder if they were being hit by rp_filter or something? Should look into that further.

Something which I need to check, is that I only patched the 'multicast' socket receive path and not the legacy unicast socket receive path (via legacy_unicast_socket_event and dispatch_legacy_unicast_packet). That also needs patching.

It seems that on modern Ubuntu at least that the legacy unicast socket does not receive the packets. I need to research further if this is a behavior change over kernel versions or otherwise what purpose the legacy unicast socket is fulfilling on the receive side now.

@lathiat lathiat reopened this Dec 22, 2018
@lathiat
Copy link
Contributor

lathiat commented Dec 22, 2018

Testing Steps:

You can generate a legitimate legacy unicast query as follows:
dig HOSTNAME.local @DEST_IP -p 5353

Note that for the test scapy to work, you have to publish an _ssh._tcp service, e.g. put the example ssh.service into /etc/avahi/services. To avoid that, you can query for the machine's mdns hostname as an A record instead.
send(IP(src="1.1.1.1",dst="DEST_IP")/UDP(sport=53, dport=5353)/DNS(rd=1,qd=DNSQR(qtype="A", qname="HOSTNAME.local.")))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants