Security

Pentesting mDNS and Service Discovery: Exploiting Trust Assumptions

Multicast DNS (mDNS) and DNS Service Discovery (DNS-SD) are ubiquitous protocols, now enabled by default in many tech products—especially those intended for home or small office networks. In this article, I’ll cover what a pentester needs to know about mDNS and DNS-SD and how to leverage these technologies to their advantage.

info

This is a translation of an article by Mark E. Haase, first published on the Hyperion Gray blog. Translated by Alyona Georgieva.

What is mDNS?

The official websites for Multicast DNS and DNS Service Discovery are more likely to confuse than clarify what these technologies are about. So before we dive into the security aspects of mDNS and DNS-SD, let’s first talk about why these protocols exist and what they actually do.

Both protocols are part of Zeroconf—a suite of technologies that lets networked devices discover each other automatically. When you send a document to print and your computer automatically suggests nearby printers, it’s most likely using Zeroconf. The protocols build on DNS, so you should at least have a basic understanding of how the DNS system works.

Normally, DNS uses unicast—each query is sent to a specific IP address. In mDNS, multicast means the query is fanned out to all devices in the broadcast domain. The term “broadcast domain” basically means all Layer 2 neighbors—for example, hosts connected through network switches. That’s important because mDNS queries don’t cross routers, since routers operate at Layer 3.

Let’s look at an example. My MacBook Pro’s mDNS hostname is MehBook.local. You can find this in the System Settings → Sharing pane.

To determine the MacBook’s IP address, we can use a DNS query tool like dig:

$ dig @224.0.0.251 -p 5353 +short MehBook.local
10.105.0.203

Note that the name ends with .local — this is a top-level domain reserved specifically for mDNS. If you see a name like that, you can probably resolve the IP address using mDNS. These domain names are called link-local names because they’re only visible within the local network.

info

Heads up: some sysadmins misuse the .local TLD with unicast DNS. Stay alert and be careful!

Instead of sending a query to a DNS server on port 53, we use port 5353 and the special address 224.0.0.251—a multicast address. This specific address is reserved for mDNS. When a query goes to 224.0.0.251, every device on the local network receives a copy and can respond. In our example, my MacBook saw the query and replied with its own IP address, 10.105.0.203.

My MacBook’s IP address is dynamic—it will change over time—but its mDNS hostname stays the same. That means we can use hostnames without running a DNS server. You can see why that’s handy on home and small office networks.

What Is DNS-SD?

In the mDNS example, we looked up a device’s IP address when we already knew its name. But what if you want to reach a device whose name you don’t know—say, a printer? That’s exactly what Service Discovery is for. It lets devices advertise the specific services they offer so they can be discovered without any centralized configuration.

Let’s start by enumerating the printers:

$ dig @224.0.0.251 -p 5353 -t ptr +short _printer._tcp.local
Brother\032DCP-L2540DW\032series._printer._tcp.local.

We can use the same multicast DNS address and port, but this time we query for PTR records and use the special domain name _printer._tcp.local, which is specifically for printer discovery. In response to this query, my Brother printer returned its local hostname.

If you want to query devices for other services, check their official registry. For example, there’s the RAOP service—Apple’s AirTunes protocol. Let’s discover it:

$ dig @224.0.0.251 -p 5353 -t ptr +short _raop._tcp.local
C8D083XXXXXX\@Living\032Room._raop._tcp.local

The query shows a device on my network advertising the RAOP service — an Apple TV named “Гос­тиная” (Living Room). I actually have two Apple TVs on this network, but dig only prints the first response it receives. Fortunately, there are better tools. On macOS, use the dns-sd command from the Rendezvous (Bonjour) framework, Apple’s implementation of Zeroconf.

$ dns-sd -B _raop._tcp
Browsing for _raop._tcp
DATE: —Sun 16 Sep 2018—
10:02:18.236 …STARTING…
Timestamp Domain Service Type Instance Name
10:02:18.237 local. _raop._tcp. D0D2B0XXXXXX@Bedroom
10:02:18.238 local. _raop._tcp. C8D083XXXXXX@Living Room
^C

