Subject: Proposed Resolution to LLMNR Issue 64: TTL Revisited

From: Bernard Aboba <[email-masked]>
Date: Wed, 17 Mar 2004 06:06:21 -0800 (PST)

The text of LLMNR Issue 64 is enclosed below.

The proposed resolution is as follows:

In Section 2.4, change:

"Unicast LLMNR queries SHOULD be sent using TCP."

To:

"Unicast LLMNR queries MUST be sent using TCP."

Change:

"Unicast UDP queries MAY be responded to with a UDP response containing
an empty answer section and the TC bit set, so as to require the sender
to resend the query using TCP."

To:

"Unicast UDP queries MUST be silently discarded."

Change:

"If an ICMP "Time Exceeded" message is received in response to a unicast
UDP query, or if TCP connection setup cannot be completed in order to
send a unicast TCP query, this is treated as a response that no records
of the specified type and class exist for the specified name (it is
treated the same as a response with RCODE=0 and an empty answer
section).  The UDP sender receiving an ICMP "Time Exceeded" message
SHOULD verify that the ICMP error payload contains a valid LLMNR query
packet, which matches a query that is currently in progress, so as to
guard against a potential Denial of Service (DoS) attack.  If a match
cannot be made, then the sender relies on the retransmission and timeout
behavior described in Section 2.7."

To:

"If TCP connection setup cannot be completed in order to
send a unicast TCP query, this is treated as a response that no records
of the specified type and class exist for the specified name (it is
treated the same as a response with RCODE=0 and an empty answer
section)."

In Section 2.5, change:

"In composing LLMNR queries, the sender MUST set the Hop Limit field in
the IPv6 header and the TTL field in IPv4 header of the response to one
(1).  Even when LLMNR queries are sent to a link-scope multicast
address, it is possible that some routers may not properly implement
link-scope multicast, or that link-scope multicast addresses may leak
into the multicast routing system.  Therefore setting the IPv6 Hop Limit
or IPv4 TTL field to one provides an additional precaution against
leakage of LLMNR queries.

In composing a response to an LLMNR query, the responder MUST set the
Hop Limit field in the IPv6 header and the TTL field in IPv4 header of
the response to one (1).  This is done so as to prevent the use of LLMNR
for denial of service attacks across the Internet.

Section 2.4 discusses use of TCP for LLMNR queries and responses.  The
responder SHOULD set the TTL or Hop Limit settings on the TCP listen
socket to one (1) so that SYN-ACK packets will have TTL (IPv4) or Hop
Limit (IPv6) set to one (1). This prevents an incoming connection from
off-link since the sender will not receive a SYN-ACK from the responder."

To:

"Section 2.4 discusses use of TCP for LLMNR queries and responses.
In composing an LLMNR query using TCP, the sender MUST set the Hop Limit
field in the IPv6 header and the TTL field in the IPv4 header of the
response to one (1).  The responder SHOULD set the TTL or Hop Limit
settings on the TCP listen socket to one (1) so that SYN-ACK packets will
have TTL (IPv4) or Hop Limit (IPv6) set to one (1). This prevents an
incoming connection from off-link since the sender will not receive a
SYN-ACK from the responder.

For UDP queries and responses the Hop Limit field in the IPv6 header,
and the TTL field in the IPV4 header MAY be set to any value.  However,
it is RECOMMENDED that the value 255 be used for compatibility with
Apple Rendezvous."

In Section 5.1, change:

"Since LLMNR is typically deployed in situations where no trust model can
be assumed, it is likely that LLMNR queries and responses will be
unauthenticated. In the absence of authentication, LLMNR reduces the
exposure to such threats by utilizing queries sent to a link-scope
multicast address, as well as setting the TTL (IPv4) or Hop Limit (IPv6)
fields to one (1) on both queries and responses.

A TTL of one (1) was chosen so as to limit the likelihood that LLMNR can
be used to launch denial of service attacks. For example, were the TTL
of an LLMNR Response to be set to a value larger than one (1), an
attacker could send a large volume of queries from a spoofed source
address, causing an off-link target to be deluged with responses.

Utilizing a TTL of one (1) in LLMNR responses ensures that they will not
be forwarded off-link. Using a TTL of one (1) to set up a TCP connection
in order to send a unicast LLMNR query reduces the likelihood of both
denial of service attacks and spoofed responses.  Checking that an LLMNR
query is sent to a link-scope multicast address should prevent spoofing
of multicast queries by off-link attackers.

While this limits the ability of off-link attackers to spoof LLMNR
queries and responses, it does not eliminate it. For example, it is
possible for an attacker to spoof a response to a frequent query (such
as an A or AAAA query for a popular Internet host), and by using a TTL
or Hop Limit field larger than one (1), for the forged response to reach
the LLMNR sender."

To:

"Since LLMNR is typically deployed in situations where no trust model can
be assumed, it is likely that LLMNR queries and responses will be
unauthenticated.  In the absence of authentication, LLMNR reduces the
exposure to such threats by utilizing UDP queries sent to a link-scope
multicast address, as well as setting the TTL (IPv4) or Hop Limit (IPv6)
fields to one (1) on TCP queries and responses.

Using a TTL of one (1) to set up a TCP connection
in order to send a unicast LLMNR query reduces the likelihood of both
denial of service attacks and spoofed responses.  Checking that an LLMNR
query is sent to a link-scope multicast address should prevent spoofing
of multicast queries by off-link attackers.

While this limits the ability of off-link attackers to spoof LLMNR
queries and responses, it does not eliminate it. For example, it is
possible for an attacker to spoof a response to a frequent query (such
as an A or AAAA query for a popular Internet host), and by using a TTL
or Hop Limit field larger than one (1), for the forged response to reach
the LLMNR sender.

When LLMNR queries are sent to a link-scope multicast
address, it is possible that some routers may not properly implement
link-scope multicast, or that link-scope multicast addresses may leak
into the multicast routing system.

Setting the IPv6 Hop Limit or IPv4 TTL field to a value larger than one
in an LLMNR UDP response may enable denial of service attacks across the
Internet.  However, since LLMNR responders only respond to queries
for which they are authoritative, and LLMNR does not provide
wildcard query support, it is believed that this threat is minimal."

An edited version of the specification incorporating these changes is
available at:
http://www.drizzle.com/~aboba/DNSEXT/draft-ietf-dnsext-mdns-30.txt

--------------------------------------------------------------------
Issue 64: TTL Revisited
Submitter name: Olafur Gudmundsson
Submitter email address: [email-masked]
Date first submitted: March 15, 2004
Reference:
http://ops.ietf.org/lists/namedroppers/namedroppers.2004/msg00299.html
Document: LLMNR-29
Comment type: T
Priority: S
Section: Various
Rationale/Explanation of issue:

The chairs are looking for closure and rough consensus on this only
remaining issue for LLMNR. The solution below seems like a good solid
compromise.

Is there any technical reason why this should not be adopted, please
state so before March 24'th.

Olafur & Olaf

Subject: Re: LLMNR and Rendezvous TTL disagreement, a modest proposal
From: Derek Atkins <[email-masked]>
Date: Tue, 24 Feb 2004 22:14:43 -0500

It sounds like you want two things here, but it also sounds like all
of them need to happen in the responder.  The attacker could
theoretically send packets of any type, with any TTL.  So you can't
trust anything you receive from the network.  To this affect, I think:

1) We want the responder to try to determine that a request came from
   the local network.  The best way to do this is for the responder to
   check that TTL=255 to make sure.  If a TTL is less than 255 then it
   originiated off-net and can be dropped.

2) We want the responder to make sure response packets don't go
   off-net.  In other words, we want the responder to respond with
   TTL=1, to make sure it can't smurf.

So, to this affect:

a) an LLMNR requestor should send requests with TTL=255
b) an LLMNR responder should verify requests have TTL=255 -- if it is not
   255 then it should drop the packet.
c) an LLMNR responder should respond with TTL=1
d) I dont' think an LLMNR requestor needs to check the response TTL.

The only issue this doesn't directly solve is a requester being
spoofed by an off-net attacker, but said attacker would need
to guess the transaction id of the request in order to send a
valid response, which is just as likely in LLMNR as it is in
standard DNS, so it can probably be ignored.

So, other than this issue, does this solve the issue?

[Christian Huitema]
Could we agree in any case that the TTL discussion does not apply when we
use TCP?

As far as I can tell, I would split the problem as follow:

1) Source address is an IPv6 local-link address: must use TTL=255, as per
IPv6. No need for special code, this is done by the stack.

2) Operation over TCP: three-ways handshake prevents spoofing. Test of
address ranges is sufficient to guarantee on-link status. Setting TTL=1
provides additional benefit.

