Subject: [quicwg/base-drafts] Amplification attack using retry tokens and spoofed addresses (#2064)

From: Christian Huitema <[email-masked]>
Date: Wed, 28 Nov 2018 11:46:59 -0800

We designed the Address Validation procedures to prevent QUIC servers from being used for UDP based DOS amplification attacks. By default, sending an Initial packet to a QUIC server results in up to 3 full size UDP packets sent back to the originating address, and perhaps several more if the server repeats packets on timeout. With address validation turned on, the server will only answer to Initial packets carrying a proof of origin, in the form of a "token". Once address is validated, servers are free to send many more than 3 packets in response to the Initial packets. I am concerned that the validation procedure can be bypassed with a replay attack.

Let's imagine that an attacker manages to locate itself close enough to its target to be able to observe an Initial/Retry exchange between the source address and a remote server, and obtain a copy of the Retry packet. The attacker now has enough information to manufacture an Initial packet that will pass address validation at the server, if sent from the spoofed address of the target. The attacker could then pass that information to a botnet. A large number of bots can send spoofed packets to the server, resulting in a massive attack against the target.

Whether the attack is plausible or not depends on how the server performs address validation. The current draft presents little guidance about that. If a server implementation simply verifies that the token was associated with the source address of the client, the botnet can run unimpeded. If the token also has some time to live, the attack will run unimpeded until that time. The attack will only be blocked if the server enforces that tokens are used only once, but the current draft does not require that.

I looked at how to modify the Picoquic implementation and protect against this attack. The simplest defense that I found was to embed in the ticket the Connection ID of the server. The connection ID is provided to the client as part of the retry packet, so that change is easy. Tokens could also be provided in New Token frames and sent by clients in Initial packet; the server could extract the CID from the token, and chose that for the new connection. The "server CID defense" is not perfect, but it ensures that the botnet will only be able to create one connection at a time. If tokens have a limited time to live, the attack is effectively thwarted.

I am not saying that all implementations should adopt the server CID defense. The goal is to prevent token reuse at the server, and there are certainly other ways to achieve that. I am just asking that we ask servers to prevent multiple reuses of the same token.
You can view, comment on, or merge this pull request online at:

  https://github.com/quicwg/base-drafts/pull/2064

-- Commit Summary --

  * Merge pull request #8 from quicwg/master
  * Ask servers to limit use of tokens to only once

-- File Changes --

    M draft-ietf-quic-transport.md (3)

-- Patch Links --

https://github.com/quicwg/base-drafts/pull/2064.patch
https://github.com/quicwg/base-drafts/pull/2064.diff

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064

---

From: Martin Thomson <[email-masked]>
Date: Wed, 28 Nov 2018 13:01:24 -0800

this is a good sentiment, but i feel like it is asking too much

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#issuecomment-442603028

---

From: Christian Huitema <[email-masked]>
Date: Wed, 28 Nov 2018 13:07:59 -0800

I am happy to negotiate. Instead of making a requirement on servers, we can document the attack in the security section. We should also explain to clients that servers MAY enforce single use of the tokens, and that thus they REALLY SHOULD NOT try to reuse a token multiple times.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#issuecomment-442605033

---

From: Martin Thomson <[email-masked]>
Date: Wed, 28 Nov 2018 13:13:17 -0800

yes, having no expectation that reuse is possible is fine, but the best i can think of for dos protection is a very short timer, which - for a sufficiently good amplification factor - might not be enough

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#issuecomment-442606636

---

From: ianswett <[email-masked]>
Date: Wed, 28 Nov 2018 13:19:43 -0800

ianswett commented on this pull request.

> @@ -1637,6 +1637,9 @@ able to reuse a token.  To avoid attacks that exploit this property, a server
 can limit its use of tokens to only the information needed validate client
 addresses.
 
+Fraudulently obtained tokens could enable botnets to use servers as amplifiers

```suggestion
Fraudulently obtained tokens could enable attackers to use servers as amplifiers
```

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#pullrequestreview-179521964

---

From: ianswett <[email-masked]>
Date: Wed, 28 Nov 2018 21:21:31 +0000 (UTC)

+Fraudulently obtained tokens could enable botnets to use servers as amplifiers
+in DDOS attacks. Servers SHOULD protect against such attacks by ensuring that
+tokens are used by clients only once.

I think this issue applies to non-fraudulently obtained tokens as well, but it's worse for the case you outlined in the description, since it's lower cost.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#pullrequestreview-179522683

---

From: Christian Huitema <[email-masked]>
Date: Wed, 28 Nov 2018 20:17:07 -0800

@huitema pushed 1 commit.

dbe4f5d  Update draft-ietf-quic-transport.md

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064/files/baeb9877136de5aab6d026f1d5a349ba41f70a30..dbe4f5dca11b71570e72c507f1f649298ef95392

---

From: janaiyengar <[email-masked]>
Date: Thu, 29 Nov 2018 18:56:06 -0800

It's quite a burden on server to ensure single use of tokens, and SHOULD seems too strong. I'm not sure how you enforce it... while a single server might be able to ensure single use at that server, you need some serious infrastructure to enforce it across the fleet.

Is it adequate to suggest that servers MUST include a timestamp in the token, and SHOULD expire the token within a short period of time (a few seconds)?

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#issuecomment-443073490

---

From: Christian Huitema <[email-masked]>
Date: Thu, 29 Nov 2018 19:09:40 -0800

For the basic retry, yes a short life time is plausible. You expect to see the token in the next packet. But for the NEW TOKEN frane, you need about the same lifetime as a session resume ticket.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#issuecomment-443075866

---

From: janaiyengar <[email-masked]>
Date: Thu, 29 Nov 2018 19:27:47 -0800

@huitema: right, but your attack was on a token sent in a RETRY, right?

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#issuecomment-443078730

---

From: Christian Huitema <[email-masked]>
Date: Thu, 29 Nov 2018 19:58:02 -0800

Yes, the RETRY tokens are easier to steal than the NEW TOKEN. Making sure that we protect at least that would be nice.

I am thinking at how attackers could get a NEW TOKEN valid for the target IP. You probably need to run at least one connection from the target to the amplification server. That's relatively easy if you want to demolish a public network -- connect once as a guest, get tokens from a bunch of servers, use them to flood the network access point. So yes, there is still a risk.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#issuecomment-443083103

---

From: Marten Seemann <[email-masked]>
Date: Thu, 29 Nov 2018 20:30:25 -0800

It's sufficient to be on path and observe packets sent from the client to the server to obtain a token sent in a NEW_TOKEN frame. Getting a Retry token is marginally easier, since you can observe it in both directions, but this would allow you to direct traffic to that IP address until the expiry date of the token (which might be days).

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#issuecomment-443087560

---

From: Christian Huitema <[email-masked]>
Date: Fri, 30 Nov 2018 17:31:17 +0000 (UTC)

@marten-seemann good point. The attackers can get the Token by observing a client use it.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#issuecomment-443278420

---

From: Christian Huitema <[email-masked]>
Date: Fri, 30 Nov 2018 09:46:12 -0800

How about the following rewrite:
```
Attackers could replay tokens to use servers as amplifiers
in DDOS attacks. Servers SHOULD protect against such attacks by ensuring that
tokens have a short life time. They MAY ensure that tokens are used by clients only once.
```
This takes into account Ian's comments that tokens need not be obtained fraudulently.
It also takes into account Jana's comment that on big server farms it is much easier to
limit lifetime than to enforce single use. The main point of the MAY is that it forces clients to not assume they can ever reuse a token.

Should we add a description of the attack in the security section?

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#issuecomment-443282924

---

From: MikkelFJ <[email-masked]>
Date: Fri, 30 Nov 2018 12:14:54 -0800

I think @huitema's suggestion makes sense.

But ... if a token is tied to a client IP it can't really be used as general amplification attack since the attacker would need to spoof the original client IP. This can direct traffic to a specific client, but I'm not sure this is an effective attack. So we could require tokens to encode the client IP and servers to verify it, or am I missing something?

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#issuecomment-443326158

---

From: Christian Huitema <[email-masked]>
Date: Fri, 30 Nov 2018 12:36:31 -0800

@mikkelfj the whole point of the token mechanism is to protect against spoofed IP address attacks. So, yes, attackers routinely send packets with spoofed IP addresses.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#issuecomment-443331773

---

From: MikkelFJ <[email-masked]>
Date: Fri, 30 Nov 2018 12:53:14 -0800

OK, maybe I need to read up on things. But I had this idea that the if you have the token, it is because you received it, so sending it back proves that you have the IP.

But if you can steal the token and spoof your source IP to some DDoS target the server will then attempt handshake with the target because it thinks the address has been validated.

My suggestion was to ensure that the token cryptographically encodes the IP so the attacker cannot force a handshake with anyone other than the client that it stole the token from.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#issuecomment-443336030

---

From: MikkelFJ <[email-masked]>
Date: Fri, 30 Nov 2018 13:23:02 -0800

Here is a tricky variation:

The attacker initiates a handshake with a spoofed source IP in the hope of generating a retry. The attacker is sufficiently close to the target server that it can observe retry token. It is now able to share the token with many bots that all use the token to initiated spoofed validated handshakes toward the target. Even if the token is cryptographically encoding the target IP, it will not help, because the spoofed handshakes match the token.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#issuecomment-443343644

---

From: Christian Huitema <[email-masked]>
Date: Fri, 30 Nov 2018 21:47:38 +0000 (UTC)

@mikkelfj , this suggestion is already in the spec. The problem is that a connection attempt will trigger several packets towards the spoofed address, which is an attack amplification mechanism.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#issuecomment-443349639

---

From: MikkelFJ <[email-masked]>
Date: Fri, 30 Nov 2018 14:01:03 -0800

OK thanks for explaining. Your text seems reasonable in that context. Harvesting tokens over a long time period without knowing a target in advance is different from having to steal the token real time for a brief attack.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#issuecomment-443352876

---

From: MikkelFJ <[email-masked]>
Date: Fri, 30 Nov 2018 14:15:42 -0800

The token IP validation can be disabled in some not unlikely deployments:

The server is behind a NAT'ing load balancer so all tokens get the IP of the LB. Instead of targeting the QUIC server directly, it attempts to punch a hole in the NAT with a spoofed IP and possible a token it fetched for itself through an ordinary connection, assuming the token does not cover the port number. A port number is not likely included in the token because it would prevent a new 0-length CID connection.

For reference, here is the text I failed to read:
```
There is no need for a single well-defined format for the token because the server that generates the token also consumes it. A token could include information about the claimed client address (IP and port), a timestamp, and any other supplementary information the server will need to validate the token in the future.
```

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2064#issuecomment-443356048