This command will broadcast a query and display every response it receives (press Ctrl-C to stop). Now we can see both of my Apple TVs.

On Linux, the same set of tools is provided by the Avahi package (on Debian/Ubuntu it’s called avahi-utils).

$ avahi-browse _raop._tcp

  • IPv6 D0D2B0XXXXXX@Bedroom AirTunes Remote Audio local
  • IPv6 C8D083XXXXXX@Living Room AirTunes Remote Audio local
  • IPv4 D0D2B0XXXXXX@Bedroom AirTunes Remote Audio local
  • IPv4 C8D083XXXXXX@Living Room AirTunes Remote Audio local
  • ^C

Avahi can translate service names like _raop._tcp.local into something more readable—AirTunes Remote Audio local, for example. It can also resolve the IP via mDNS, so dig isn’t needed here:`

$ avahi-resolve --name Bedroom.local
Bedroom.local 10.105.0.230

info

Note that in an mDNS query we don’t include values like _raop._tcp—that’s a service type, not a device. We also don’t put anything before the @ symbol.

Enumerating Devices

Now you can see why Zeroconf is appealing to pentesters: it lets you quickly enumerate a whole list of accessible devices with just a couple of queries. And Avahi goes a step further by automating the process. For example, you can realistically bundle service discovery and mDNS-based IP resolution into a single step.

$ avahi-browse --resolve _printer._tcp

  • enp4s0 IPv4 Brother DCP-L2540DW series UNIX Printer local
  • = enp4s0 IPv4 Brother DCP-L2540DW series UNIX Printer local
  • hostname = [brotherB85F3190.local]
  • address = [10.105.0.3]
  • port = [515]
  • txt = [“UUID=e3248000-XXXX-XXXX-XXXX-XXXXXXXXXXXX”
  • “TBCP=F” “Transparent=T” “Binary=T” “PaperCustom=T”
  • “Scan=T” “Fax=F” “Duplex=T” “Copies=T” “Color=F” …]
  • ^C

As a result, we get the local hostname, IP address, and port (tcp/515—the default port for the Line Printer Daemon), plus lots of information about the printer’s capabilities in the txt field.

The command we used here is a great way to enumerate all devices of a specific type, but Avahi can do even more. The next command lists all service types at once.

$ avahi-browse --all

  • IPv6 8FB20F14F5966F78620XXXX iPod Touch Music Library local
  • IPv6 276A1455BC533567B08XXXX iPod Touch Music Library local
  • IPv4 8FB20F14F5966F78620XXXX iPod Touch Music Library local
  • IPv4 276A1455BC533567B08XXXX iPod Touch Music Library local
  • IPv6 8FB20F14F5966F78620XXXX _appletv-v2._tcp local
  • IPv6 276A1455BC533567B08XXXX _appletv-v2._tcp local
  • IPv4 8FB20F14F5966F78620XXXX _appletv-v2._tcp local
  • IPv4 276A1455BC533567B08XXXX _appletv-v2._tcp local
  • ^C

Finally, Avahi can passively listen for Zeroconf (mDNS/DNS‑SD) queries from other devices, enabling background device discovery.

$ avahi-browse -a

  • IPv6 MehBook _companion-link._tcp local
  • IPv6 Bedroom _companion-link._tcp local
  • IPv6 Living Room _companion-link._tcp local
  • IPv4 MehBook _companion-link._tcp local
  • ^C

You can use either command together with --resolve to get the IP addresses and ports for each device—your whole network at a glance.

And of course, it’s worth mentioning that Nmap can enumerate Zeroconf devices using the broadcast-dns-service-discovery script.

$ nmap --script=broadcast-dns-service-discovery
Starting Nmap 7.60 ( https://nmap.org ) at 2018-09-18 11:40 EDT
Stats: 0:00:03 elapsed; 0 hosts completed (0 up)
NSE Timing: About 0.00% done
Pre-scan script results:
| broadcast-dns-service-discovery:
| 224.0.0.251
| 80/tcp privet
| txtvers=1
| ty=Brother DCP-L2540DW series [ACD1B8XXXXX]
| note=Brother DCP-L2540DW series
| url=https://www.google.com/cloudprint
| type=printer
| id=10d70d78-XXXX-XXXX-XXXX-XXXXXXXXXXXX
| cs=online
| Address=10.105.0.3
…snip…

This script isn’t included in the default category — you can only find it under safe.

A Note on Limitations

  • This only works on the local network, so you need access to it.
  • Large enterprise networks are typically segmented, so you’ll need a foothold inside the specific segment you care about.
  • Many important services don’t advertise via DNS-SD, so you’ll have to discover those systems by other means.
  • Because these are broadcast-style protocols, think carefully about whether your tactics and strategy can safely make use of them.

Exploitation

Okay, device discovery is cool and all, but is there anything we can actually exploit? We found a bunch of printers and an Apple TV—now what?

First, keep in mind that home and small office network gear that relies on Zeroconf is very likely to have misconfigurations and vulnerabilities. One simple example: if a printer authenticates against an LDAP server and that server still uses the vendor’s default password, you can compromise the server, trick the printer into connecting to it, and steal the printer’s LDAP credentials. That way you can pretty quickly take over a domain account!

www

There’s an excellent post on GrimBlog about hijacking a printer via an LDAP server.

Second, from a security standpoint Zeroconf is similar to ARP: it assumes the local network is trusted. As we’ve already seen, Zeroconf doesn’t provide confidentiality—you can passively sniff all DNS-SD queries on the LAN. There’s no authentication either: any device on the network can respond to mDNS or DNS-SD queries. As a result, an attacker can, for example, answer queries with misspelled names (which a real domain would simply ignore). And for correctly formed queries, they can try to beat the legitimate device to the punch and advertise services that don’t actually exist.

If you’re not familiar with Responder yet, now’s the time: it’s a fantastic tool for local network spoofing (cache poisoning). In addition to mDNS, it responds to NetBIOS and LLMNR queries, making it ideal for penetration testing.

www

We’ll walk through a quick example using Responder, but if you want more detail, check out this post from 4ARMED.

I’m starting Responder on the machine I’ll use to launch the attack.

Responder sits and waits for any device on the network to make a request. I trigger that request from the victim machine: I try to look up my MacBook’s IP address but “accidentally” mistype it.

~ $ dns-sd -G v4 MehBok.local
DATE: —Tue 18 Sep 2018—
12:18:31.228 …STARTING…
Timestamp A/R Flags if Hostname Address TTL
12:18:31.229 Add 2 5 MehBok.local. 10.105.0.2 120

Note: even with a typo in the hostname, I still get a response. The Responder logs show it was the one that replied—and it redirected the victim to the attacker’s machine.

[*] [MDNS] Poisoned answer sent to 10.105.0.203 for name MehBok.local

What if the victim sends a real, correctly spelled hostname? In that case, Responder tries to beat the legitimate device and reply first. For example, here I’m resolving my printer’s name.

~ $ dns-sd -G v4 brotherB85F3190.local
DATE: —Tue 18 Sep 2018—
12:27:50.695 …STARTING…
Timestamp Hostname Address TTL
12:27:50.696 brotherB85F3190.local. 10.105.0.3 240
12:27:51.916 brotherB85F3190.local. 10.105.0.2 120

The first result is the real printer’s response. The second, which arrived almost 1.2 seconds later, is a poisoned response from Responder. Most clients accept only the first response and ignore any subsequent ones, so in this case Responder didn’t succeed.

Conclusion

Zeroconf is a solid, widely available technology. You’re probably already using it at home or at work, even if you don’t realize it. Pentesters can leverage Zeroconf for quiet—or even background—device discovery. While scanning with Nmap generates lots of traffic and highly distinctive signatures, Zeroconf-based discovery uses very little traffic and blends in with normal network activity. On top of that, mDNS poisoning with Responder is a much more reliable way to pull off a man‑in‑the‑middle attack than classic ARP poisoning.

it? Share: