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 2f90d5c55..ac9147241 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**),尽管它缺乏现代浏览器的一些安全机制。 -通常,您可能会在`.asar`应用程序中找到electron应用程序代码,获取代码需要提取它: +通常,您可能会在`.asar`应用程序中找到electron应用代码,获取代码需要提取它: ```bash npx asar extract app.asar destfolder #Extract everything npx asar extract-file app.asar main.js #Extract just a file @@ -20,7 +20,7 @@ npx asar extract-file app.asar main.js #Extract just a file Electron 有 2 种进程类型: - 主进程(完全访问 NodeJS) -- 渲染进程(出于安全原因,应该限制 NodeJS 的访问) +- 渲染进程(出于安全原因,应该限制对 NodeJS 的访问) ![](<../../../images/image (182).png>) @@ -32,15 +32,15 @@ let win = new BrowserWindow() //Open Renderer Process win.loadURL(`file://path/to/index.html`) ``` -**renderer process** 的设置可以在 **main process** 中的 main.js 文件中进行 **配置**。一些配置将 **防止 Electron 应用程序获取 RCE** 或其他漏洞,如果 **设置正确配置**。 +设置 **renderer process** 可以在 **main process** 的 main.js 文件中 **配置**。一些配置将 **防止 Electron 应用程序获取 RCE** 或其他漏洞,如果 **设置正确配置**。 -Electron 应用程序 **可以通过 Node apis 访问设备**,尽管可以配置以防止它: +Electron 应用程序 **可以通过 Node API 访问设备**,尽管可以配置以防止它: -- **`nodeIntegration`** - 默认情况下为 `off`。如果开启,允许从 renderer process 访问 node 特性。 +- **`nodeIntegration`** - 默认情况下为 `off`。如果开启,允许从 renderer process 访问 Node 特性。 - **`contextIsolation`** - 默认情况下为 `on`。如果关闭,主进程和渲染进程不被隔离。 - **`preload`** - 默认情况下为空。 - [**`sandbox`**](https://docs.w3cub.com/electron/api/sandbox-option) - 默认情况下为 off。它将限制 NodeJS 可以执行的操作。 -- 工作线程中的 Node 集成 +- Node Integration in Workers - **`nodeIntegrationInSubframes`** - 默认情况下为 `off`。 - 如果 **`nodeIntegration`** 被 **启用**,这将允许在 Electron 应用程序中 **加载在 iframe 中的网页** 使用 **Node.js APIs**。 - 如果 **`nodeIntegration`** 被 **禁用**,则预加载将在 iframe 中加载。 @@ -71,7 +71,7 @@ spellcheck: true, }, } ``` -一些 **RCE payloads** 来自 [here](https://7as.es/electron/nodeIntegration_rce.txt): +一些 **RCE payloads** 来自 [这里](https://7as.es/electron/nodeIntegration_rce.txt): ```html Example Payloads (Windows): ## RCE: XSS + nodeIntegration -如果 **nodeIntegration** 设置为 **on**,网页的 JavaScript 可以通过调用 `require()` 轻松使用 Node.js 功能。例如,在 Windows 上执行计算器应用程序的方法是: +如果 **nodeIntegration** 设置为 **on**,网页的 JavaScript 可以通过调用 `require()` 轻松使用 Node.js 功能。例如,在 Windows 上执行 calc 应用程序的方法是: ```html ``` +## Remote module + +Electron Remote模块允许**渲染进程访问主进程API**,促进Electron应用程序内的通信。然而,启用此模块会引入显著的安全风险。它扩大了应用程序的攻击面,使其更容易受到跨站脚本(XSS)攻击等漏洞的影响。 + +> [!TIP] +> 尽管**remote**模块将一些API从主进程暴露给渲染进程,但仅仅通过滥用组件并不容易获得RCE。然而,这些组件可能会暴露敏感信息。 + +> [!WARNING] +> 许多仍然使用remote模块的应用程序以**需要在渲染进程中启用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)`** +- **设置**或**移除****自定义Jump List**(在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** 之前,您可以通过将 **nil** 传递给 CFNotificationCenterAddObserver 来嗅探 **所有** 分发的通知。 +* 在 **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) + ## **工具** -- [**Electronegativity**](https://github.com/doyensec/electronegativity) 是一个用于识别基于 Electron 的应用程序中的错误配置和安全反模式的工具。 +- [**Electronegativity**](https://github.com/doyensec/electronegativity) 是一个识别 Electron 应用程序中的错误配置和安全反模式的工具。 - [**Electrolint**](https://github.com/ksdmitrieva/electrolint) 是一个用于 Electron 应用程序的开源 VS Code 插件,使用 Electronegativity。 - [**nodejsscan**](https://github.com/ajinabraham/nodejsscan) 用于检查易受攻击的第三方库 -- [**Electro.ng**](https://electro.ng/): 你需要购买它 +- [**Electro.ng**](https://electro.ng/): 您需要购买它 ## 实验室 -在 [https://www.youtube.com/watch?v=xILfQGkLXQo\&t=22s](https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s) 中,你可以找到一个利用易受攻击的 Electron 应用程序的实验室。 +在 [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 @@ -309,5 +399,6 @@ npm start - [https://www.youtube.com/watch?v=xILfQGkLXQo\&t=22s](https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s) - 更多关于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}}