Opened 5 years ago

Last modified 2 years ago

#13155 new defect

I can use an extend cell to remotely determine whether two relays have a connection open

Reported by: arma Owned by:
Priority: Medium Milestone: Tor: unspecified
Component: Core Tor/Tor Version:
Severity: Normal Keywords: needs-insight needs-design security maybe-wontfix
Cc: Actual Points:
Parent ID: Points:
Reviewer: Sponsor:


Send an extend cell to relay A, listing the address and identity key of relay B but the wrong port.

Relay A calls circuit_extend() for the new cell, which calls channel_get_for_extend(), which tries to figure out if there's a canonical connection already established. To do that, it asks

    if (!channel_is_canonical(chan) &&
         channel_is_canonical_is_reliable(chan) &&
        !channel_matches_target_addr_for_extend(chan, target_addr)) {

and channel_matches_target_addr_for_extend() turns into channel_tls_matches_target_method() which basically is

  return tor_addr_eq(&(tlschan->conn->real_addr), target);

It doesn't consider the port. So if there is a canonical channel open, bingo we use it.

But if there isn't one open, then off we go to make one:

      n_chan = channel_connect_for_circuit(&ec.orport_ipv4.addr,
                                           (const char*)ec.node_id);

where ec.orport_ipv4.port was set from extend_cell_parse(), i.e. it came from our extend cell. If we specify the wrong port, that connect attempt will fail. Now we can distinguish, remotely, which situation we're in.

Child Tickets

Change History (12)

comment:1 Changed 5 years ago by arma

I wonder how thorough a fix it would be to check if it's an identity key and address we know from the consensus, and if so, use the canonical port instead of the one we found in the extend cell.

I guess that situation would fail in the case where the relay had just changed its port but kept the same address, and whoever sent the extend cell knew it but we haven't noticed it yet. That situation is plausible, especially for relays who set e.g. 'orport auto'.

Another option would be to avoid setting the is_canonical flag if the port we've been asked for isn't the one the directory tells us to expect, or or avoid using a canonical circuit if the port we used for that circuit doesn't match the port we've just been asked for. That might help some? Hm.

comment:2 Changed 5 years ago by Sebastian

won't timing give this away pretty reliably, too?

comment:3 in reply to:  2 Changed 5 years ago by arma

Replying to Sebastian:

won't timing give this away pretty reliably, too?

Yes (probably) -- you could ask to connect to the right addr:port for the relay, and see if you succeed quickly or slowly.

But in that case you're modifying the thing you're measuring. The above attack leaves it in whatever state it's in (e.g. so you can measure it again soon after).

comment:4 Changed 5 years ago by cypherpunks

Information leaked by this and similar bugs was used to tracing long-lived connections (pdf).
It's #6799 bug related.

Last edited 5 years ago by cypherpunks (previous) (diff)

comment:5 Changed 5 years ago by cypherpunks

This bug is not about port only, if any open channel for requested digest is canonical then no matter address or port. Relays prefer canonical connection, for most cases they connected in between using canonical connection, or no any connection in between installed yet. Attacker can to send extend request for scanning digest with controllable addresses as target. No timings for attack need, 99% of determinism.

comment:6 Changed 5 years ago by cypherpunks

And port part, or absent of port part if to say correctly, can be used for another bug.

    if (chan->state != CHANNEL_STATE_OPEN) {
      /* If the address matches, don't launch a new connection for this
       * circuit. */
      if (channel_matches_target_addr_for_extend(chan, target_addr))

If no connection installed yet from relay A to relay B, then attacker can to introduce DoS situation by sending storm of extend requests to relay A, with valid digest and address of relay B but with wrong port. Depends firewall settings of target it could be very hard for legal requests to finish successfully.

comment:7 Changed 5 years ago by cypherpunks

First fix is to compare port by channel_matches_target_addr_for_extend, it will prevent broken logic for every case. If client requested address:port other than relay had for already open non-canonical connection then relay should not to reuse non canonical connection for such request.

comment:8 Changed 5 years ago by cypherpunks

First fix

And then we have mess of inbound or outbound connection, with port which nothing means for inbound connection if no information about peer known from current consensus.

comment:9 Changed 3 years ago by teor

Milestone: Tor: 0.2.???Tor: 0.3.???

Milestone renamed

comment:10 Changed 2 years ago by nickm

Keywords: tor-03-unspecified-201612 added
Milestone: Tor: 0.3.???Tor: unspecified

Finally admitting that 0.3.??? was a euphemism for Tor: unspecified all along.

comment:11 Changed 2 years ago by nickm

Keywords: tor-03-unspecified-201612 removed

Remove an old triaging keyword.

comment:12 Changed 2 years ago by nickm

Keywords: needs-insight needs-design security maybe-wontfix added
Severity: Normal
Note: See TracTickets for help on using tickets.