diff --git a/src/network-services-pentesting/pentesting-web/electron-desktop-apps/README.md b/src/network-services-pentesting/pentesting-web/electron-desktop-apps/README.md index 5351162e1..cfe94215a 100644 --- a/src/network-services-pentesting/pentesting-web/electron-desktop-apps/README.md +++ b/src/network-services-pentesting/pentesting-web/electron-desktop-apps/README.md @@ -1,17 +1,17 @@ -# Electron Desktop Apps +# Electron 데스크톱 앱 {{#include ../../../banners/hacktricks-training.md}} -## Introduction +## 소개 -Electron은 로컬 백엔드(**NodeJS**)와 프론트엔드(**Chromium**)를 결합하지만, 최신 브라우저의 일부 보안 메커니즘이 부족합니다. +Electron은 로컬 백엔드(**NodeJS**)와 프런트엔드(**Chromium**)를 결합하지만, 최신 브라우저에 있는 일부 보안 메커니즘이 부족합니다. -일반적으로 전자 앱 코드는 `.asar` 애플리케이션 내부에 있으며, 코드를 얻으려면 이를 추출해야 합니다: +보통 electron 앱 코드는 `.asar` 애플리케이션 안에서 발견됩니다. 코드를 얻으려면 이를 추출해야 합니다: ```bash 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` 파일을 찾을 수 있습니다. +Electron 앱의 소스 코드에서 `packet.json` 안에 보안 설정이 적용된 `main.js` 파일이 지정되어 있는 것을 찾을 수 있습니다. ```json { "name": "standard-notes", @@ -19,12 +19,12 @@ Electron 앱의 소스 코드에서 `packet.json` 안에 보안 설정이 지정 ``` Electron에는 2가지 프로세스 유형이 있습니다: -- Main Process (NodeJS에 완전 접근 가능) -- Renderer Process (보안상의 이유로 NodeJS 접근이 제한되어야 함) +- 메인 프로세스 (NodeJS에 대한 완전한 접근 권한을 가짐) +- 렌더러 프로세스 (보안상 NodeJS 접근이 제한되어야 함) ![](<../../../images/image (182).png>) -**renderer process**는 파일을 로드하는 브라우저 창이 될 것입니다: +하나의 **렌더러 프로세스**는 파일을 로드하는 브라우저 창이 됩니다: ```javascript const { BrowserWindow } = require("electron") let win = new BrowserWindow() @@ -32,20 +32,20 @@ let win = new BrowserWindow() //Open Renderer Process win.loadURL(`file://path/to/index.html`) ``` -**렌더러 프로세스**의 설정은 **main.js** 파일의 **메인 프로세스**에서 **구성**할 수 있습니다. 일부 구성은 **설정이 올바르게 구성되면 Electron 애플리케이션이 RCE** 또는 기타 취약점에 노출되는 것을 **방지**합니다. +main.js 파일 내부의 **main process**에서 **renderer process**의 설정을 **구성**할 수 있습니다. 설정이 올바르게 구성되면 일부 설정은 **Electron 애플리케이션이 RCE**나 다른 취약점을 얻는 것을 **방지**할 수 있습니다. -Electron 애플리케이션은 Node API를 통해 **장치에 접근할 수 있지만**, 이를 방지하도록 구성할 수 있습니다: +Electron 애플리케이션은 **Node apis를 통해 기기에 접근할 수** 있지만 이를 방지하도록 구성할 수 있습니다: -- **`nodeIntegration`** - 기본값은 `off`입니다. 켜면 렌더러 프로세스에서 노드 기능에 접근할 수 있습니다. -- **`contextIsolation`** - 기본값은 `on`입니다. 꺼지면 메인 프로세스와 렌더러 프로세스가 격리되지 않습니다. +- **`nodeIntegration`** - 기본값은 `off`입니다. 켜져 있으면 renderer process에서 node 기능에 접근할 수 있습니다. +- **`contextIsolation`** - 기본값은 `on`입니다. `off`이면 main과 renderer 프로세스가 격리되지 않습니다. - **`preload`** - 기본값은 비어 있습니다. -- [**`sandbox`**](https://docs.w3cub.com/electron/api/sandbox-option) - 기본값은 꺼져 있습니다. NodeJS가 수행할 수 있는 작업을 제한합니다. -- 워커에서의 Node 통합 -- **`nodeIntegrationInSubframes`** - 기본값은 꺼져 있습니다. -- **`nodeIntegration`**이 **활성화**되면, 이는 Electron 애플리케이션 내의 **iframe에 로드된 웹 페이지에서 Node.js API**를 사용할 수 있게 합니다. -- **`nodeIntegration`**이 **비활성화**되면, 프리로드는 iframe에서 로드됩니다. +- [**`sandbox`**](https://docs.w3cub.com/electron/api/sandbox-option) - 기본값은 `off`입니다. NodeJS가 수행할 수 있는 동작을 제한합니다. +- Workers에서의 Node Integration +- **`nodeIntegrationInSubframes`** - 기본값은 `off`입니다. +- 만약 **`nodeIntegration`**이 **enabled**되어 있으면, 이는 Electron 애플리케이션 내에서 **iframe**에 로드된 웹 페이지에서 **Node.js APIs**를 사용할 수 있게 합니다. +- 만약 **`nodeIntegration`**이 **disabled**되어 있으면, preload들이 iframe에서 로드됩니다. -구성 예시: +Example of configuration: ```javascript const mainWindowOptions = { title: "Discord", @@ -71,7 +71,7 @@ spellcheck: true, }, } ``` -일부 **RCE 페이로드**는 [여기](https://7as.es/electron/nodeIntegration_rce.txt)에서 확인할 수 있습니다: +다음은 [here](https://7as.es/electron/nodeIntegration_rce.txt)에서 가져온 일부 **RCE payloads**: ```html Example Payloads (Windows): ``` ### 트래픽 캡처 -start-main 구성을 수정하고 다음과 같은 프록시 사용을 추가하세요: +start-main 설정을 수정하고 다음과 같은 proxy 사용을 추가하세요: ```javascript "start-main": "electron ./dist/main/main.js --proxy-server=127.0.0.1:8080 --ignore-certificateerrors", ``` -## Electron 로컬 코드 주입 +## Electron Local Code Injection -Electron 앱을 로컬에서 실행할 수 있다면 임의의 자바스크립트 코드를 실행할 수 있을 가능성이 있습니다. 방법은 다음을 확인하세요: +로컬에서 Electron App을 실행할 수 있다면 임의의 JavaScript 코드를 실행하도록 만들 수 있다. 방법은 다음을 확인: {{#ref}} ../../../macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-electron-applications-injection.md @@ -111,7 +111,7 @@ Electron 앱을 로컬에서 실행할 수 있다면 임의의 자바스크립 ## RCE: XSS + nodeIntegration -**nodeIntegration**이 **on**으로 설정되어 있으면, 웹 페이지의 자바스크립트는 `require()`를 호출하기만 하면 Node.js 기능을 쉽게 사용할 수 있습니다. 예를 들어, Windows에서 calc 애플리케이션을 실행하는 방법은 다음과 같습니다: +만약 **nodeIntegration**이 **on**으로 설정되어 있다면, 웹 페이지의 JavaScript는 `require()`를 호출하기만 해도 Node.js 기능을 쉽게 사용할 수 있다. 예를 들어 Windows에서 calc 애플리케이션을 실행하는 방법은 다음과 같다: ```html ``` -> [!NOTE] > **`contextIsolation`이 켜져 있으면, 이 방법은 작동하지 않습니다.** +> [!NOTE] > **`contextIsolation`이 켜져 있으면 작동하지 않습니다** ## RCE: XSS + contextIsolation -_**contextIsolation**_은 **웹 페이지 스크립트와 JavaScript Electron의 내부 코드 간의 분리된 컨텍스트**를 도입하여 각 코드의 JavaScript 실행이 서로 영향을 미치지 않도록 합니다. 이는 RCE의 가능성을 제거하기 위한 필수 기능입니다. +The _**contextIsolation**_는 웹 페이지 스크립트와 Electron의 내부 JavaScript 코드 간의 분리된 컨텍스트를 도입하여 각 코드의 JavaScript 실행이 서로 영향을 미치지 않도록 합니다. 이는 RCE 가능성을 제거하기 위한 필수 기능입니다. -컨텍스트가 분리되지 않으면 공격자는: +컨텍스트가 분리되어 있지 않으면 공격자는 다음을 수행할 수 있습니다: -1. **렌더러에서 임의의 JavaScript 실행** (XSS 또는 외부 사이트로의 탐색) -2. **프리로드 또는 Electron 내부 코드에서 사용되는 내장 메서드**를 자신의 함수로 덮어쓰기 -3. **덮어쓴 함수의 사용을 트리거** +1. renderer에서 **임의의 JavaScript를 실행**할 수 있습니다 (XSS 또는 외부 사이트로의 이동) +2. **preload나 Electron 내부 코드에서 사용되는 내장 메서드를 덮어씀**으로써 함수를 장악할 수 있습니다 +3. **덮어쓴 함수**의 사용을 **트리거**할 수 있습니다 4. RCE? -내장 메서드를 덮어쓸 수 있는 두 곳이 있습니다: 프리로드 코드 또는 Electron 내부 코드에서: +내장 메서드를 덮어쓸 수 있는 장소는 2곳이 있습니다: preload 코드 또는 Electron 내부 코드에서: + {{#ref}} electron-contextisolation-rce-via-preload-code.md {{#endref}} + {{#ref}} electron-contextisolation-rce-via-electron-internal-code.md {{#endref}} + {{#ref}} electron-contextisolation-rce-via-ipc.md {{#endref}} ### 클릭 이벤트 우회 -링크를 클릭할 때 제한이 적용되는 경우, 일반 왼쪽 클릭 대신 **중간 클릭**을 통해 이를 우회할 수 있습니다. +링크를 클릭할 때 제한이 적용되어 있다면, 일반적인 왼쪽 클릭 대신 **middle click**을 사용하여 해당 제한을 우회할 수 있습니다. ```javascript window.addEventListener('click', (e) => { ``` -## RCE via shell.openExternal +## shell.openExternal을 통한 RCE -이 예제에 대한 자세한 정보는 [https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8](https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8) 및 [https://benjamin-altpeter.de/shell-openexternal-dangers/](https://benjamin-altpeter.de/shell-openexternal-dangers/)를 확인하세요. +이 예제들에 대한 자세한 내용은 [https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8](https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8) 및 [https://benjamin-altpeter.de/shell-openexternal-dangers/](https://benjamin-altpeter.de/shell-openexternal-dangers/)를 참고하세요. -Electron 데스크탑 애플리케이션을 배포할 때 `nodeIntegration` 및 `contextIsolation`에 대한 올바른 설정을 보장하는 것이 중요합니다. **클라이언트 측 원격 코드 실행(RCE)**이 프리로드 스크립트나 메인 프로세스의 Electron 기본 코드를 대상으로 할 때 이러한 설정이 적용되면 효과적으로 방지된다는 것이 확립되었습니다. +Electron 데스크톱 애플리케이션을 배포할 때 `nodeIntegration`과 `contextIsolation` 설정을 올바르게 하는 것이 중요합니다. 이러한 설정이 적용되면 메인 프로세스에서 preload 스크립트나 Electron의 네이티브 코드로의 **client-side remote code execution (RCE)** 시도가 실질적으로 차단되는 것으로 알려져 있습니다. -사용자가 링크와 상호작용하거나 새 창을 열면 특정 이벤트 리스너가 트리거되며, 이는 애플리케이션의 보안 및 기능에 중요합니다: +사용자가 링크를 클릭하거나 새 창을 열면 특정 이벤트 리스너들이 트리거되며, 이는 애플리케이션의 보안과 기능에 매우 중요합니다: ```javascript webContents.on("new-window", function (event, url, disposition, options) {} webContents.on("will-navigate", function (event, url) {} ``` -이 리스너는 **데스크탑 애플리케이션에 의해 재정의되어** 자체 **비즈니스 로직**을 구현합니다. 애플리케이션은 탐색된 링크가 내부에서 열려야 하는지 또는 외부 웹 브라우저에서 열려야 하는지를 평가합니다. 이 결정은 일반적으로 `openInternally`라는 함수를 통해 이루어집니다. 이 함수가 `false`를 반환하면, 링크는 외부에서 열려야 함을 나타내며, `shell.openExternal` 함수를 사용합니다. +이러한 리스너들은 데스크탑 애플리케이션에 의해 **재정의되어** 자체 **비즈니스 로직**을 구현합니다. 애플리케이션은 탐색된 링크를 내부에서 열지 외부 웹 브라우저에서 열지 평가합니다. 이 결정은 일반적으로 `openInternally` 함수를 통해 이루어집니다. 이 함수가 `false`를 반환하면, 링크는 외부에서 열려야 함을 의미하며 `shell.openExternal` 함수를 사용합니다. -**여기 간단한 의사코드가 있습니다:** +**Here is a simplified pseudocode:** ![https://miro.medium.com/max/1400/1*iqX26DMEr9RF7nMC1ANMAA.png](<../../../images/image (261).png>) ![https://miro.medium.com/max/1400/1*ZfgVwT3X1V_UfjcKaAccag.png](<../../../images/image (963).png>) -Electron JS 보안 모범 사례는 `openExternal` 함수를 사용하여 신뢰할 수 없는 콘텐츠를 수용하지 말 것을 권장합니다. 이는 다양한 프로토콜을 통해 RCE로 이어질 수 있습니다. 운영 체제는 RCE를 유발할 수 있는 다양한 프로토콜을 지원합니다. 이 주제에 대한 자세한 예제와 추가 설명은 [이 리소스](https://positive.security/blog/url-open-rce#windows-10-19042)를 참조할 수 있으며, 여기에는 이 취약점을 악용할 수 있는 Windows 프로토콜 예제가 포함되어 있습니다. +Electron JS 보안 권장사항은 `openExternal` 함수를 통해 신뢰할 수 없는 콘텐츠를 수락하지 않을 것을 권고합니다. 이는 다양한 프로토콜을 통해 RCE로 이어질 수 있기 때문입니다. 운영 체제는 RCE를 유발할 수 있는 다양한 프로토콜을 지원합니다. 이 주제에 대한 자세한 예와 추가 설명은 [this resource](https://positive.security/blog/url-open-rce#windows-10-19042)를 참조할 수 있으며, 여기에는 이 취약점을 악용할 수 있는 Windows 프로토콜 예시가 포함되어 있습니다. -macOS에서는 `openExternal` 함수를 악용하여 `shell.openExternal('file:///System/Applications/Calculator.app')`와 같은 임의의 명령을 실행할 수 있습니다. +macOS에서 `openExternal` 함수는 `shell.openExternal('file:///System/Applications/Calculator.app')`처럼 임의의 명령을 실행하도록 악용될 수 있습니다. -**Windows 프로토콜 악용의 예는 다음과 같습니다:** +**Examples of Windows protocol exploits include:** ```html ``` -## **RCE: XSS + Old Chromium** +## **RCE: XSS + 오래된 Chromium** -애플리케이션에서 사용되는 **chromium**이 **오래된** 경우, **알려진** **취약점**이 있을 수 있으며, 이를 **악용하여 XSS를 통해 RCE를 얻을 수** 있습니다.\ -이 **writeup**에서 예제를 확인할 수 있습니다: [https://blog.electrovolt.io/posts/discord-rce/](https://blog.electrovolt.io/posts/discord-rce/) +애플리케이션에서 사용하는 **chromium**이 **오래된** 버전이고 그에 대한 **알려진** **취약점**이 있다면, 이를 **악용하여 XSS를 통해 RCE를 획득하는 것이** 가능할 수 있습니다.\ +예시는 이 **writeup**에서 볼 수 있습니다: [https://blog.electrovolt.io/posts/discord-rce/](https://blog.electrovolt.io/posts/discord-rce/) -## **XSS Phishing via Internal URL regex bypass** +## **내부 URL regex 우회를 통한 XSS Phishing** -XSS를 발견했지만 **RCE를 트리거하거나 내부 파일을 훔칠 수 없는** 경우, 이를 사용하여 **피싱을 통해 자격 증명을 훔치려고** 시도할 수 있습니다. +XSS를 발견했지만 **RCE를 유발하거나 내부 파일을 훔칠 수 없다면**, 이를 사용해 **phishing을 통해 자격 증명(계정 정보)을 탈취** 시도할 수 있습니다. -우선, 새 URL을 열려고 할 때 발생하는 일을 알아야 하며, 프론트엔드의 JS 코드를 확인해야 합니다: +먼저 새로운 URL을 열려고 할 때 어떤 일이 일어나는지 알아야 하며, 프런트엔드의 JS 코드를 확인하세요: ```javascript 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) ``` -**`openInternally`** 호출은 **링크**가 플랫폼에 속하는 링크이기 때문에 **데스크탑 창**에서 **열릴지** 아니면 **브라우저에서 3자 리소스**로 열릴지를 결정합니다. +**`openInternally`** 호출은 해당 **link**가 플랫폼 소유의 링크로서 **desktop window**에서 **opened** 될지, **or** 제3자 리소스로서 **browser as a 3rd party resource**에서 열릴지를 결정합니다. -함수가 사용하는 **정규 표현식**이 **우회 공격에 취약한 경우**(예: **서브도메인의 점을 이스케이프하지 않는 경우**) 공격자는 XSS를 악용하여 **새 창을 열 수 있으며**, 이 창은 공격자의 인프라에 위치하여 **사용자에게 자격 증명을 요청**할 수 있습니다: +함수에서 사용된 **regex**가 **vulnerable to bypasses**한 경우(예: **not escaping the dots of subdomains**) 공격자는 **XSS**를 악용해 공격자 인프라에 위치한 **open a new window which**를 열어 사용자에게 **asking for credentials**하도록 요청할 수 있습니다: ```html