Closed Bug 1552993 (CVE-2019-11728) Opened 5 years ago Closed 5 years ago

Extended Port Scanning with Alt-Svc on Firefox

Categories

(Core :: Networking: HTTP, defect, P1)

66 Branch
defect

Tracking

()

VERIFIED FIXED
mozilla69
Tracking Status
geckoview66 --- wontfix
firefox-esr60 --- wontfix
firefox67 --- wontfix
firefox67.0.1 --- wontfix
firefox68 --- fixed
firefox69 --- verified

People

(Reporter: trtiwari, Assigned: Gijs)

References

Details

(Keywords: sec-low, Whiteboard: [necko-triaged][adv-main68+])

Attachments

(2 files)

Attached image port-scan.png

User Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:66.0) Gecko/20100101 Firefox/66.0

Steps to reproduce:

Contributors: Trishita Tiwari (me) and Prof. Ari Trachtenberg (my advisor, email: trachten@bu.edu) from Boston University.

General Description:
The HTTP Alternative Services header (Alt-Svc) implementation on the Firefox browser may be abused by an attacker to compromise security measures, for instance, to conduct extended port scanning. (Note that other attacks related to the Alt-Svc implementation on Firefox have been filed in separate reports, as indicated in the bugzilla guidelines)

To effect these compromises, an attacker need only have the victim visit a website under the attacker’s control (either as a first party or a third party through an image/iframe).  The attacker’s website specifies an Alt-Svc header that enables the various attacks in a manner that is not visible to the victim (i.e. URL and domain name visible in the browser are not affected).

Details on extended port scanning:
The Alt-Svc header may be leveraged to force an unwitting victim to scan all TCP ports of any host that the victim can access. This includes ports that Firefox marks as unsafe and are otherwise inaccessible through JavaScript, and hosts behind the victim’s firewall or even the victim’s localhost. The attack naturally lends itself to a stealthy distributed port scanning of a target from multiple victim browsers.

The basis of this attack is the observation that if a website specifies an Alt-Svc header to a secondary host with an HTTP2 endpoint, then Firefox immediately tries to initiate a TLS handshake with the secondary host, without performing any checks on the host or port (i.e., the secondary host could even be a private IP or localhost).

