We have an XSS in a desktop application, what happens next? How can you escalate it to remote code execution? Let's see.
Modern desktop applications are mostly1 based on Chromium. There are three major frameworks:
- Electron: The most popular one.
- Chromium Embedded Framework.
- QtWebEngine: A part of the Qt framework (pronounced like
cute
).
There also some miscellaneous frameworks like NW.js. I have only seen a single commercial app using this framework and it was six years ago when I was still doing consulting at good ole' Cigital.
What's The JavaScript Bridge?
There are two kinds of browser-based desktop applications:
- Just displays a website in Electron, e.g., Trello.
- Also interacts with the machine, e.g., Steam.
The JavaScript bridge is a set of APIs that allow the web content in the application to interact with the host machine. In Steam (based on CEF), you click on the install button on a web page displayed in the app and a game gets installed on your machine. The web page button calls some JavaScript and eventually it uses the JavaScript bridge to do stuff on the machine.
Why is The JavaScript Bridge Important?
Rogue JavaScript (e.g., via XSS) can use it to jump the browser sandbox and do bad things to the underlying machine.
XSS Happens (lol)
"But I am not gonna have XSS, Parsia." You will, my friend. Even if you do everything right, you might get hit by a framework bypass.
Examples
As is tradition, we're gonna review public bugs. That's how I learn.
Razer Comms - CEF
Years ago (probably around 2015), I looked at Razer Comms. Think of it as the precursor to Discord. Razer Comms was a CEF app and I managed to get a few trivial XSS instances there.
Not knowing what to do next, the best I could do was show a prompt to phish user's passwords. Now, I wish I had explored the JavaScript bridge to see what else I could have done.
I never disclosed them and published a post after it was retired:
Origin XSS to RCE - QtWebEngine
Disclosure: I work for EA and Origin is one of our products.
I have used this bug numerous times. There are a few reasons:
- It's a cool bug.
- It's one of the few public Origin bugs I can talk about.
- I know Origin like the back of my hand (at least I think so).
XSS happened because of an AngularJS sandbox bypass. This is one of those
situations when you can do everything correctly but get hit. We see a typical
alert
.
But the last section named The Third Bug (RCE) explores
the JavaScript bridge. Origin is using the QtWebEngine to display web pages and
the Origin.client.desktopServices
API is available. The weapon of choice is
asyncOpenUrl
which allows us to pass a scheme (including file:///
to execute
files), but no parameters.
Overwolf XSS to RCE - CEF
This is a new one by Joel Noguera of SwordBytes Security. You should read it:
- https://swordbytes.com/blog/security-advisory-overwolf-1-click-remote-code-execution-cve-2021-33501/
I am not gonna go through the blog post, but here's a summary (quoting myself again lol):
CEF App -> Protocol Handler -> Send request -> Response has XSS -> XSS calls JavaScript bridge API -> Write file with API -> Execute file with API
Let's focus on the Escaping the CEF sandbox
section. The Overwolf JavaScript
bridge provides a openUrlInDefaultBrowser(url) which is
similar to what we have seen before. We can open URL/file or execute files
without parameters.
But there's also writeFileContents which allows writing a file to disk. The rest of the path is clear, write a bat file (or an HTA file if you feel fancy) and then execute it with the previous API.
Electron - Not Again!
I have purposefully not talked about Electron in this post. Electron has the
ultimate JavaScript bridge with nodeIntegration
. I have talked about it a lot.
Even, when it's disabled, RCE happens (this is a great writeup,
btw). With the Electron defaults becoming more secure, we need to start using
the techniques in this blog.
Here's a ton of examples (including two of mine):
What Did We Learn Here Today?
XSS happens. After you get XSS in a modern desktop app, start poking the JavaScript bridge to jump out of the Chromium sandbox.
I say almost because I might be missing some but I have never seen desktop apps based on another browser. ↩︎