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 f680d63c6..ddedf377c 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,4 +1,4 @@
-# Aplikacje desktopowe Electron
+# Aplikacje Desktopowe Electron
{{#include ../../../banners/hacktricks-training.md}}
@@ -6,7 +6,7 @@
Electron łączy lokalny backend (z **NodeJS**) i frontend (**Chromium**), chociaż brakuje mu niektórych mechanizmów zabezpieczeń nowoczesnych przeglądarek.
-Zazwyczaj kod aplikacji Electron można znaleźć wewnątrz aplikacji `.asar`, aby uzyskać kod, musisz go wyodrębnić:
+Zazwyczaj kod aplikacji electron można znaleźć wewnątrz aplikacji `.asar`, aby uzyskać kod, musisz go wyodrębnić:
```bash
npx asar extract app.asar destfolder #Extract everything
npx asar extract-file app.asar main.js #Extract just a file
@@ -32,17 +32,17 @@ let win = new BrowserWindow()
//Open Renderer Process
win.loadURL(`file://path/to/index.html`)
```
-Ustawienia **procesu renderera** mogą być **konfigurowane** w **procesie głównym** w pliku main.js. Niektóre z konfiguracji **zapobiegną uzyskaniu RCE** lub innych podatności, jeśli **ustawienia są poprawnie skonfigurowane**.
+Ustawienia **procesu renderera** mogą być **konfigurowane** w **procesie głównym** w pliku main.js. Niektóre z konfiguracji **zapobiegną uzyskaniu RCE przez aplikację Electron** lub inne podatności, jeśli **ustawienia są poprawnie skonfigurowane**.
Aplikacja electron **może uzyskać dostęp do urządzenia** za pomocą interfejsów API Node, chociaż można ją skonfigurować, aby temu zapobiec:
- **`nodeIntegration`** - jest `wyłączone` domyślnie. Jeśli włączone, pozwala na dostęp do funkcji node z procesu renderera.
- **`contextIsolation`** - jest `włączone` domyślnie. Jeśli wyłączone, procesy główny i renderera nie są izolowane.
- **`preload`** - pusty domyślnie.
-- [**`sandbox`**](https://docs.w3cub.com/electron/api/sandbox-option) - jest wyłączone domyślnie. Ograniczy to działania, które NodeJS może wykonać.
+- [**`sandbox`**](https://docs.w3cub.com/electron/api/sandbox-option) - jest wyłączone domyślnie. Ograniczy to działania, które NodeJS może wykonywać.
- Integracja Node w Workerach
- **`nodeIntegrationInSubframes`** - jest `wyłączone` domyślnie.
-- Jeśli **`nodeIntegration`** jest **włączone**, umożliwi to korzystanie z **API Node.js** na stronach internetowych, które są **ładowane w iframe** w aplikacji Electron.
+- Jeśli **`nodeIntegration`** jest **włączone**, pozwoli to na użycie **API Node.js** w stronach internetowych, które są **ładowane w iframe** w aplikacji Electron.
- Jeśli **`nodeIntegration`** jest **wyłączone**, wówczas preloady będą ładowane w iframe.
Przykład konfiguracji:
@@ -95,15 +95,15 @@ onerror="alert(require('child_process').execSync('ls -l').toString());" />
src="x"
onerror="alert(require('child_process').execSync('uname -a').toString());" />
```
-### Przechwytywanie ruchu
+### Capture traffic
-Zmień konfigurację start-main i dodaj użycie proxy, takiego jak:
+Zmodyfikuj konfigurację start-main i dodaj użycie proxy, takiego jak:
```javascript
"start-main": "electron ./dist/main/main.js --proxy-server=127.0.0.1:8080 --ignore-certificateerrors",
```
## Wstrzykiwanie kodu lokalnego w Electron
-Jeśli możesz lokalnie uruchomić aplikację Electron, istnieje możliwość, że możesz sprawić, aby wykonała dowolny kod JavaScript. Sprawdź jak w:
+Jeśli możesz lokalnie uruchomić aplikację Electron, istnieje możliwość, że możesz sprawić, aby wykonała dowolny kod javascript. Sprawdź jak w:
{{#ref}}
../../../macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-electron-applications-injection.md
@@ -111,7 +111,7 @@ Jeśli możesz lokalnie uruchomić aplikację Electron, istnieje możliwość,
## RCE: XSS + nodeIntegration
-Jeśli **nodeIntegration** jest ustawione na **włączone**, JavaScript na stronie internetowej może łatwo korzystać z funkcji Node.js, po prostu wywołując `require()`. Na przykład, sposób na uruchomienie aplikacji kalkulatora w systemie Windows to:
+Jeśli **nodeIntegration** jest ustawione na **włączone**, JavaScript na stronie internetowej może łatwo korzystać z funkcji Node.js, po prostu wywołując `require()`. Na przykład, sposób uruchomienia aplikacji kalkulatora w systemie Windows to:
```html
```
-## **Narzędzia**
+## Moduł zdalny
-- [**Electronegativity**](https://github.com/doyensec/electronegativity) to narzędzie do identyfikacji błędów konfiguracyjnych i wzorców antybezpieczeństwa w aplikacjach opartych na Electronie.
+Moduł Electron Remote pozwala **procesom renderującym na dostęp do API procesu głównego**, ułatwiając komunikację w aplikacji Electron. Jednak włączenie tego modułu wprowadza znaczące ryzyko bezpieczeństwa. Zwiększa to powierzchnię ataku aplikacji, czyniąc ją bardziej podatną na luki, takie jak ataki typu cross-site scripting (XSS).
+
+> [!TIP]
+> Chociaż moduł **remote** udostępnia niektóre API z procesu głównego do procesów renderujących, nie jest łatwo uzyskać RCE tylko poprzez nadużywanie komponentów. Jednak komponenty mogą ujawniać wrażliwe informacje.
+
+> [!WARNING]
+> Wiele aplikacji, które nadal używają modułu remote, robi to w sposób, który **wymaga włączenia NodeIntegration** w procesie renderującym, co stanowi **ogromne ryzyko bezpieczeństwa**.
+
+Od wersji Electron 14 moduł `remote` może być włączany w kilku krokach, ponieważ z powodów bezpieczeństwa i wydajności **zaleca się jego nieużywanie**.
+
+Aby go włączyć, najpierw należy **włączyć go w procesie głównym**:
+```javascript
+const remoteMain = require('@electron/remote/main')
+remoteMain.initialize()
+[...]
+function createMainWindow() {
+mainWindow = new BrowserWindow({
+[...]
+})
+remoteMain.enable(mainWindow.webContents)
+```
+Następnie proces renderera może importować obiekty z modułu, który lubi:
+```javascript
+import { dialog, getCurrentWindow } from '@electron/remote'
+```
+**[blog post](https://blog.doyensec.com/2021/02/16/electron-apis-misuse.html)** wskazuje na kilka interesujących **funkcji** udostępnionych przez obiekt **`app`** z modułu zdalnego:
+
+- **`app.relaunch([options])`**
+- **Restartuje** aplikację, **zatrzymując** bieżącą instancję i **uruchamiając** nową. Przydatne do **aktualizacji aplikacji** lub znaczących **zmian stanu**.
+- **`app.setAppLogsPath([path])`**
+- **Definiuje** lub **tworzy** katalog do przechowywania **logów aplikacji**. Logi można **pobierać** lub **modyfikować** za pomocą **`app.getPath()`** lub **`app.setPath(pathName, newPath)`**.
+- **`app.setAsDefaultProtocolClient(protocol[, path, args])`**
+- **Rejestruje** bieżący plik wykonywalny jako **domyślny handler** dla określonego **protokołu**. Możesz podać **niestandardową ścieżkę** i **argumenty**, jeśli to konieczne.
+- **`app.setUserTasks(tasks)`**
+- **Dodaje** zadania do **kategorii Zadań** w **Liście Szybkiego Dostępu** (na Windows). Każde zadanie może kontrolować, jak aplikacja jest **uruchamiana** lub jakie **argumenty** są przekazywane.
+- **`app.importCertificate(options, callback)`**
+- **Importuje** **certyfikat PKCS#12** do systemowego **magazynu certyfikatów** (tylko Linux). **Callback** może być użyty do obsługi wyniku.
+- **`app.moveToApplicationsFolder([options])`**
+- **Przenosi** aplikację do **folderu Aplikacji** (na macOS). Pomaga zapewnić **standardową instalację** dla użytkowników Maca.
+- **`app.setJumpList(categories)`**
+- **Ustawia** lub **usuwa** **niestandardową Listę Szybkiego Dostępu** na **Windows**. Możesz określić **kategorie**, aby zorganizować, jak zadania pojawiają się dla użytkownika.
+- **`app.setLoginItemSettings(settings)`**
+- **Konfiguruje**, które **pliki wykonywalne** uruchamiają się przy **logowaniu** wraz z ich **opcjonalnymi ustawieniami** (tylko macOS i Windows).
+```javascript
+Native.app.relaunch({args: [], execPath: "/System/Applications/Calculator.app/Contents/MacOS/Calculator"});
+Native.app.exit()
+```
+## systemPreferences module
+
+Główne API do uzyskiwania dostępu do preferencji systemowych i emitowania zdarzeń systemowych w Electron. Metody takie jak **subscribeNotification**, **subscribeWorkspaceNotification**, **getUserDefault** i **setUserDefault** są wszystkie **częścią** tego modułu.
+
+**Przykład użycia:**
+```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**
+
+* **Nasłuchuje** **natychmiastowych powiadomień macOS** za pomocą NSDistributedNotificationCenter.
+* Przed **macOS Catalina** można było podsłuchiwać **wszystkie** rozproszone powiadomienia, przekazując **nil** do CFNotificationCenterAddObserver.
+* Po **Catalina / Big Sur** aplikacje w piaskownicy mogą nadal **subskrybować** **wiele zdarzeń** (na przykład **blokady/odblokowania ekranu**, **montowanie woluminów**, **aktywność sieciowa** itp.) rejestrując powiadomienia **po nazwie**.
+
+### **getUserDefault / setUserDefault**
+
+* **Interfejsy** z **NSUserDefaults**, które przechowują **preferencje** aplikacji lub **globalne** na macOS.
+
+* **getUserDefault** może **pobierać** wrażliwe informacje, takie jak **ostatnie lokalizacje plików** lub **geograficzna lokalizacja użytkownika**.
+
+* **setUserDefault** może **modyfikować** te preferencje, potencjalnie wpływając na **konfigurację** aplikacji.
+
+* W **starszych wersjach Electron** (przed v8.3.0) dostępna była tylko **standardowa suite** NSUserDefaults.
+
+## Shell.showItemInFolder
+
+Ta funkcja wyświetla dany plik w menedżerze plików, co **może automatycznie wykonać plik**.
+
+Aby uzyskać więcej informacji, sprawdź [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) to narzędzie do identyfikacji błędów konfiguracyjnych i wzorców bezpieczeństwa w aplikacjach opartych na Electron.
- [**Electrolint**](https://github.com/ksdmitrieva/electrolint) to otwarty plugin VS Code dla aplikacji Electron, który wykorzystuje Electronegativity.
- [**nodejsscan**](https://github.com/ajinabraham/nodejsscan) do sprawdzania podatnych bibliotek stron trzecich.
- [**Electro.ng**](https://electro.ng/): Musisz to kupić.
-## Laboratoria
+## Labs
-W [https://www.youtube.com/watch?v=xILfQGkLXQo\&t=22s](https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s) znajdziesz laboratorium do eksploatacji podatnych aplikacji Electron.
+W [https://www.youtube.com/watch?v=xILfQGkLXQo\&t=22s](https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s) możesz znaleźć laboratorium do eksploatacji podatnych aplikacji Electron.
Niektóre polecenia, które pomogą Ci w laboratorium:
```bash
@@ -309,5 +399,6 @@ npm start
- [https://www.youtube.com/watch?v=xILfQGkLXQo\&t=22s](https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s)
- Więcej badań i artykułów na temat bezpieczeństwa Electron w [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}}