The port-scanning thus proceeds with the attacker creating a webpage (e.g., https://evil.com/p1) whose Alt-Svc is set to a target host and port. When the victim then visits this page, the victim’s browser parses the Alt-Svc value and attempts to initiate a connection to the target host on the specified port:

  1. If the target port is in a closed state, the target immediately sends an RST packet to the browser and the browser registers the alternative service as broken.
  2. However, if the target port is in an open state, more packets are typically exchanged (e.g., ACKs) and the browser thus does not immediately know whether the Alt-Svc host is valid.

To discern between these two possible states of the target port, the attacker then automatically redirects the victim to a second webpage on the same attacker host (e.g., https://evil.com/p2), but whose Alt-Svc host is under the attacker’s control (e.g., h2="moreevil.com"). Two cases emerge:

  1. The browser has determined that the original Alt-Svc (i.e. the target host and port) is broken, and the redirect will produce an immediate connection to the secondary attacker site (moreevil.com) and can be logged by the attacker.
  2. The browser has not yet determined that the original Alt-Svc is broken, and the redirect will not produce a connection to the secondary attacker site (moreevil.com).

In this way the attacker can infer whether the target port was open or closed, as illustrated in the attached figure.

Actual results:

Demo: We provide a demo website that implements this. The form on the landing page asks you to enter an IP/Port combination, (which defaults to localhost:25). To test it, you could open/close any port on a machine under your control to see if the port is reported as open or closed. We would like to note that since there is a time threshold involved for discerning an open vs closed port, the results will inherently include some noise.

Demo link:
http://trishita.ddns.net:9000/h2/ip-port-entry.html

Expected results:

Mitigation: Firefox might want to institute the same port blacklist for Alt-Svcs as it does for JavaScript.

(In reply to Trishita Tiwari from comment #0)

Mitigation: Firefox might want to institute the same port blacklist for Alt-Svcs as it does for JavaScript.

For clarity, what list are you referring to?

Group: firefox-core-security → network-core-security
Component: Untriaged → Networking: HTTP
Flags: needinfo?(trtiwari)
Product: Firefox → Core
See Also: → 1553002

(In reply to :Gijs (he/him) from comment #1)

(In reply to Trishita Tiwari from comment #0)

Mitigation: Firefox might want to institute the same port blacklist for Alt-Svcs as it does for JavaScript.

For clarity, what list are you referring to?

Sorry, I meant port blocking instead of port blacklisting.
Here is the link: https://developer.mozilla.org/en-US/docs/Mozilla/Mozilla_Port_Blocking

Flags: needinfo?(trtiwari)

Do the connection attempts show up in wireshark and/or the Firefox devtools? Also, for clarity, what versions of Firefox have you tested?

Because I tried using your demo page, and using nc -lvu [port] locally, and I cannot get the demo page to recognize any ports as open (even after checking my firewall). I also don't see any requests in the Firefox devtools that go to localhost. Tested on both Firefox beta 67 and nightly 69.

Flags: needinfo?(trtiwari)

(In reply to :Gijs (he/him) from comment #3)

Do the connection attempts show up in wireshark and/or the Firefox devtools? Also, for clarity, what versions of Firefox have you tested?

Because I tried using your demo page, and using nc -lvu [port] locally, and I cannot get the demo page to recognize any ports as open (even after checking my firewall). I also don't see any requests in the Firefox devtools that go to localhost. Tested on both Firefox beta 67 and nightly 69.

I believe that this specific demo is only for TCP ports ... it tests as working on my box.

OK, I can see it reporting 0 for a high-numbered port after dropping the -u switch from nc -- though only on the second and later tries. Still no reported requests in devtools, which is sort of interesting.

Valentin, I believe this should be hitting something like the check at https://searchfox.org/mozilla-central/rev/6c9f60f8cc064a1005cd8141ecd526578ae9da7a/netwerk/base/nsBaseChannel.cpp#663 for the blocked ports, but apparently we're taking a path that doesn't hit asyncopen? Perhaps you know why that might be?

Flags: needinfo?(trtiwari) → needinfo?(valentin.gosu)

I believe the code path is nsHttpChannel::ProcessAltService() then AltSvcMapping::ProcessHeader which sets the AltSvcMapping here.

I think adding a NS_CheckPortSafety check to AltSvcMapping::ProcessHeader might be enough to fix it.

Flags: needinfo?(valentin.gosu)

(In reply to Valentin Gosu [:valentin] (he/him) from comment #6)

I believe the code path is nsHttpChannel::ProcessAltService() then AltSvcMapping::ProcessHeader which sets the AltSvcMapping here.

Thanks - sorry, I should have been more clear. I did notice those bits of code, but I would have assumed that we would record some kind of redirect on the channel and asyncopen would be called again on the new channel (or something similar). Looking at the code, I guess the altsvc code just updates mConnectionInfo on the extant channel from BeginConnect() and that's what gets used for the actual network request? Is that reading of the code correct? And are there any other ways that type of thing could happen where we bypass those checks for tcp connections in necko? Could we move the checks closer to where we call into socket code or would that make propagating errors more difficult?

I think adding a NS_CheckPortSafety check to AltSvcMapping::ProcessHeader might be enough to fix it.

Right, just making sure this doesn't end up as whack-a-mole with loads of other places to update...

Flags: needinfo?(valentin.gosu)
Status: UNCONFIRMED → NEW
Ever confirmed: true

CC'ing Dimi in case the discussion here helps with 1552999.

(In reply to :Gijs (he/him) from comment #7)

(In reply to Valentin Gosu [:valentin] (he/him) from comment #6)

I think adding a NS_CheckPortSafety check to AltSvcMapping::ProcessHeader might be enough to fix it.

Right, just making sure this doesn't end up as whack-a-mole with loads of other places to update...

Dragana knows that code a bit better.

Flags: needinfo?(valentin.gosu)
Flags: needinfo?(dd.mozilla)

(In reply to Valentin Gosu [:valentin] (he/him) from comment #10)

(In reply to :Gijs (he/him) from comment #7)

(In reply to Valentin Gosu [:valentin] (he/him) from comment #6)

I think adding a NS_CheckPortSafety check to AltSvcMapping::ProcessHeader might be enough to fix it.

Right, just making sure this doesn't end up as whack-a-mole with loads of other places to update...

Dragana knows that code a bit better.

That is only place. It called for http1 header and h2 frame. There is no other possibility to add a new destination. Redirects are performing checks already.

Flags: needinfo?(dd.mozilla)
Assignee: nobody → gijskruitbosch+bugs
Priority: -- → P1
Whiteboard: [necko-triaged]

This includes ports that Firefox marks as unsafe

Note that mostly we block these because HTTP is an overly forgiving protocol, as are some services, and the browser can read data or send commands to things that would be "safe" in HTTP but maybe not in those other common protocols. A simple existence check is not violating the purpose of the port ban.

Keywords: sec-low
Blocks: 1555671
Group: network-core-security → core-security-release
Status: NEW → RESOLVED
Closed: 5 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla69

Comment on attachment 9066557 [details]
Bug 1552993 - r?valentin

Beta/Release Uplift Approval Request

  • User impact if declined: Potential security issue
  • Is this code covered by automated tests?: No
  • Has the fix been verified in Nightly?: No
  • Needs manual test from QE?: No
  • If yes, steps to reproduce: (Unfortunately, I don't think this is easily testable, bug 1555671 covers automated testing)
  • List of other uplifts needed: n/a
  • Risk to taking this patch: Low
  • Why is the change risky/not risky? (and alternatives if risky): small, targeted patch that reuses existing primitives to block certain ports, plus we have plenty of cycle time left
  • String changes made/needed: n/a
Attachment #9066557 - Flags: approval-mozilla-beta?

Could you verify with a copy of nightly (https://nightly.mozilla.org/ ) that the patch fixes the issue?

Flags: needinfo?(trtiwari)
Flags: qe-verify-

Comment on attachment 9066557 [details]
Bug 1552993 - r?valentin

necko fix, approved for 68.0b7

Attachment #9066557 - Flags: approval-mozilla-beta? → approval-mozilla-beta+

(In reply to :Gijs (he/him) from comment #16)

Could you verify with a copy of nightly (https://nightly.mozilla.org/ ) that the patch fixes the issue?

Yep, the patch fixed it. Now no connections are opened to any of the blocked ports. Thanks a lot! :)

Flags: needinfo?(trtiwari)

Marking verified per comment #18.

Status: RESOLVED → VERIFIED

(In reply to :Gijs (he/him) from comment #3)

Do the connection attempts show up in wireshark and/or the Firefox devtools? Also, for clarity, what versions of Firefox have you tested?

Sorry, I somehow missed this earlier. But none of the alt-svc connection attempts show up on devtools. I was only able to check them through wireshark. I had tried this on Firefox 66

Because I tried using your demo page, and using nc -lvu [port] locally, and I cannot get the demo page to recognize any ports as open (even after checking my firewall). I also don't see any requests in the Firefox devtools that go to localhost. Tested on both Firefox beta 67 and nightly 69.

The demo is for TCP ports only, so it should work if you drop the u flag in nc.

Whiteboard: [necko-triaged] → [necko-triaged][adv-main68+]
Alias: CVE-2019-11728

Hi!
Thanks for addressing the issue! Just a heads up, we will be presenting all the Alt-Svc attacks at USENIX WOOT this August.

Group: core-security-release
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: