In this blog, we’ll discuss how the zonote Electron app can be exploited via the infamous CVE-2020-35717 vulnerability. The CVE reads
zonote through 0.4.0 allows XSS via a crafted note, with resultant Remote Code Execution (because nodeIntegration in webPreferences is true).
Electron Applications
Electron is a well-known open-source library that is used by well-established firms including Microsoft, Facebook, Slack, and Docker. Using just HTML, CSS, and JavaScript, the framework allows developers to create cross-platform desktop apps. These apps can then be packaged to run on macOS, Windows, or Linux, and released through the Mac App Store or Microsoft Store.
An Electron application is essentially a combination of Chromium and Node.js, a JavaScript runtime based on the Chrome V8 JavaScript engine.
The main script defines the Electron application’s entry point (in our example, the main.js file) for running the Main process. The script that runs in the “Main” process often manages the application’s lifecycle, displays the graphical user interface and its parts, interacts with the native operating system, and produces “Renderer” processes within web pages. There can only be one Main process in an Electron application.
Although there are several issues surrounding Electron applications, this particular one (CVE-2020-35717) caught our attention as it involves an exploit chain resulting in remote code execution or RCE.
CVE-2020-35717 Vulnerability
The main issue is that the nodeIntegration property value is true. This allows document object model or DOM access to the Node.js APIs. This particular scenario could allow attackers to use cross-site scripting or XSS to call the Node.js methods, resulting in remote code execution.
If nodeIntegration property is true, each window allows complete access to the Node.js API.
For the demonstration, we are going to use Zonote v4.
zonote is a desktop note-taking application that runs on all platforms. Although the most basic function is to save a simple text note, you can also utilize markdown code or embed any type of HTML.
Hacking zonote Electron App
First let’s create a new note by double clicking on the window.
As we know (from above), the zonote Electron app can run html code so as a next step we’ll inject the HTML h1 tags.
As we can see (from the screenshot above), the web page renders the html tags. Now, we’ll try to exploit the cross-site scripting (XSS) vulnerability.
We’ll generate a new note and attach a suitable XSS payload. The payload below will execute when a legitimate user hovers the mouse over the attached link. We are doing this to see if the zonote Electron application is vulnerable to an XSS attack.
<a onmouseover="alert('XSS!')">Test XSS</a>
Since we have a working XSS payload we can try for a remote code execution attack.
We have access to the Node.js API because nodeIntegration is set to true. To call an external URI, we’ll utilize Electron’s shell module. Below, we’re loading the “calc.exe” executable with our payload.
<a onmouseover="try{ const {shell} = require('electron'); shell.openExternal('file:C:/Windows/System32/calc.exe') }catch(e){alert(e)}"> Calculator</a>
We can replace “calc.exe” executable with any malicious executable giving the attacker complete control of the victim’s system. Alternatively, an attacker can eliminate any user involvement and have the payload run as soon as the markdown file is processed and trigger the remote code execution.
Mitigation
Cross-site scripting (XSS) attacks are more damaging if an attacker can exit the renderer process and execute code on the user’s machine. Cross-site scripting attacks are quite prevalent, although their potency is generally confined to the website they are run on. Disabling Node.js integration helps prevent XSS attacks from becoming RCE attacks.
// Bad const mainWindow = new BrowserWindow({ webPreferences: { contextIsolation: false, nodeIntegration: true, nodeIntegrationInWorker: true } }) mainWindow.loadURL('https://example.com')
Even if developers disable Node.js integration, they can still expose APIs to the application that utilize Node.js modules or functionality. Preload scripts continue to have access to require and other Node.js features, allowing developers to expose a custom API to remotely loaded content via the contextBridge API.
// Good const mainWindow = new BrowserWindow({ webPreferences: { preload: path.join(app.getAppPath(), 'preload.js') } }) mainWindow.loadURL('https://example.com')
For more information you can refer to this link.
We will try exploiting more desktop applications in our upcoming blogs. Till then … stay safe, stay healthy, and hack responsibly.
By partnering with Redfox Security, you’ll get the best security and technical skills required to execute an effective and thorough penetration test. Our offensive security experts have years of experience assisting organizations in protecting their digital assets through penetration testing services. To schedule a call with one of our technical specialists, call 1-800-917-0850 now.
Redfox Security is a diverse network of expert security consultants with a global mindset and a collaborative culture. With a combination of data-driven, research-based, and manual testing methodologies, we proudly deliver robust security solutions.
“Join us on our journey of growth and development by signing up for our comprehensive courses, if you want to excel in the field of cybersecurity.”