Gather.town 0-day Report

VXRL
5 min readNov 1, 2021

by {FileDescriptor, Ozetta, Alanh0, Darkfloyd, Dragon, Byron, PilotOwl, Ken}

Introduction

We have found various vulnerabilities of Gather.town and reported to Gather, they have made and fixed the issues promptly and we are thankful for their generosity to gift us 2000 USD even they have no bounty program.

Discoveries

  1. RCE on Gather town desktop app
  2. Input Validation Bypass
  3. XSS on cdn.gather.town
  4. Potential blind SSRF
  5. Verification code with insufficient rate limiting

1. RCE on Gather town desktop app

Description

It was found that the desktop app, which is written in Electron, is vulnerable to RCE. It can be exploited by simply posting an external link on the chat room, and upon victims clicking on it, will allow the attacker to run arbitrary code on the victim’s machine.

Details

When unpacking the \AppData\Local\Programs\Gather\resources\app.asar file which contains the source code of the Electron of Gather Town, it was discovered that dist/main.js, which spawns the BrowserWindow object, uses the incorrectly configurations of contextIsolation and nodeIntegration
settings[1]:

webPreferences: {
preload: path_1["default"].join(__dirname, "./interop.js"),
nativeWindowOpen: true,
// We have to disable this to allow for window.require("electron"), but we may want to consider
// taking a second look at this in the future. From:
// https://www.electronjs.org/docs/breaking-changes#default-changed-contextisolation-defaults-to-true
// "We recommend having contextIsolation enabled for the security of your application."
contextIsolation: false, // <-----------
nodeIntegration: true, // <-----------
enableRemoteModule: true
},

When nodeIntegration is enabled, it will inject node objects into the main renderer. This means if the app loads a custom web page, the web page can use require('child_process').exec(...) to run arbitrary code.

To load an external web page in the app, one can post an external link in the chat room. However, if the URL is not from gather.town, it will open on an external browser instead of the app. Though, there is a bug in handling the new window:

if (IN_APP_URLS.some(function (inAppUrl) { return baseUrl.includes(inAppUrl); })) {
// load some gather urls in same window
mainWindow.loadURL(url);
}

This condition checks if the posted URL contains the string gather.town/app. Therefore, it can be simply bypassed with (e.g. https://innerht.ml/gather.town/app/).

Steps to Reproduce

  1. Use the desktop app on Windows, enter a space
  2. Post https://innerht.ml/gather.town/app/ in the chat room
  3. Click it
  4. Observe calc.exe popping up

The PoC file contains a simple payload (require('child_process').exec('calc');)

Fix

Use the correct configurations

popup calc.exe from the desktop app

2. Input Validation Bypass

Description

It was found that gather.town is vulnerable to Input Validation Bypass. The user name field validation can be bypassed with HTTP intercepting tools like Charles proxy. The attacker may be able to bypass the name field restrictions and input a massive amount of characters to block the view of other users on-screen.

Details

When we put our browser in proxy mode, we intercept all our traffic with tools like burpsuite or Charles proxy. We found that the input validation can be bypassed, and the user name can be modified and sent to the server. The attacker can input extremely long strings and block other user interactions.

Steps to Reproduce

  1. Join any event in gather.town
  2. Edit your name in event, submit and intercept the WebSocket request
  3. Modify {"event":"rpc","target":"space","args":{"space":"","type":"name","name":"<very long name>"}} and submit
  4. Refresh the page and join again
long display name
long display name

Fix

Place limit on names

3. XSS on cdn.gather.town

Description

It is found that gather.town stores user-uploaded images in Google CDN buckets, which allows an adversary to trick an user into loading malicious JavaScript hosted in a bucket controlled by the attacker. As a result, an attacker may create phishing JavaScript to steal information from the victim who clicks on a malicious link with the gather.town’s domain name.

Details

We have found that we can create a bucket under Google cloud and deploy a page with JavaScript, which can be executed under cdn.gather.town when loaded in another user’s browser.

To reproduce the bug, paste the following PoC URL, which pops up the value of document.domain, into the gather.town chatroom, and click the link from another user.
https://cdn.gather.town/storage.googleapis.com/gather-town-xss/xss.html

xss in cdn.gather.town

Fix

Do not allow using other buckets.

4. Potential blind SSRF

Description

It was found that the calendar sync function may be vulnerable to Blind SSRF. The function allows supply a custom URL and the system will fetch the file. It can potentially be allowed to send internal HTTP requests.

Steps to Reproduce

5. Verification code with insufficient rate limiting

Description

During login, Gather.town will send a one-time pad (OTP) to the designated email. Each code has a limited number of re-trial (i.e. max 4). However, users can perform an unlimited number of trials for requesting new OTP. Others may get authenticated by guessing the same OTP value with a sufficiently large number of trials.

We have attempted to brute force for 100, 000 attempts and there doesn’t seem to appear to have any blockage.

Steps to Reproduce

Fix

Apply rate-limiting for generating new OTP. For example, stopping users from sending a large number of login requests in a short period of time.

--

--

VXRL

VXRL Team is founded by group of enthusiastic security researchers, providing information security services and contribute to the community. https://www.vxrl.hk