Tabletopia: from XSS to RCE
During this period of social isolation, a friend of mine proposed to play some online “board games”. He proposed “Tabletopia”: a cool sandbox virtual table with more than 800 board games.
Tabletopia is both accessible from its own website and from the Steam’s platform.
We finished the game and begin logging out, but as soon as we left our room, my payload started popping out from Tabletopia’s Steam Client and some of my friends’ browsers.
“OMG VoidSec, you broke it!”
Triggering the Cross Site Scripting (XSS)
I’ve created a new account, joined a new room and started debugging the issue.
- Account 1: Firefox Browser
- Account 2: Steam Client
In Tabletopia there are 3 “different” chat-like areas:
- Cross players server chat
- Player’s room chat
- In-game chat
I didn’t want to impact other’s account, so I focused on the last two.
In the player’s room chat I’ve started putting some very cross site scripting (XSS) basic payload like:
<script>alert(“VoidSec”);</script>, nothing happened (on both accounts).
I’ve then started a new game and repeated the process, again nothing happened but as soon as one player left the room, the payload was executed in its context. Cool.
Steps to reproduce:
- Player 1: Create a room and host any game on Tabletopia’s platform.
- Player 2: join the room.
- Player 1: start the game.
- Now any players in the room have access to the in-game chat. Providing a comment like:
- As soon as one player leave the game (or return to the lobby), the previous payload get executed.
Impact of the XSS was high, as an attacker would have been able to perform the following attacks:
- User session hijacking (stealing player’s session cookies).
- In case of a premium account, having access to all the Tabletopia’s functionalities for free.
- Perform redirects to other websites / pages.
- Change/edit the UI, for example, creating a new window posing as Tabletopia / Steam in order to phish and steal users’ credentials.
- Conduct other social engineering attacks (eg. convince a user to download a backdoored update).
I’ve used BeEF to fingerprint Tabletopia’s Steam Client.
browser.capabilities.activex: No browser.capabilities.flash: No browser.capabilities.googlegears: No browser.capabilities.phonegap: No browser.capabilities.quicktime: No browser.capabilities.realplayer: No browser.capabilities.silverlight: No browser.capabilities.vbscript: No browser.capabilities.vlc: No browser.capabilities.webgl: No browser.capabilities.webrtc: Yes browser.capabilities.websocket: Yes browser.capabilities.webworker: Yes browser.capabilities.wmp: No browser.date.datestamp: Sun Mar 22 2020 14:00:17 GMT+0100 (W. Europe Standard Time) browser.engine: Blink browser.language: en-US browser.name: C browser.name.friendly: Chrome browser.name.reported: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36 browser.platform: Win32 browser.plugins: Chromium PDF Viewer browser.version: 53
Chrome? Strange, I’ve then fired up “Process Hacker” and started further “debugging” the issue.
Tabletopia.exe utilize the CefSharp.BrowserSubprocess.exe to render the web application (game). Researching a bit into it I’ve discovered that CefSharp.BrowserSubprocess.exe belongs to CEFSharp; CEFSharp lets embed Chromium in .NET application.
From XSS to RCE
Given the fact that the Tabletopia’s Steam Client was utilizing Chromium, I’ve then started gathering more information.
Chrome 53.0.2785 last release was in 2016-08-31, checking with the CEFSharp Github repo, I was able to determine that the master branch of CEFSharp is on Chrome 80.
For some reason Tabletopia’s version wasn’t the latest available, anyway, I’ve looked at the process command line and discovered another problem. Can you spot it?
CefSharp.BrowserSubprocess.exe --type=renderer --no-sandbox --primordial-pipe-token=90[SNIP] --lang=en-US --lang=en-US --log-file="D:\SteamLibrary\steamapps\common\Tabletopia\debug.log" --enable-system-flash=1 --enable-pinch --device-scale-factor=1 --num-raster-threads=4 --content-image-texture-target=3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553 --video-image-texture-target=3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553 --disable-accelerated-video-decode --disable-webrtc-hw-encoding --disable-gpu-compositing --mojo-channel-token=59[SNIP] --mojo-application-channel-token=90[SNIP] --channel="20[SNIP]" --mojo-platform-channel-handle=35 /prefetch:1 --wcf-enabled
Yes, the -–no-sandbox flag!
–no-sandbox, in fact, is an important security boundary.
“Sandbox leverages the OS-provided security to allow code execution that cannot make persistent changes to the computer or access information that is confidential.”
More on the sandbox design here.
Disabled sandbox leave the browser in an insecure state were, if compromised, an attacker will easily have full control of the underlying operative system.
- sandbox disabled.
- an old (Chrome) Chromium version.
- and a context where I was able to run arbitrary JS code (thanks to the previously identified XSS).
was the perfect recipe for a disaster.
Without the sandbox, I could have exploited every Tabletopia’s Steam Client users just recycling any released Chrome’s exploit during the last 4 years (eg. Kurucsai’s Exploit).
A big shout out to: Tabletopia’s development team for the prompt fix and the great communication, resulting in a successfully Coordinated Vulnerability Disclosure; to Valve’s security department that put me in contact with the right person at Tabletopia.
That’s an happy ending story on how, in my opinion, all security disclosures should be coordinated and handled. Despite not being the latest coolest super bug that will doom us all, I’ve decided to publish this anyway, in order to share a methodology on how (sometimes insignificant) vulnerabilities can be chained into a more critical one.
To Tabletopia’s players, keep on (safely) rolling the dice! To my fellows security researchers, see you in the cyberspace arena.
- 22 March 2020: Issue discovered.
- 22 March 2020: Tried to contact Tabletopia’s support with no success.
- 24 March 2020: Contacted Valve security department.
- 25 March 2020: Valve Security Department linked me with Tabletopia’s CEO.
- 25 March 2020: Security advisory shared with Tabletopia’s CEO and CTO.
- 06 April 2020: Tabletopia released a patch.
- 06 April 2020: VoidSec checked and confirmed the fix.
- 08 April 2020: VoidSec advisory and blog post is sent for review.
- 09 April 2020: VoidSec advisory and blog post is published.