# Aplicaciones de Escritorio Electron
Aprende hacking en AWS de cero a héroe con htARTE (HackTricks AWS Red Team Expert)! Otras formas de apoyar a HackTricks: * Si quieres ver a tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF**, consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)! * Consigue el [**merchandising oficial de PEASS & HackTricks**](https://peass.creator-spring.com) * Descubre [**La Familia PEASS**](https://opensea.io/collection/the-peass-family), nuestra colección de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos * **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **sigue**me en **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.** * **Comparte tus trucos de hacking enviando PRs a los repositorios de github** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
## Introducción Electron se **basa en Chromium**, pero no es un navegador. Ciertos principios y mecanismos de seguridad implementados por navegadores modernos no están presentes.\ Podrías ver a Electron como una aplicación local de backend+frontend donde **NodeJS** es el **backend** y **chromium** es el **frontend**. Usualmente podrías encontrar el código de la aplicación electron dentro de una aplicación `.asar`, para obtener el código necesitas extraerlo: ```bash npx asar extract app.asar destfolder #Extract everything npx asar extract-file app.asar main.js #Extract just a file ``` En el código fuente de una app Electron, dentro de `packet.json`, puedes encontrar especificado el archivo `main.js` donde se establecen las configuraciones de seguridad. ```json { "name": "standard-notes", "main": "./app/index.js", ``` Electron tiene 2 tipos de procesos: * Proceso Principal (tiene acceso completo a NodeJS) * Proceso de Renderizado (debería tener acceso restringido a NodeJS por razones de seguridad) ![](<../../../.gitbook/assets/image (307) (5) (1).png>) Un **proceso de renderizado** será una ventana del navegador cargando un archivo: ```javascript const {BrowserWindow} = require('electron'); let win = new BrowserWindow(); //Open Renderer Process win.loadURL(`file://path/to/index.html`); ``` La configuración del **proceso de renderizado** puede ser **configurada** en el **proceso principal** dentro del archivo main.js. Algunas de las configuraciones **evitarán que la aplicación Electron obtenga RCE** u otras vulnerabilidades si las **configuraciones están correctamente establecidas**. La aplicación de escritorio podría tener acceso al dispositivo del usuario a través de las APIs de Node. Las siguientes dos configuraciones son responsables de proporcionar mecanismos para **evitar que el JavaScript de la aplicación tenga acceso directo al dispositivo del usuario** y a los comandos a nivel de sistema. * **`nodeIntegration`** - está `off` por defecto. Si está activado, permite acceder a las características de node desde el proceso de renderizado. * **`contextIsolation`** - está `on` por defecto. Si está activado, los procesos principal y de renderizado no están aislados. * **`preload`** - vacío por defecto. * [**`sandbox`**](https://docs.w3cub.com/electron/api/sandbox-option) - está `off` por defecto. Restringirá las acciones que NodeJS puede realizar. * Integración de Node en Workers * **`nodeIntegrationInSubframes`**- está `off` por defecto. * Si **`nodeIntegration`** está **habilitado**, esto permitiría el uso de las APIs de **Node.js** en páginas web que se **cargan en iframes** dentro de una aplicación Electron. * Si **`nodeIntegration`** está **deshabilitado**, entonces los preloads se cargarán en el iframe Ejemplo de configuración: ```javascript const mainWindowOptions = { title: 'Discord', backgroundColor: getBackgroundColor(), width: DEFAULT_WIDTH, height: DEFAULT_HEIGHT, minWidth: MIN_WIDTH, minHeight: MIN_HEIGHT, transparent: false, frame: false, resizable: true, show: isVisible, webPreferences: { blinkFeatures: 'EnumerateDevices,AudioOutputDevices', nodeIntegration: false, contextIsolation: false, sandbox: false, nodeIntegrationInSubFrames: false, preload: _path2.default.join(__dirname, 'mainScreenPreload.js'), nativeWindowOpen: true, enableRemoteModule: false, spellcheck: true } }; ``` Algunos **RCE payloads** de [aquí](https://7as.es/electron/nodeIntegration_rce.txt): ```html Example Payloads (Windows): Example Payloads (Linux & MacOS): ``` ### Captura de tráfico Modifica la configuración de start-main y añade el uso de un proxy como: ```javascript "start-main": "electron ./dist/main/main.js --proxy-server=127.0.0.1:8080 --ignore-certificateerrors", ``` ## Inyección de Código Local en Electron Si puedes ejecutar localmente una App de Electron, es posible que puedas hacer que ejecute código javascript arbitrario. Consulta cómo en: {% content-ref url="../../../macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-electron-applications-injection.md" %} [macos-electron-applications-injection.md](../../../macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-electron-applications-injection.md) {% endcontent-ref %} ## RCE: XSS + nodeIntegration Si **nodeIntegration** está configurado en **on**, el JavaScript de una página web puede usar las características de Node.js fácilmente simplemente llamando a `require()`. Por ejemplo, la forma de ejecutar la aplicación calc en Windows es: ```html ```
## RCE: preload El script indicado en esta configuración se **carga antes que otros scripts en el renderizador**, por lo que tiene **acceso ilimitado a las APIs de Node**: ```javascript new BrowserWindow{ webPreferences: { nodeIntegration: false, preload: _path2.default.join(__dirname, 'perload.js'), } }); ``` Por lo tanto, el script puede exportar características de node a páginas: {% code title="preload.js" %} ```javascript typeof require === 'function'; window.runCalc = function(){ require('child_process').exec('calc') }; ``` ``` {% endcode %} {% code title="index.html" %} ``` ```html ``` {% endcode %} {% hint style="info" %} **Si `contextIsolation` está activado, esto no funcionará** {% endhint %} ## RCE: XSS + contextIsolation El _**contextIsolation**_ introduce **contextos separados entre los scripts de la página web y el código interno de JavaScript de Electron** para que la ejecución de JavaScript de cada código no afecte al otro. Esta es una característica necesaria para eliminar la posibilidad de RCE. Si los contextos no están aislados, un atacante puede: 1. Ejecutar **JavaScript arbitrario en el renderizador** (XSS o navegación a sitios externos) 2. **Sobrescribir el método incorporado** que se utiliza en el código de precarga o en el código interno de Electron por su propia función 3. **Desencadenar** el uso de **la función sobrescrita** 4. ¿RCE? Hay 2 lugares donde se pueden sobrescribir los métodos incorporados: En el código de precarga o en el código interno de Electron: {% content-ref url="electron-contextisolation-rce-via-preload-code.md" %} [electron-contextisolation-rce-via-preload-code.md](electron-contextisolation-rce-via-preload-code.md) {% endcontent-ref %} {% content-ref url="electron-contextisolation-rce-via-electron-internal-code.md" %} [electron-contextisolation-rce-via-electron-internal-code.md](electron-contextisolation-rce-via-electron-internal-code.md) {% endcontent-ref %} {% content-ref url="electron-contextisolation-rce-via-ipc.md" %} [electron-contextisolation-rce-via-ipc.md](electron-contextisolation-rce-via-ipc.md) {% endcontent-ref %} ### Evitar evento de clic Si hay restricciones aplicadas cuando haces clic en un enlace, podrías ser capaz de evitarlas **haciendo un clic con el botón central** en lugar de un clic izquierdo regular. ```javascript window.addEventListener('click', (e) => { ``` ## RCE a través de shell.openExternal Si la aplicación de escritorio Electron se implementa con la configuración adecuada de `nodeIntegration`, `contextIsolation`; simplemente significa que **no se puede lograr un RCE del lado del cliente al apuntar a scripts de precarga o código nativo de Electron desde el proceso principal**. Cada vez que un usuario hace clic en el enlace o abre una nueva ventana, se invocan los siguientes oyentes de eventos: {% code overflow="wrap" %} ```javascript webContents.on("new-window", function (event, url, disposition, options) {} webContents.on("will-navigate", function (event, url) {} ``` {% endcode %} La aplicación de escritorio **sobrescribe estos listeners** para implementar la propia **lógica de negocio** de la aplicación de escritorio. Durante la creación de nuevas ventanas, la aplicación verifica si el enlace navegado debe abrirse en una ventana o pestaña de la aplicación de escritorio, o si debe abrirse en el navegador web. En nuestro ejemplo, la verificación se implementa con la función `openInternally`, si devuelve `false`, la aplicación asumirá que el enlace debe abrirse en el navegador web utilizando la función `shell.openExternal`. **Aquí hay un pseudocódigo simplificado:** ![](<../../../.gitbook/assets/image (638) (2) (1) (1).png>) ![](<../../../.gitbook/assets/image (620).png>) De acuerdo con las mejores prácticas de seguridad de Electron JS, la función `openExternal` **no debe aceptar contenido no confiable** **porque eso podría llevar a RCE abusando de diferentes protocolos** si la aplicación no limita la navegación de los usuarios a través de protocolos como https:// o http://. Diferentes sistemas operativos admiten diferentes protocolos que podrían desencadenar RCE, para más información sobre ellos consulta [https://positive.security/blog/url-open-rce](https://positive.security/blog/url-open-rce#windows-10-19042) pero aquí tienes algunos ejemplos de Windows: ```html ``` Para más información sobre estos ejemplos, consulta [https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8](https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8) y [https://benjamin-altpeter.de/shell-openexternal-dangers/](https://benjamin-altpeter.de/shell-openexternal-dangers/) ## Leer Archivos Internos: XSS + contextIsolation Si `contextIsolation` está configurado en false, puedes intentar usar \ (similar a \ ``` ## **RCE: XSS + Chromium Antiguo** Si el **chromium** utilizado por la aplicación es **antiguo** y existen **vulnerabilidades conocidas** en él, podría ser posible **explotarlo y obtener RCE a través de un XSS**.\ Puedes ver un ejemplo en este **informe**: [https://blog.electrovolt.io/posts/discord-rce/](https://blog.electrovolt.io/posts/discord-rce/) ## **Phishing XSS mediante bypass de regex de URL interna** Suponiendo que encontraste un XSS pero **no puedes activar RCE ni robar archivos internos**, podrías intentar usarlo para **robar credenciales mediante phishing**. Primero que nada necesitas saber qué sucede cuando intentas abrir una nueva URL, revisando el código JS en el front-end: ```javascript webContents.on("new-window", function (event, url, disposition, options) {} // opens the custom openInternally function (it is declared below) webContents.on("will-navigate", function (event, url) {} // opens the custom openInternally function (it is declared below) ``` La llamada a **`openInternally`** decidirá si el **enlace** se **abrirá** en la **ventana de escritorio** ya que es un enlace que pertenece a la plataforma, **o** si se abrirá en el **navegador como un recurso de terceros**. En el caso de que la **expresión regular** utilizada por la función sea **vulnerable a omisiones** (por ejemplo, por **no escapar los puntos de los subdominios**), un atacante podría abusar del XSS para **abrir una nueva ventana que** estará ubicada en la infraestructura del atacante **solicitando credenciales** al usuario: ```html ``` ## **Herramientas** * [**Electronegativity**](https://github.com/doyensec/electronegativity) es una herramienta para identificar configuraciones erróneas y antipatrones de seguridad en aplicaciones basadas en Electron. * [**Electrolint**](https://github.com/ksdmitrieva/electrolint) es un complemento de código abierto para VS Code para aplicaciones Electron que utiliza Electronegativity. * [**nodejsscan**](https://github.com/ajinabraham/nodejsscan) para verificar bibliotecas de terceros vulnerables * [**Electro.ng**](https://electro.ng/): Necesitas comprarlo ## Laboratorios En [https://www.youtube.com/watch?v=xILfQGkLXQo\&t=22s](https://www.youtube.com/watch?v=xILfQGkLXQo\&t=22s) puedes encontrar un laboratorio para explotar aplicaciones Electron vulnerables. Algunos comandos que te ayudarán con el laboratorio: ```bash # Download apps from these URls # Vuln to nodeIntegration https://training.7asecurity.com/ma/webinar/desktop-xss-rce/apps/vulnerable1.zip # Vuln to contextIsolation via preload script https://training.7asecurity.com/ma/webinar/desktop-xss-rce/apps/vulnerable2.zip # Vuln to IPC Rce https://training.7asecurity.com/ma/webinar/desktop-xss-rce/apps/vulnerable3.zip # Get inside the electron app and check for vulnerabilities npm audit # How to use electronegativity npm install @doyensec/electronegativity -g electronegativity -i vulnerable1 # Run an application from source code npm install -g electron cd vulnerable1 npm install npm start ``` ## **Referencias** * [https://shabarkin.medium.com/unsafe-content-loading-electron-js-76296b6ac028](https://shabarkin.medium.com/unsafe-content-loading-electron-js-76296b6ac028) * [https://medium.com/@renwa/facebook-messenger-desktop-app-arbitrary-file-read-db2374550f6d](https://medium.com/@renwa/facebook-messenger-desktop-app-arbitrary-file-read-db2374550f6d) * [https://speakerdeck.com/masatokinugawa/electron-abusing-the-lack-of-context-isolation-curecon-en?slide=8](https://speakerdeck.com/masatokinugawa/electron-abusing-the-lack-of-context-isolation-curecon-en?slide=8) * [https://www.youtube.com/watch?v=a-YnG3Mx-Tg](https://www.youtube.com/watch?v=a-YnG3Mx-Tg) * [https://www.youtube.com/watch?v=xILfQGkLXQo\&t=22s](https://www.youtube.com/watch?v=xILfQGkLXQo\&t=22s) * Más investigaciones y artículos sobre la seguridad de Electron en [https://github.com/doyensec/awesome-electronjs-hacking](https://github.com/doyensec/awesome-electronjs-hacking) * [https://www.youtube.com/watch?v=Tzo8ucHA5xw\&list=PLH15HpR5qRsVKcKwvIl-AzGfRqKyx--zq\&index=81](https://www.youtube.com/watch?v=Tzo8ucHA5xw\&list=PLH15HpR5qRsVKcKwvIl-AzGfRqKyx--zq\&index=81)
Aprende a hackear AWS desde cero hasta héroe con htARTE (HackTricks AWS Red Team Expert)! Otras formas de apoyar a HackTricks: * Si quieres ver a tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF** revisa los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)! * Consigue el [**merchandising oficial de PEASS & HackTricks**](https://peass.creator-spring.com) * Descubre [**La Familia PEASS**](https://opensea.io/collection/the-peass-family), nuestra colección de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos * **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **sígueme** en **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.** * **Comparte tus trucos de hacking enviando PRs a los repositorios de github** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).