From d37297568a521b3479e63f7a0a024db02bbac084 Mon Sep 17 00:00:00 2001 From: Translator Date: Tue, 7 Jan 2025 18:15:41 +0000 Subject: [PATCH] Translated ['src/network-services-pentesting/pentesting-web/electron-des --- .gitignore | 1 + hacktricks-preprocessor.py | 53 ++++-- .../electron-desktop-apps/README.md | 151 ++++++++++++++---- 3 files changed, 158 insertions(+), 47 deletions(-) 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 c607e7add..be14b42ce 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 kombinuje lokalni backend (sa **NodeJS**) i frontend (**Chromium**), iako mu nedostaju neki od bezbednosnih mehanizama modernih pregledača. -Obično možete pronaći kod electron aplikacije unutar `.asar` aplikacije, da biste dobili kod potrebno je da ga ekstrahujete: +Obično možete pronaći kod electron aplikacije unutar `.asar` aplikacije, kako biste dobili kod, potrebno je da ga ekstrahujete: ```bash npx asar extract app.asar destfolder #Extract everything npx asar extract-file app.asar main.js #Extract just a file @@ -20,11 +20,11 @@ U izvornoj kodu Electron aplikacije, unutar `packet.json`, možete pronaći nave Electron ima 2 tipa procesa: - Glavni proces (ima potpun pristup NodeJS-u) -- Proces renderovanja (treba da ima ograničen pristup NodeJS-u iz bezbednosnih razloga) +- Proces renderera (treba da ima ograničen pristup NodeJS-u iz bezbednosnih razloga) ![](<../../../images/image (182).png>) -**Proces renderovanja** će biti prozor pregledača koji učitava datoteku: +**Proces renderera** će biti prozor pregledača koji učitava datoteku: ```javascript const { BrowserWindow } = require("electron") let win = new BrowserWindow() @@ -32,18 +32,18 @@ let win = new BrowserWindow() //Open Renderer Process win.loadURL(`file://path/to/index.html`) ``` -Podešavanja **renderer procesa** mogu se **konfigurisati** u **main procesu** unutar main.js datoteke. Neka od podešavanja će **sprečiti Electron aplikaciju da dobije RCE** ili druge ranjivosti ako su **podešavanja ispravno konfigurisana**. +Podešavanja **renderer process** mogu se **konfigurisati** u **main process** unutar main.js datoteke. Neka od podešavanja će **sprečiti Electron aplikaciju da dobije RCE** ili druge ranjivosti ako su **podešavanja ispravno konfigurisana**. Electron aplikacija **može pristupiti uređaju** putem Node apija, iako se može konfigurisati da to spreči: -- **`nodeIntegration`** - je `isključen` po defaultu. Ako je uključen, omogućava pristup node funkcijama iz renderer procesa. -- **`contextIsolation`** - je `uključen` po defaultu. Ako je isključen, glavni i renderer procesi nisu izolovani. +- **`nodeIntegration`** - je `off` po defaultu. Ako je uključen, omogućava pristup node funkcijama iz renderer process. +- **`contextIsolation`** - je `on` po defaultu. Ako je isključen, main i renderer procesi nisu izolovani. - **`preload`** - prazan po defaultu. -- [**`sandbox`**](https://docs.w3cub.com/electron/api/sandbox-option) - je isključen po defaultu. Ograničiće radnje koje NodeJS može izvesti. -- Node Integration u Radnicima -- **`nodeIntegrationInSubframes`** - je `isključen` po defaultu. +- [**`sandbox`**](https://docs.w3cub.com/electron/api/sandbox-option) - je isključen po defaultu. Ograničiće akcije koje NodeJS može izvesti. +- Node Integration u Workers +- **`nodeIntegrationInSubframes`** - je `off` po defaultu. - Ako je **`nodeIntegration`** **omogućen**, to bi omogućilo korišćenje **Node.js API-a** na web stranicama koje su **učitane u iframes** unutar Electron aplikacije. -- Ako je **`nodeIntegration`** **onemogućen**, tada će preloadi biti učitani u iframe. +- Ako je **`nodeIntegration`** **onemogućen**, tada će preload-ovi učitati u iframe. Primer konfiguracije: ```javascript @@ -95,15 +95,15 @@ onerror="alert(require('child_process').execSync('ls -l').toString());" /> src="x" onerror="alert(require('child_process').execSync('uname -a').toString());" /> ``` -### Snimanje saobraćaja +### Capture traffic Izmenite start-main konfiguraciju i dodajte korišćenje proksija kao što su: ```javascript "start-main": "electron ./dist/main/main.js --proxy-server=127.0.0.1:8080 --ignore-certificateerrors", ``` -## Elektronska lokalna injekcija koda +## Electron lokalna injekcija koda -Ako možete lokalno izvršiti Elektronsku aplikaciju, moguće je da možete izvršiti proizvoljni JavaScript kod. Proverite kako u: +Ako možete lokalno izvršiti Electron aplikaciju, moguće je da možete izvršiti proizvoljan JavaScript kod. Proverite kako u: {{#ref}} ../../../macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-electron-applications-injection.md @@ -123,7 +123,7 @@ top.require("child_process").exec("open /System/Applications/Calculator.app") ## RCE: preload -Skripta navedena u ovoj postavci se **učitava pre drugih skripti u rendereru**, tako da ima **neograničen pristup Node API-ima**: +Skripta navedena u ovoj postavci se l**oaduje pre drugih skripti u rendereru**, tako da ima **neograničen pristup Node API-ima**: ```javascript new BrowserWindow{ webPreferences: { @@ -132,7 +132,7 @@ preload: _path2.default.join(__dirname, 'perload.js'), } }); ``` -Stoga, skripta može da eksportuje node-features na stranice: +Stoga, skript može da eksportuje node-features na stranice: ```javascript:preload.js typeof require === "function" window.runCalc = function () { @@ -177,7 +177,7 @@ electron-contextisolation-rce-via-ipc.md ### Obilaženje događaja klika -Ako postoje ograničenja primenjena kada kliknete na link, možda ćete moći da ih zaobiđete **srednjim klikom** umesto običnim levim klikom. +Ako postoje ograničenja koja se primenjuju kada kliknete na link, možda ćete moći da ih zaobiđete **srednjim klikom** umesto običnim levim klikom. ```javascript window.addEventListener('click', (e) => { ``` @@ -187,12 +187,12 @@ Za više informacija o ovim primerima pogledajte [https://shabarkin.medium.com/1 Kada se implementira Electron desktop aplikacija, osiguranje ispravnih podešavanja za `nodeIntegration` i `contextIsolation` je ključno. Utvrđeno je da **izvršavanje daljinskog koda na klijentskoj strani (RCE)** koje cilja preload skripte ili Electron-ov nativni kod iz glavnog procesa efikasno sprečava sa ovim podešavanjima. -Kada korisnik interaguje sa linkovima ili otvara nove prozore, aktiviraju se specifični slušaoci događaja, koji su ključni za sigurnost i funkcionalnost aplikacije: +Kada korisnik interaguje sa linkovima ili otvara nove prozore, aktiviraju se specifični slušaoci događaja, koji su ključni za bezbednost i funkcionalnost aplikacije: ```javascript webContents.on("new-window", function (event, url, disposition, options) {} webContents.on("will-navigate", function (event, url) {} ``` -Ovi slušatelji su **prepisani od strane desktop aplikacije** da implementiraju svoju **poslovnu logiku**. Aplikacija procenjuje da li bi navigirani link trebao biti otvoren interno ili u spoljašnjem web pretraživaču. Ova odluka se obično donosi putem funkcije, `openInternally`. Ako ova funkcija vrati `false`, to ukazuje da link treba biti otvoren spolja, koristeći funkciju `shell.openExternal`. +Ovi slušatelji su **prepisani od strane desktop aplikacije** kako bi implementirali svoju **poslovnu logiku**. Aplikacija procenjuje da li bi navigirani link trebao biti otvoren interno ili u spoljašnjem web pretraživaču. Ova odluka se obično donosi putem funkcije, `openInternally`. Ako ova funkcija vrati `false`, to ukazuje da link treba biti otvoren spolja, koristeći funkciju `shell.openExternal`. **Evo pojednostavljenog pseudokoda:** @@ -200,7 +200,9 @@ Ovi slušatelji su **prepisani od strane desktop aplikacije** da implementiraju ![https://miro.medium.com/max/1400/1*ZfgVwT3X1V_UfjcKaAccag.png](<../../../images/image (963).png>) -Electron JS sigurnosne najbolje prakse savetuju protiv prihvatanja nepouzdanog sadržaja sa funkcijom `openExternal`, jer to može dovesti do RCE kroz različite protokole. Operativni sistemi podržavaju različite protokole koji mogu izazvati RCE. Za detaljne primere i dalja objašnjenja o ovoj temi, može se konsultovati [ovaj resurs](https://positive.security/blog/url-open-rce#windows-10-19042), koji uključuje primere Windows protokola sposobnih za iskorišćavanje ove ranjivosti. +Electron JS sigurnosne najbolje prakse savetuju protiv prihvatanja nepouzdanog sadržaja sa funkcijom `openExternal`, jer to može dovesti do RCE kroz različite protokole. Operativni sistemi podržavaju različite protokole koji mogu pokrenuti RCE. Za detaljne primere i dalja objašnjenja o ovoj temi, može se konsultovati [ovaj resurs](https://positive.security/blog/url-open-rce#windows-10-19042), koji uključuje primere Windows protokola sposobnih za iskorišćavanje ove ranjivosti. + +Na macOS-u, funkcija `openExternal` može biti iskorišćena za izvršavanje proizvoljnih komandi kao u `shell.openExternal('file:///System/Applications/Calculator.app')`. **Primeri Windows protokolskih eksploatacija uključuju:** ```html @@ -222,13 +224,13 @@ window.open( ) ``` -## Čitanje internih fajlova: XSS + contextIsolation +## Čitanje unutrašnjih fajlova: XSS + contextIsolation -**Onemogućavanje `contextIsolation` omogućava korišćenje `` tagova**, sličnih `