# Az - Tokens & Public Applications

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

## Osnovne Informacije

Entra ID je Microsoftova platforma za upravljanje identitetom i pristupom (IAM) zasnovana na oblaku, koja služi kao osnovni sistem za autentifikaciju i autorizaciju za usluge kao što su Microsoft 365 i Azure Resource Manager. Azure AD implementira OAuth 2.0 okvir za autorizaciju i OpenID Connect (OIDC) protokol za autentifikaciju kako bi upravljao pristupom resursima.

### OAuth

**Ključni učesnici u OAuth 2.0:**

1. **Server resursa (RS):** Štiti resurse koje poseduje vlasnik resursa.
2. **Vlasnik resursa (RO):** Obično krajnji korisnik koji poseduje zaštićene resurse.
3. **Klijentska aplikacija (CA):** Aplikacija koja traži pristup resursima u ime vlasnika resursa.
4. **Server za autorizaciju (AS):** Izdaje pristupne tokene klijentskim aplikacijama nakon autentifikacije i autorizacije.

**Opsezi i saglasnost:**

- **Opsezi:** Granularne dozvole definisane na serveru resursa koje specificiraju nivoe pristupa.
- **Saglasnost:** Proces kojim vlasnik resursa daje klijentskoj aplikaciji dozvolu za pristup resursima sa specifičnim opsezima.

**Integracija sa Microsoft 365:**

- Microsoft 365 koristi Azure AD za IAM i sastoji se od više "prvih strana" OAuth aplikacija.
- Ove aplikacije su duboko integrisane i često imaju međuzavisne odnose usluga.
- Da bi pojednostavio korisničko iskustvo i održao funkcionalnost, Microsoft daje "implicitnu saglasnost" ili "pre-saglasnost" ovim aplikacijama prve strane.
- **Implicitna saglasnost:** Određene aplikacije automatski **dobijaju pristup specifičnim opsezima bez eksplicitne saglasnosti korisnika ili administratora**.
- Ovi pre-saglašeni opsezi su obično skriveni i od korisnika i od administratora, čineći ih manje vidljivim u standardnim upravljačkim interfejsima.

**Tipovi klijentskih aplikacija:**

1. **Poverljivi klijenti:**
- Imaju svoje sopstvene akreditive (npr. lozinke ili sertifikate).
- Mogu **sigurno da se autentifikuju** na serveru za autorizaciju.
2. **Javni klijenti:**
- Nemaju jedinstvene akreditive.
- Ne mogu sigurno da se autentifikuju na serveru za autorizaciju.
- **Bezbednosna implikacija:** Napadač može da se pretvara da je javna klijentska aplikacija prilikom traženja tokena, jer ne postoji mehanizam za server za autorizaciju da verifikuje legitimnost aplikacije.

## Autentifikacioni Tokeni

Postoje **tri tipa tokena** koji se koriste u OIDC:

- [**Pristupni tokeni**](https://learn.microsoft.com/en-us/azure/active-directory/develop/access-tokens)**:** Klijent predstavlja ovaj token serveru resursa da bi **pristupio resursima**. Može se koristiti samo za specifičnu kombinaciju korisnika, klijenta i resursa i **ne može biti opozvan** do isteka - što je 1 sat po defaultu.
- **ID tokeni**: Klijent prima ovaj **token od servera za autorizaciju**. Sadrži osnovne informacije o korisniku. **Povezan je sa specifičnom kombinacijom korisnika i klijenta**.
- **Refresh tokeni**: Dodeljuju se klijentu zajedno sa pristupnim tokenom. Koriste se za **dobijanje novih pristupnih i ID tokena**. Povezani su sa specifičnom kombinacijom korisnika i klijenta i mogu biti opozvani. Podrazumevano vreme isteka je **90 dana** za neaktivne refresh tokene i **nema isteka za aktivne tokene** (iz refresh tokena je moguće dobiti nove refresh tokene).
- Refresh token treba biti vezan za **`aud`**, za neke **opsege**, i za **tenanta** i treba da može da generiše pristupne tokene samo za taj aud, opsege (i ništa više) i tenant. Međutim, ovo nije slučaj sa **FOCI aplikacijama tokena**.
- Refresh token je enkriptovan i samo Microsoft može da ga dekriptuje.
- Dobijanje novog refresh tokena ne opoziva prethodni refresh token.

> [!WARNING]
> Informacije za **uslovni pristup** su **smeštene** unutar **JWT**. Dakle, ako zatražite **token sa dozvoljene IP adrese**, ta **IP** će biti **smeštena** u tokenu i tada možete koristiti taj token sa **nedozvoljene IP adrese za pristup resursima**.

### Pristupni Tokeni "aud"

Polje označeno u "aud" polju je **server resursa** (aplikacija) koji se koristi za obavljanje prijave.

Komanda `az account get-access-token --resource-type [...]` podržava sledeće tipove i svaki od njih će dodati specifičan "aud" u rezultantnom pristupnom tokenu:

> [!CAUTION]
> Imajte na umu da su sledeće samo API-jevi podržani od strane `az account get-access-token`, ali ih ima više.

<details>

<summary>aud primeri</summary>

- **aad-graph (Azure Active Directory Graph API)**: Koristi se za pristup starom Azure AD Graph API (ukinut), koji omogućava aplikacijama da čitaju i pišu podatke direktorijuma u Azure Active Directory (Azure AD).
- `https://graph.windows.net/`

* **arm (Azure Resource Manager)**: Koristi se za upravljanje Azure resursima putem Azure Resource Manager API-ja. Ovo uključuje operacije kao što su kreiranje, ažuriranje i brisanje resursa kao što su virtuelne mašine, skladišni nalozi i još mnogo toga.
- `https://management.core.windows.net/ or https://management.azure.com/`

- **batch (Azure Batch Services)**: Koristi se za pristup Azure Batch, usluzi koja omogućava efikasno izvođenje aplikacija za paralelno i visokoperformantno računanje u oblaku.
- `https://batch.core.windows.net/`

* **data-lake (Azure Data Lake Storage)**: Koristi se za interakciju sa Azure Data Lake Storage Gen1, koja je skalabilna usluga za skladištenje podataka i analitiku.
- `https://datalake.azure.net/`

- **media (Azure Media Services)**: Koristi se za pristup Azure Media Services, koje pružaju usluge obrade i isporuke medija zasnovane na oblaku za video i audio sadržaj.
- `https://rest.media.azure.net`

* **ms-graph (Microsoft Graph API)**: Koristi se za pristup Microsoft Graph API-ju, jedinstvenom kraju za podatke usluga Microsoft 365. Omogućava vam pristup podacima i uvidima iz usluga kao što su Azure AD, Office 365, Enterprise Mobility i Security usluge.
- `https://graph.microsoft.com`

- **oss-rdbms (Azure Open Source Relational Databases)**: Koristi se za pristup Azure Database uslugama za open-source relacione baze podataka kao što su MySQL, PostgreSQL i MariaDB.
- `https://ossrdbms-aad.database.windows.net`

</details>

### Pristupni Tokeni Opsezi "scp"

Opseg pristupnog tokena se čuva unutar scp ključa unutar JWT pristupnog tokena. Ovi opsezi definišu šta pristupni token može da pristupi.

Ako je JWT dozvoljeno da kontaktira određeni API, ali **nema opseg** za izvršenje tražene radnje, **neće moći da izvrši radnju** sa tim JWT-om.

### Primer dobijanja refresh & pristupnog tokena
```python
# Code example from https://github.com/secureworks/family-of-client-ids-research
import msal
import requests
import jwt
from pprint import pprint
from typing import Any, Dict, List


# LOGIN VIA CODE FLOW AUTHENTICATION
azure_cli_client = msal.PublicClientApplication(
"04b07795-8ddb-461a-bbee-02f9e1bf7b46" # ID for Azure CLI client
)
device_flow = azure_cli_client.initiate_device_flow(
scopes=["https://graph.microsoft.com/.default"]
)
print(device_flow["message"])

# Perform device code flow authentication

azure_cli_bearer_tokens_for_graph_api = azure_cli_client.acquire_token_by_device_flow(
device_flow
)
pprint(azure_cli_bearer_tokens_for_graph_api)


# DECODE JWT
def decode_jwt(base64_blob: str) -> Dict[str, Any]:
"""Decodes base64 encoded JWT blob"""
return jwt.decode(
base64_blob, options={"verify_signature": False, "verify_aud": False}
)
decoded_access_token = decode_jwt(
azure_cli_bearer_tokens_for_graph_api.get("access_token")
)
pprint(decoded_access_token)


# GET NEW ACCESS TOKEN AND REFRESH TOKEN
new_azure_cli_bearer_tokens_for_graph_api = (
# Same client as original authorization
azure_cli_client.acquire_token_by_refresh_token(
azure_cli_bearer_tokens_for_graph_api.get("refresh_token"),
# Same scopes as original authorization
scopes=["https://graph.microsoft.com/.default"],
)
)
pprint(new_azure_cli_bearer_tokens_for_graph_api)
```
### Ostala polja pristupnog tokena

- **appid**: ID aplikacije koji se koristi za generisanje tokena
- **appidacr**: Referenca klase konteksta autentifikacije aplikacije ukazuje na to kako je klijent autentifikovan, za javnog klijenta vrednost je 0, a ako se koristi tajna klijenta vrednost je 1
- **acr**: Zahtev za referencom klase konteksta autentifikacije je "0" kada autentifikacija krajnjeg korisnika nije ispunila zahteve ISO/IEC 29115.
- **amr**: Metoda autentifikacije ukazuje na to kako je token autentifikovan. Vrednost “pwd” ukazuje da je korišćena lozinka.
- **groups**: Ukazuje na grupe u kojima je glavni korisnik član.
- **iss**: Izdavač identifikuje servis za bezbednosne tokene (STS) koji je generisao token. npr. https://sts.windows.net/fdd066e1-ee37-49bc-b08f-d0e152119b04/ (uuid je ID zakupca)
- **oid**: ID objekta glavnog korisnika
- **tid**: ID zakupca
- **iat, nbf, exp**: Izdato (kada je izdato), Ne pre (ne može se koristiti pre ovog vremena, obično ista vrednost kao iat), Vreme isteka.

## FOCI Tokeni Eskalacija privilegija

Prethodno je pomenuto da bi refresh tokeni trebali biti vezani za **opsege** sa kojima su generisani, za **aplikaciju** i **zakupca** za koje su generisani. Ako se bilo koja od ovih granica prekine, moguće je eskalirati privilegije jer će biti moguće generisati pristupne tokene za druge resurse i zakupce kojima korisnik ima pristup i sa više opsega nego što je prvobitno predviđeno.

Štaviše, **to je moguće sa svim refresh tokenima** u [Microsoft identity platform](https://learn.microsoft.com/en-us/entra/identity-platform/) (Microsoft Entra računi, Microsoft lični računi i društveni računi kao što su Facebook i Google) jer, kao što [**dokumentacija**](https://learn.microsoft.com/en-us/entra/identity-platform/refresh-tokens) pominje: "Refresh tokeni su vezani za kombinaciju korisnika i klijenta, ali **nisu vezani za resurs ili zakupca**. Klijent može koristiti refresh token za dobijanje pristupnih tokena **kroz bilo koju kombinaciju resursa i zakupca** gde ima dozvolu da to učini. Refresh tokeni su enkriptovani i samo Microsoft identity platform može da ih pročita."

Takođe, imajte na umu da su FOCI aplikacije javne aplikacije, tako da **nije potrebna tajna** za autentifikaciju na serveru.

Poznati FOCI klijenti prijavljeni u [**originalnom istraživanju**](https://github.com/secureworks/family-of-client-ids-research/tree/main) mogu se [**pronaći ovde**](https://github.com/secureworks/family-of-client-ids-research/blob/main/known-foci-clients.csv).

### Dobijanje različitog opsega

Nastavljajući sa prethodnim primerom koda, u ovom kodu se traži novi token za različit opseg:
```python
# Code from https://github.com/secureworks/family-of-client-ids-research
azure_cli_bearer_tokens_for_outlook_api = (
# Same client as original authorization
azure_cli_client.acquire_token_by_refresh_token(
new_azure_cli_bearer_tokens_for_graph_api.get(
"refresh_token"
),
# But different scopes than original authorization
scopes=[
"https://outlook.office.com/.default"
],
)
)
pprint(azure_cli_bearer_tokens_for_outlook_api)
```
### Dobijanje različitih klijenata i opsega
```python
# Code from https://github.com/secureworks/family-of-client-ids-research
microsoft_office_client = msal.PublicClientApplication("d3590ed6-52b3-4102-aeff-aad2292ab01c")
microsoft_office_bearer_tokens_for_graph_api = (
# This is a different client application than we used in the previous examples
microsoft_office_client.acquire_token_by_refresh_token(
# But we can use the refresh token issued to our original client application
azure_cli_bearer_tokens_for_outlook_api.get("refresh_token"),
# And request different scopes too
scopes=["https://graph.microsoft.com/.default"],
)
)
# How is this possible?
pprint(microsoft_office_bearer_tokens_for_graph_api)
```
## Gde pronaći tokene

Iz perspektive napadača, veoma je zanimljivo znati gde je moguće pronaći pristupne i osvežavajuće tokene kada je, na primer, PC žrtve kompromitovan:

- Unutar **`<HOME>/.Azure`**
- **`azureProfile.json`** sadrži informacije o prijavljenim korisnicima iz prošlosti
- **`clouds.config` sadrži** informacije o pretplatama
- **`service_principal_entries.json`** sadrži akreditive aplikacija (tenant id, klijente i tajnu). Samo na Linuxu i macOS-u
- **`msal_token_cache.json`** sadrži pristupne tokene i osvežavajuće tokene. Samo na Linuxu i macOS-u
- **`service_principal_entries.bin`** i **`msal_token_cache.bin`** se koriste na Windows-u i su enkriptovani sa DPAPI
- **`msal_http_cache.bin`** je keš HTTP zahteva
- Učitajte ga: `with open("msal_http_cache.bin", 'rb') as f: pickle.load(f)`
- **`AzureRmContext.json`** sadrži informacije o prethodnim prijavama koristeći Az PowerShell (ali ne i akreditive)
- Unutar **`C:\Users\<username>\AppData\Local\Microsoft\IdentityCache\*`** se nalaze nekoliko `.bin` fajlova sa **pristupnim tokenima**, ID tokenima i informacijama o nalogu enkriptovanim sa korisnikovim DPAPI.
- Moguće je pronaći više **pristupnih tokena** u `.tbres` fajlovima unutar **`C:\Users\<username>\AppData\Local\Microsoft\TokenBroken\Cache\`** koji sadrže base64 enkriptovane sa DPAPI pristupne tokene.
- Na Linuxu i macOS-u možete dobiti **pristupne tokene, osvežavajuće tokene i id tokene** iz Az PowerShell-a (ako se koristi) pokretanjem `pwsh -Command "Save-AzContext -Path /tmp/az-context.json"`
- Na Windows-u ovo samo generiše id tokene.
- Moguće je videti da li je Az PowerShell korišćen na Linuxu i macOS-u proverom da li `$HOME/.local/share/.IdentityService/` postoji (iako su sadržani fajlovi prazni i beskorisni)
- Ako je korisnik **prijavljen unutar Azure-a putem pregledača**, prema ovom [**postu**](https://www.infosecnoodle.com/p/obtaining-microsoft-entra-refresh?r=357m16&utm_campaign=post&utm_medium=web) moguće je započeti tok autentifikacije sa **preusmeravanjem na localhost**, omogućiti pretraživaču da automatski autorizuje prijavu i primiti osvežavajući token. Imajte na umu da postoji samo nekoliko FOCI aplikacija koje omogućavaju preusmeravanje na localhost (kao što su az cli ili PowerShell modul), tako da ove aplikacije moraju biti dozvoljene.

## Reference

- [https://github.com/secureworks/family-of-client-ids-research](https://github.com/secureworks/family-of-client-ids-research)
- [https://github.com/Huachao/azure-content/blob/master/articles/active-directory/active-directory-token-and-claims.md](https://github.com/Huachao/azure-content/blob/master/articles/active-directory/active-directory-token-and-claims.md)

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