3) Multicast query: multicast routing normally limits propagation of
packet to the local link. On-link attackers can spoof the source address;
off-link attackers generally cannot send multicast packets to the
destination. Checking the TTL provides no protection against on-link
attackers (they can set whatever TTL value is expected). Checking that the
source address belongs to an "on-link" prefix prevents the "smurf attack
to an off-link target". Setting the TTL=1 in multicast queries prevent the
side effects of a rare bug in routers, but this bug may not be very
frequent anyhow.

4) UDP unicast query: spoofing of the source address is very easy,
including for off-link attackers. Checking TTL=255 protects against
spoofing by off-link sources. Checking that the source address belongs to
a local range also affords some protection.

5) UDP unicast response: spoofing of the response requires guessing the
transaction identifier, which in practice requires an "on-link" attacker;
TTL games do not protect against on-link attackers. Setting the TTL to 1
protects against unwitting participation in a DOS-attack to an off-link
target, if the source address of the query was spoofed.

6) Setting the TTL to either 1 or 255 will create failures in some network
topologies that support multicast but require packets to go through a
router -- some wireless networks and some ad hoc networks can have that
property.

In practice, checking TTL=255 is only useful in UDP unicast queries, where
it provides a slight incremental benefit over a simple check of the source
address prefix. Setting the TTL to 1 provides a limited benefit in TCP
operation, multicast queries and unicast responses, but contradicts the
requirement of TTL=255 for IPv6 link-local addresses. Setting to either
value will create operational problems in some future scenarios.

The simplest solution is probably to remove all mentions of TTL checks
from the LLMNR document, and simply state that:
1) Nodes should verify that the source address of queries belong to an
authorized range;
2) The TTL field should be set by the stack to whatever default value is
adequate for the interface and the source address (e.g., TTL=255 for IPv6
link-local addresses.)

[Mika Liljeberg]
> Setting the TTL to 1 provides a limited benefit in TCP operation,
> multicast queries and unicast responses, but contradicts the
> requirement of TTL=255 for IPv6 link-local addresses. Setting to
> either value will create operational problems in some future
> scenarios.

This is untrue. IPv6 does not require nor enforce hop limit 255 for
link-local addresses. Only ICMPv6 neighbor discovery packets use hop
limit 255. This is not a constraint for LLMNR.

> The simplest solution is probably to remove all mentions of TTL checks
> from the LLMNR document, and simply state that:
> 1) Nodes should verify that the source address of queries belong to an
> authorized range;

This seems useful.

> 2) The TTL field should be set by the stack to whatever default value
> is adequate for the interface and the source address (e.g., TTL=255
> for IPv6 link-local addresses.)

Ok, although I would rather suggest:

2) Use TTL=1 with TCP.

3) No TTL requirements for UDP requests and responses, but recommend
setting to 255 for compatibility with Rendezvous.

[Bernard Aboba]
I'm not sure how to define an "authorized range". A host may not know
all the prefixes present on a given link.

TTL=255 on UDP request & responses only works if UDP unicast requests
are prohibited. Otherwise, LLMNR would send unicast PTR RR queries
off the local link, which is not acceptable.

An alternative would be to have no TTL requirements for multicast UDP
request and unicast UDP responses, but setting to 255 for compatibility
with Rendezvous. But requiring either TTL=1 for UDP unicast queries or
get rid of unicast UDP queries entirely.

[Christian Huitema]
Getting rid of unicast UDP queries would be by far the most robust
solution. Multicast routing pretty much guaranties that a multicast
request only travels one single hop; the TCP 3-ways handshake combined
with TTL=1 also guarantees an on-link peering.

The residual risk is address spoofing by an on-link source, to enroll
the LLMNR responder in a reflection attack. But as long as we devise the
protocol so that only one node respond to a query, we have not created
an extra vulnerability. Regular DNS servers are just as easy to enroll
in a reflection attack...

--
to unsubscribe send a message to [email-masked] with
the word 'unsubscribe' in a single line as the message text body.
archive: <http://ops.ietf.org/lists/namedroppers/>

---

From: "Christian Huitema" <[email-masked]>
Date: Wed, 17 Mar 2004 20:02:00 -0800

> Why not change it to:
> > and the TTL field in the IPV4 header SHOULD be set to 255.

Because this is a trade-off. The proper design is to use a TTL=1. The
only reason to use the 255 value, which has a larger exposure to DOS
exploitation, is compatibility with rendezvous. The text that Bernard
proposes is a fine compromise.

-- Christian Huitema