diff --git a/.gitignore b/.gitignore index 365859fbc..77edd91a0 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ scripts/* book book/* hacktricks-preprocessor.log +hacktricks-preprocessor-error.log diff --git a/hacktricks-preprocessor.py b/hacktricks-preprocessor.py index 969d5333e..af5949449 100644 --- a/hacktricks-preprocessor.py +++ b/hacktricks-preprocessor.py @@ -7,7 +7,14 @@ from os import path from urllib.request import urlopen, Request logger = logging.getLogger(__name__) -logging.basicConfig(filename='hacktricks-preprocessor.log', filemode='w', encoding='utf-8', level=logging.DEBUG) +logger.setLevel(logging.DEBUG) +handler = logging.FileHandler(filename='hacktricks-preprocessor.log', mode='w', encoding='utf-8') +handler.setLevel(logging.DEBUG) +logger.addHandler(handler) + +handler2 = logging.FileHandler(filename='hacktricks-preprocessor-error.log', mode='w', encoding='utf-8') +handler2.setLevel(logging.ERROR) +logger.addHandler(handler2) def findtitle(search ,obj, key, path=(),): @@ -27,7 +34,7 @@ def findtitle(search ,obj, key, path=(),): def ref(matchobj): - logger.debug(f'Match: {matchobj.groups(0)[0].strip()}') + logger.debug(f'Ref match: {matchobj.groups(0)[0].strip()}') href = matchobj.groups(0)[0].strip() title = href if href.startswith("http://") or href.startswith("https://"): @@ -45,19 +52,29 @@ def ref(matchobj): try: if href.endswith("/"): href = href+"README.md" # Fix if ref points to a folder - chapter, _path = findtitle(href, book, "source_path") - logger.debug(f'Recursive title search result: {chapter["name"]}') - title = chapter['name'] + if "#" in href: + chapter, _path = findtitle(href.split("#")[0], book, "source_path") + title = " ".join(href.split("#")[1].split("-")).title() + logger.debug(f'Ref has # using title: {title}') + else: + chapter, _path = findtitle(href, book, "source_path") + logger.debug(f'Recursive title search result: {chapter["name"]}') + title = chapter['name'] except Exception as e: try: dir = path.dirname(current_chapter['source_path']) logger.debug(f'Error getting chapter title: {href} trying with relative path {path.normpath(path.join(dir,href))}') - chapter, _path = findtitle(path.normpath(path.join(dir,href)), book, "source_path") - logger.debug(f'Recursive title search result: {chapter["name"]}') - title = chapter['name'] + if "#" in href: + chapter, _path = findtitle(path.normpath(path.join(dir,href.split('#')[0])), book, "source_path") + title = " ".join(href.split("#")[1].split("-")).title() + logger.debug(f'Ref has # using title: {title}') + else: + chapter, _path = findtitle(path.normpath(path.join(dir,href.split('#')[0])), book, "source_path") + title = chapter["name"] + logger.debug(f'Recursive title search result: {chapter["name"]}') except Exception as e: - logger.debug(f'Error getting chapter title: {path.normpath(path.join(dir,href))}') - print(f'Error getting chapter title: {path.normpath(path.join(dir,href))}') + logger.debug(e) + logger.error(f'Error getting chapter title: {path.normpath(path.join(dir,href))}') sys.exit(1) @@ -69,6 +86,7 @@ def ref(matchobj): return result + def files(matchobj): logger.debug(f'Files match: {matchobj.groups(0)[0].strip()}') href = matchobj.groups(0)[0].strip() @@ -76,19 +94,19 @@ def files(matchobj): try: for root, dirs, files in os.walk(os.getcwd()+'/src/files'): + logger.debug(root) + logger.debug(files) if href in files: title = href logger.debug(f'File search result: {os.path.join(root, href)}') except Exception as e: logger.debug(e) - logger.debug(f'Error searching file: {href}') - print(f'Error searching file: {href}') + logger.error(f'Error searching file: {href}') sys.exit(1) if title=="": - logger.debug(f'Error searching file: {href}') - print(f'Error searching file: {href}') + logger.error(f'Error searching file: {href}') sys.exit(1) template = f"""{title}""" @@ -97,6 +115,7 @@ def files(matchobj): return result + def add_read_time(content): regex = r'(<\/style>\n# .*(?=\n))' new_content = re.sub(regex, lambda x: x.group(0) + "\n\nReading time: {{ #reading_time }}", content) @@ -126,15 +145,15 @@ if __name__ == '__main__': context, book = json.load(sys.stdin) logger.debug(f"Context: {context}") - logger.debug(f"Env: {context['config']['preprocessor']['hacktricks']['env']}") for chapter in iterate_chapters(book['sections']): logger.debug(f"Chapter: {chapter['path']}") current_chapter = chapter - regex = r'{{[\s]*#ref[\s]*}}(?:\n)?([^\\\n]*)(?:\n)?{{[\s]*#endref[\s]*}}' + # regex = r'{{[\s]*#ref[\s]*}}(?:\n)?([^\\\n]*)(?:\n)?{{[\s]*#endref[\s]*}}' + regex = r'{{[\s]*#ref[\s]*}}(?:\n)?([^\\\n#]*(?:#(.*))?)(?:\n)?{{[\s]*#endref[\s]*}}' new_content = re.sub(regex, ref, chapter['content']) regex = r'{{[\s]*#file[\s]*}}(?:\n)?([^\\\n]*)(?:\n)?{{[\s]*#endfile[\s]*}}' - new_content = re.sub(regex, files, chapter['content']) + new_content = re.sub(regex, files, new_content) new_content = add_read_time(new_content) chapter['content'] = new_content 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 395e923e5..759cc0e2a 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 @@ -6,7 +6,7 @@ Electronは、ローカルバックエンド(**NodeJS**)とフロントエンド(**Chromium**)を組み合わせていますが、最新のブラウザのセキュリティメカニズムのいくつかが欠けています。 -通常、Electronアプリのコードは`.asar`アプリケーション内にあります。コードを取得するには、抽出する必要があります: +通常、Electronアプリのコードは`.asar`アプリケーション内に見つかります。コードを取得するには、抽出する必要があります: ```bash npx asar extract app.asar destfolder #Extract everything npx asar extract-file app.asar main.js #Extract just a file @@ -32,18 +32,18 @@ let win = new BrowserWindow() //Open Renderer Process win.loadURL(`file://path/to/index.html`) ``` -**renderer process**の設定は、main.jsファイル内の**main process**で**設定**できます。いくつかの設定は、**設定が正しく構成されていれば**、ElectronアプリケーションがRCEやその他の脆弱性を持つのを**防ぐ**ことができます。 +**renderer process**の設定は、main.jsファイル内の**main process**で**設定**できます。いくつかの設定は、**設定が正しく構成されている**場合、ElectronアプリケーションがRCEやその他の脆弱性を持つのを**防ぐ**ことができます。 Electronアプリケーションは、Node APIを介して**デバイスにアクセス**することができますが、それを防ぐように構成することもできます: - **`nodeIntegration`** - デフォルトでは`off`です。オンの場合、renderer processからNode機能にアクセスできます。 -- **`contextIsolation`** - デフォルトでは`on`です。オフの場合、mainとrendererプロセスは分離されません。 +- **`contextIsolation`** - デフォルトでは`on`です。オフの場合、mainとrendererプロセスは隔離されません。 - **`preload`** - デフォルトでは空です。 - [**`sandbox`**](https://docs.w3cub.com/electron/api/sandbox-option) - デフォルトではオフです。NodeJSが実行できるアクションを制限します。 - WorkersにおけるNode Integration - **`nodeIntegrationInSubframes`** - デフォルトでは`off`です。 - **`nodeIntegration`**が**有効**になっている場合、これはElectronアプリケーション内のiframeで**読み込まれた**ウェブページで**Node.js APIs**を使用することを許可します。 -- **`nodeIntegration`**が**無効**になっている場合、preloadsはiframe内で読み込まれます。 +- **`nodeIntegration`**が**無効**になっている場合、preloadはiframe内で読み込まれます。 設定の例: ```javascript @@ -103,7 +103,7 @@ start-main構成を変更し、次のようなプロキシの使用を追加し ``` ## Electronローカルコードインジェクション -Electronアプリをローカルで実行できる場合、任意のJavaScriptコードを実行させることができる可能性があります。方法は以下を確認してください: +Electronアプリをローカルで実行できる場合、任意のJavaScriptコードを実行させることが可能です。方法については以下を確認してください: {{#ref}} ../../../macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-electron-applications-injection.md @@ -111,7 +111,7 @@ Electronアプリをローカルで実行できる場合、任意のJavaScript ## RCE: XSS + nodeIntegration -**nodeIntegration**が**on**に設定されている場合、ウェブページのJavaScriptは`require()`を呼び出すだけでNode.jsの機能を簡単に使用できます。たとえば、Windowsで計算機アプリケーションを実行する方法は次のとおりです: +**nodeIntegration**が**on**に設定されている場合、ウェブページのJavaScriptは`require()`を呼び出すだけでNode.jsの機能を簡単に使用できます。例えば、Windowsでcalcアプリケーションを実行する方法は次の通りです: ```html ``` -## **RCE: XSS + 古いChromium** +## **RCE: XSS + Old Chromium** -アプリケーションで使用されている**chromium**が**古い**場合、**既知の****脆弱性**があると、**それを悪用してXSSを通じてRCEを取得する**ことが可能かもしれません。\ +アプリケーションで使用されている**chromium**が**古い**場合、**既知の****脆弱性**があると、**XSSを通じてそれを悪用しRCEを取得する**ことが可能かもしれません。\ この**writeup**の例を参照してください: [https://blog.electrovolt.io/posts/discord-rce/](https://blog.electrovolt.io/posts/discord-rce/) -## **内部URLの正規表現バイパスによるXSSフィッシング** +## **XSS Phishing via Internal URL regex bypass** XSSを見つけたが、**RCEをトリガーできないか内部ファイルを盗むことができない**場合、**フィッシングを通じて資格情報を盗む**ためにそれを使用することを試みることができます。 @@ -266,18 +268,106 @@ webContents.on("will-navigate", function (event, url) {} // o window.open("") ``` -## **ツール** +## リモートモジュール -- [**Electronegativity**](https://github.com/doyensec/electronegativity) は、Electronベースのアプリケーションにおける誤設定やセキュリティのアンチパターンを特定するためのツールです。 -- [**Electrolint**](https://github.com/ksdmitrieva/electrolint) は、Electronegativityを使用するElectronアプリケーション用のオープンソースのVS Codeプラグインです。 -- [**nodejsscan**](https://github.com/ajinabraham/nodejsscan) は、脆弱なサードパーティライブラリをチェックするためのツールです。 -- [**Electro.ng**](https://electro.ng/): 購入する必要があります。 +Electronのリモートモジュールは、**レンダラープロセスがメインプロセスのAPIにアクセスすることを可能にし**、Electronアプリケーション内での通信を促進します。しかし、このモジュールを有効にすると、重大なセキュリティリスクが生じます。アプリケーションの攻撃面が拡大し、クロスサイトスクリプティング(XSS)攻撃などの脆弱性に対してより脆弱になります。 -## ラボ +> [!TIP] +> **リモート**モジュールはメインからレンダラープロセスへのいくつかのAPIを公開しますが、コンポーネントを悪用するだけではRCEを得るのは簡単ではありません。しかし、コンポーネントは機密情報を公開する可能性があります。 -[https://www.youtube.com/watch?v=xILfQGkLXQo\&t=22s](https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s) では、脆弱なElectronアプリを悪用するためのラボを見つけることができます。 +> [!WARNING] +> まだリモートモジュールを使用している多くのアプリは、レンダラープロセスで**NodeIntegrationを有効にする必要がある**方法で行っており、これは**巨大なセキュリティリスク**です。 -ラボに役立ついくつかのコマンド: +Electron 14以降、Electronの`remote`モジュールは、セキュリティとパフォーマンスの理由からいくつかのステップで有効にされる可能性があり、**使用しないことが推奨されています**。 + +これを有効にするには、まず**メインプロセスで有効にする必要があります**: +```javascript +const remoteMain = require('@electron/remote/main') +remoteMain.initialize() +[...] +function createMainWindow() { +mainWindow = new BrowserWindow({ +[...] +}) +remoteMain.enable(mainWindow.webContents) +``` +その後、レンダラープロセスは、モジュールからオブジェクトを次のようにインポートできます: +```javascript +import { dialog, getCurrentWindow } from '@electron/remote' +``` +**[ブログ記事](https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html)** は、リモートモジュールのオブジェクト **`app`** によって公開されているいくつかの興味深い **関数** を示しています: + +- **`app.relaunch([options])`** +- **現在のインスタンスを終了**し、新しいインスタンスを**起動**することでアプリケーションを**再起動**します。**アプリの更新**や重要な**状態変更**に便利です。 +- **`app.setAppLogsPath([path])`** +- **アプリログ**を保存するためのディレクトリを**定義**または**作成**します。ログは **`app.getPath()`** または **`app.setPath(pathName, newPath)`** を使用して**取得**または**変更**できます。 +- **`app.setAsDefaultProtocolClient(protocol[, path, args])`** +- 指定された**プロトコル**の**デフォルトハンドラー**として現在の実行可能ファイルを**登録**します。必要に応じて**カスタムパス**と**引数**を提供できます。 +- **`app.setUserTasks(tasks)`** +- **ジャンプリスト**の**タスクカテゴリ**にタスクを**追加**します(Windows)。各タスクはアプリがどのように**起動**されるか、またはどの**引数**が渡されるかを制御できます。 +- **`app.importCertificate(options, callback)`** +- システムの**証明書ストア**に**PKCS#12証明書**を**インポート**します(Linuxのみ)。**コールバック**を使用して結果を処理できます。 +- **`app.moveToApplicationsFolder([options])`** +- アプリケーションを**アプリケーションフォルダ**に**移動**します(macOS)。Macユーザーのための**標準インストール**を確保するのに役立ちます。 +- **`app.setJumpList(categories)`** +- **Windows**で**カスタムジャンプリスト**を**設定**または**削除**します。タスクがユーザーにどのように表示されるかを整理するために**カテゴリ**を指定できます。 +- **`app.setLoginItemSettings(settings)`** +- **ログイン**時に起動する**実行可能ファイル**とその**オプション**を**構成**します(macOSおよびWindowsのみ)。 +```javascript +Native.app.relaunch({args: [], execPath: "/System/Applications/Calculator.app/Contents/MacOS/Calculator"}); +Native.app.exit() +``` +## systemPreferences モジュール + +Electron におけるシステム設定にアクセスし、システムイベントを発信するための **主要な API**。**subscribeNotification**、**subscribeWorkspaceNotification**、**getUserDefault**、および **setUserDefault** のようなメソッドはすべてこのモジュールの **一部** です。 + +**使用例:** +```javascript +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** + +* **ネイティブmacOS通知**をNSDistributedNotificationCenterを使用して**リッスン**します。 +* **macOS Catalina**以前は、CFNotificationCenterAddObserverに**nil**を渡すことで**すべての**配布通知をスニッフィングできました。 +* **Catalina / Big Sur**以降、サンドボックスアプリは、通知を**名前**で登録することにより、**多くのイベント**(例えば、**画面のロック/ロック解除**、**ボリュームのマウント**、**ネットワークアクティビティ**など)に**サブスクライブ**できます。 + +### **getUserDefault / setUserDefault** + +* **NSUserDefaults**と**インターフェース**を持ち、macOS上の**アプリケーション**または**グローバル**な設定を保存します。 + +* **getUserDefault**は、**最近のファイルの場所**や**ユーザーの地理的位置**などの機密情報を**取得**できます。 + +* **setUserDefault**は、これらの設定を**変更**でき、アプリの**構成**に影響を与える可能性があります。 + +* **古いElectronバージョン**(v8.3.0以前)では、**標準スイート**のNSUserDefaultsのみが**アクセス可能**でした。 + +## Shell.showItemInFolder + +この関数は、指定されたファイルをファイルマネージャーで表示し、**ファイルを自動的に実行する可能性があります**。 + +詳細については[https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html](https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html)を確認してください。 + +## **Tools** + +- [**Electronegativity**](https://github.com/doyensec/electronegativity)は、Electronベースのアプリケーションにおける設定ミスやセキュリティのアンチパターンを特定するためのツールです。 +- [**Electrolint**](https://github.com/ksdmitrieva/electrolint)は、Electronegativityを使用するElectronアプリケーション用のオープンソースのVS Codeプラグインです。 +- [**nodejsscan**](https://github.com/ajinabraham/nodejsscan)は、脆弱なサードパーティライブラリをチェックします。 +- [**Electro.ng**](https://electro.ng/): 購入が必要です。 + +## Labs + +[https://www.youtube.com/watch?v=xILfQGkLXQo\&t=22s](https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s)で脆弱なElectronアプリを悪用するためのラボを見つけることができます。 + +ラボを手助けするいくつかのコマンド: ```bash # Download apps from these URls # Vuln to nodeIntegration @@ -307,7 +397,8 @@ npm start - [https://speakerdeck.com/masatokinugawa/electron-abusing-the-lack-of-context-isolation-curecon-en?slide=8](https://speakerdeck.com/masatokinugawa/electron-abusing-the-lack-of-context-isolation-curecon-en?slide=8) - [https://www.youtube.com/watch?v=a-YnG3Mx-Tg](https://www.youtube.com/watch?v=a-YnG3Mx-Tg) - [https://www.youtube.com/watch?v=xILfQGkLXQo\&t=22s](https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s) -- More researches and write-ups about Electron security in [https://github.com/doyensec/awesome-electronjs-hacking](https://github.com/doyensec/awesome-electronjs-hacking) +- Electronのセキュリティに関するさらなる研究と記事は[https://github.com/doyensec/awesome-electronjs-hacking](https://github.com/doyensec/awesome-electronjs-hacking)で確認できます。 - [https://www.youtube.com/watch?v=Tzo8ucHA5xw\&list=PLH15HpR5qRsVKcKwvIl-AzGfRqKyx--zq\&index=81](https://www.youtube.com/watch?v=Tzo8ucHA5xw&list=PLH15HpR5qRsVKcKwvIl-AzGfRqKyx--zq&index=81) +- [https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html](https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html) {{#include ../../../banners/hacktricks-training.md}}