Translated ['', 'src/pentesting-cloud/azure-security/az-basic-informatio

This commit is contained in:
Translator
2026-03-31 16:58:24 +00:00
parent 761298eb0b
commit 46653d3c65
@@ -4,7 +4,7 @@
## Osnovne informacije
Entra ID je Microsoftova cloud platforma za upravljanje identitetima i pristupom (IAM), koja služi kao osnovni sistem za autentifikaciju i autorizaciju za servise poput Microsoft 365 i Azure Resource Manager. Azure AD implementira OAuth 2.0 authorization framework i OpenID Connect (OIDC) protokol za autentifikaciju radi upravljanja pristupom resursima.
Entra ID je Microsoft-ova cloud-based identity and access management (IAM) platforma, koja služi kao osnovni sistem za autentifikaciju i autorizaciju za servise kao što su Microsoft 365 i Azure Resource Manager. Azure AD implementira OAuth 2.0 authorization framework i OpenID Connect (OIDC) authentication protocol za upravljanje pristupom resursima.
### OAuth
@@ -13,88 +13,161 @@ Entra ID je Microsoftova cloud platforma za upravljanje identitetima i pristupom
1. **Resource Server (RS):** Štiti resurse koje poseduje vlasnik resursa.
2. **Resource Owner (RO):** Obično krajnji korisnik koji poseduje zaštićene resurse.
3. **Client Application (CA):** Aplikacija koja traži pristup resursima u ime vlasnika resursa.
4. **Authorization Server (AS):** Izdaje access tokens klijentskim aplikacijama nakon njihove autentifikacije i autorizacije.
4. **Authorization Server (AS):** Izdaje pristupne tokene klijentskim aplikacijama nakon njihove autentikacije i autorizacije.
**Scopes i pristanak:**
**Scopes i saglasnost:**
- **Scopes:** Granularne dozvole koje definiše resource server i koje preciziraju nivoe pristupa.
- **Consent:** Proces kojim resource owner daje dozvolu client aplikaciji da pristupi resursima sa određenim scopes.
- **Scopes:** Granularna dopuštenja definisana na resource server-u koja određuju nivoe pristupa.
- **Consent:** Proces kojim vlasnik resursa daje klijentskoj aplikaciji dozvolu za pristup resursima sa određenim scope-ovima.
**Integracija sa Microsoft 365:**
- Microsoft 365 koristi Azure AD za IAM i sastoji se od više "first-party" OAuth aplikacija.
- Ove aplikacije su duboko integrisane i često imaju međuzavisne servisne veze.
- Da bi pojednostavio korisničko iskustvo i održao funkcionalnost, Microsoft dodeljuje "implied consent" ili "pre-consent" ovim first-party aplikacijama.
- **Implied Consent:** Neke aplikacije su automatski **dobijaju pristup određenim scope-ovima bez izričitog odobrenja korisnika ili administratora**.
- Ovi pre-consented scopes su obično skriveni i od korisnika i od administratora, što ih čini manje vidljivim u standardnim upravljačkim interfejsima.
- Microsoft 365 koristi Azure AD za IAM i sastoji se iz više "first-party" OAuth aplikacija.
- Ove aplikacije su duboko integrisane i često imaju međuzavisne servisne odnose.
- Da bi se pojednostavio korisnički doživljaj i održala funkcionalnost, Microsoft dodeljuje "implied consent" ili "pre-consent" ovim first-party aplikacijama.
- **Implied Consent:** Određene aplikacije su automatski **odobrene za pristup određenim scope-ovima bez eksplicitnog odobrenja korisnika ili administratora**.
- Ovi pre-consentovani scope-ovi su obično skriveni i od korisnika i od administratora, što ih čini manje vidljivim u standardnim upravljačkim interfejsima.
**Tipovi klijentskih aplikacija:**
1. **Confidential Clients:**
- Imaju sopstvene kredencijale (npr. lozinke ili sertifikate).
- Mogu **sigurno da se autentifikuju** prema authorization server-u.
- Poseduju svoje kredencijale (npr. lozinke ili sertifikate).
- Mogu **sigurno se autentifikovati** prema authorization server-u.
2. **Public Clients:**
- Nemaju jedinstvene kredencijale.
- Ne mogu se sigurno autentifikovati prema authorization server-u.
- **Sigurnosna implikacija:** Napadač može da se lažno predstavi kao public client aplikacija prilikom zahteva za tokene, jer authorization server nema mehanizam za proveru legitimnosti aplikacije.
- **Bezbednosna implikacija:** Napadač može da se lažno predstavlja kao public client aplikacija prilikom zahtevanja tokena, jer nema mehanizma da authorization server verifikuje legitimnost aplikacije.
## Autentifikacioni tokeni
### ROPC / Password Grant
OAuth2 **Resource Owner Password Credentials** (**ROPC**) flow koristi direktan `POST` na `https://login.microsoftonline.com/<tenant>/oauth2/v2.0/token` sa `grant_type=password`, `username`, `password`, `client_id`, i traženim `scope`. U Entra ID ovo je prvenstveno zanimljivo za **public clients** jer napadač može ponovo iskoristiti Microsoft first-party client IDs ili bilo koji drugi dozvoljeni public client bez potrebe za secret-om.
```bash
curl -X POST "https://login.microsoftonline.com/<tenant>/oauth2/v2.0/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "client_id=f05ff7c9-f75a-4acd-a3b5-f4b6a870245d" \
--data-urlencode "client_info=1" \
--data-urlencode "grant_type=password" \
--data-urlencode "username=user@corp.com" \
--data-urlencode "password=Password123!" \
--data-urlencode "scope=https://graph.microsoft.com/.default"
```
If the credentials are valid and the flow is allowed, Entra can return **access tokens** and sometimes **refresh tokens** that are immediately usable against Microsoft Graph or the target resource.
### Klase zaobilaženja Entra ID sign-in log
Neki istorijski Entra ID bagovi su dozvoljavali **password validation** ili čak **full token issuance** bez generisanja očekivanog **Entra ID sign-in log** unosa. Ti slučajevi su ispravljeni, ali tehnike su i dalje korisne za razumevanje kako auth pipelines mogu zakazati na načine koji ostavljaju **downstream token use visible** dok je **upstream sign-in telemetry is absent**.
#### 1. Foreign-tenant endpoint for stealth password validation
Ako se zahtev pošalje token endpoint-u drugog tenant GUID-a, Entra može ipak proveriti da li je poslat password tačan za navedeni username pre nego što tok zakaže zato što korisnik ne postoji u tom stranom tenant-u. Istorijski je ovo omogućavalo:
- **Password spraying / credential validation** bez odgovarajućeg sign-in log zapisa u victim tenant-u
- Razliku u odgovoru koja otkriva da li je password korak uspeo
- No token issuance, ali manje telemetrije nego pri normalnom neuspelom logonu
#### 2. Force a post-password failure
Ako je parametar koji se koristi nakon credential validation nevažeći, kao što je nevažeći `client_id`, celokupna transakcija može da propadne iako je password već bio ispravan. Istorijski je ovo proizvelo prikaz neuspelog logovanja dok se krije činjenica da je pogodak password-a uspeo.
Šablon koji treba zapamtiti je:
- Password check succeeds
- A later validation step fails
- The log represents the final transaction state but not the successful password-validation step
#### 3. Trigger logging failure with oversized-but-valid values
Najopasnija klasa je kada zahtev ostane sintaktički važeći, autentifikacija uspe, **tokens are returned**, ali neko **logged field** bude dovoljno velik da slomi logging pipeline. Prijavljeni primeri su uključivali:
- Ponovljene validne scope-ove hiljadama puta, kao `openid openid openid ...`
- Slanje predugačkog, ali i dalje prihvaćenog **User-Agent** header-a
Ovo ukazuje na opštu klasu problema gde:
1. Entra validates credentials and request syntax
2. The token is issued successfully
3. Logging attempts to persist a raw user-controlled field
4. The logging write fails because of length or schema assumptions
5. The user obtains a valid token with no corresponding sign-in record
Example of the repeated-scope pattern:
```bash
curl -X POST "https://login.microsoftonline.com/${TENANT_ID}/oauth2/v2.0/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "client_id=f05ff7c9-f75a-4acd-a3b5-f4b6a870245d" \
--data-urlencode "client_info=1" \
--data-urlencode "grant_type=password" \
--data-urlencode "username=user@corp.com" \
--data-urlencode "password=Password123!" \
--data-urlencode "scope=$(for num in {1..10000}; do echo -n 'openid '; done)"
```
#### Napomena za otkrivanje / odbranu
Nemojte pretpostavljati da će svaka upotreba važećeg tokena imati odgovarajući Entra sign-in događaj. Prilikom istraživanja sumnjivih Graph aktivnosti, korrelirajte:
- **Ne-interaktivne sign-in logove**
- **Graph Activity Logs**
- **IP adresa**, **ID korisnika/objekta**, **identifikatori sesije/korelacije**, i **vremenske prozore**
Jedan praktičan metod validacije je da obuhvatite sumnjivi nevidljivi uspeh između dva normalna neuspešna logona i zatim proverite da li je očekivani niz `Failed -> Successful -> Failed` nestao srednji događaj nakon kašnjenja ingestovanja. Ako postoji downstream Graph aktivnost, ali sign-in log ne postoji, tretirajte to kao potencijalni **sign-in logging gap** ili uslov **token replay**.
## Authentication Tokens
Postoje **tri tipa tokena** koji se koriste u OIDC:
- [**Access Tokens**](https://learn.microsoft.com/en-us/azure/active-directory/develop/access-tokens)**:** Klijent predstavlja ovaj token resource server-u da bi **pristupio resursima**. Može se koristiti samo za specifičnu kombinaciju korisnika, klienta i resursa i **ne može biti opozvan** dok ne istekne - što je po defaultu 1 sat.
- **ID Tokens**: Klijent prima ovaj **token od authorization server-a**. Sadrži osnovne informacije o korisniku. On je **vezan za specifičnu kombinaciju korisnika i klijenta**.
- **Refresh Tokens**: Dodeljuje se klijentu zajedno sa access token-om. Koristi se za **dobijanje novih access i ID tokena**. Vezan je za specifičnu kombinaciju korisnika i klijenta i može biti opozvan. Podrazumevano isteknuće je **90 dana** za neaktivne refresh tokene i **nema isteka za aktivne tokene** (iz refresh token-a je moguće dobiti nove refresh tokene).
- Refresh token bi trebalo da bude vezan za **`aud`**, za određene **scopes**, i za **tenant**, i trebao bi da može generisati access tokene samo za taj aud, scopes (i ništa više) i tenant. Međutim, to nije slučaj sa **FOCI applications tokens**.
- [**Access Tokens**](https://learn.microsoft.com/en-us/azure/active-directory/develop/access-tokens)**:** Klijent predočuje ovaj token resource server-u 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 po defaultu 1 sat.
- **ID Tokens**: Klijent prima ovaj **token od authorization server-a**. Sadrži osnovne informacije o korisniku. **Povezan je sa specifičnom kombinacijom korisnika i klijenta**.
- **Refresh Tokens**: Izdaju se klijentu zajedno sa access token-om. Koriste se za **dobijanje novih access i ID tokena**. Vežu se za specifičnu kombinaciju korisnika i klijenta i mogu biti opozvani. Podrazumevano vreme isteka je **90 dana** za neaktivne refresh tokene i **nema isteka za aktivne tokene** (korišćenjem refresh tokena moguće je dobiti nove refresh tokene).
- Refresh token bi trebalo da bude vezan za **`aud`**, za neke **scopes**, i za **tenant** i trebalo bi da može da generiše access tokene samo za taj aud, te scope-ove (i ništa više) i tenant. Međutim, to nije slučaj sa **FOCI applications tokens**.
- Refresh token je enkriptovan i samo Microsoft može da ga dekriptuje.
- Dobijanje novog refresh token-a ne opoziva prethodni refresh token.
- Dobijanjem novog refresh tokena se prethodni refresh token ne opoziva.
> [!WARNING]
> Informacija o **conditional access** je **smeštena** unutar **JWT**. Dakle, ako zatražite **token sa dozvoljene IP adrese**, ta **IP** će biti **smeštena** u token i onda možete koristiti taj token sa **ne-dozvoljene IP adrese da pristupite resursima**.
> Informacije za **conditional access** su **smeštene** unutar **JWT**. Dakle, ako zatražite **token sa dozvoljene IP adrese**, ta **IP** će biti **smeštena** u tokenu i onda možete koristiti taj token sa **ne-dozvoljene IP adrese da pristupite resursima**.
### Access Tokens "aud"
Polje navedeno u "aud" polju predstavlja **resource server** (aplikaciju) koja se koristi za prijavu.
Polje označeno u "aud" polju je **resource server** (aplikacija) koja se koristi za prijavu.
Komanda `az account get-access-token --resource-type [...]` podržava sledeće tipove i svaki od njih će dodati specifičan "aud" u dobijeni access token:
Komanda `az account get-access-token --resource-type [...]` podržava sledeće tipove i svaki od njih će dodati specifičan "aud" u rezultujući access token:
> [!CAUTION]
> Imajte na umu da su sledeće samo API-ji koje podržava `az account get-access-token`, ali ima ih još.
> Imajte na umu da su sledeći samo API-ji podržani od strane `az account get-access-token`, ali postoji još.
<details>
<summary>aud examples</summary>
<summary>primeri aud</summary>
- **aad-graph (Azure Active Directory Graph API)**: Koristi se za pristup legacy Azure AD Graph API-ju (deprecated), koji omogućava aplikacijama da čitaju i pišu podatke direktorijuma u Azure Active Directory (Azure AD).
- **aad-graph (Azure Active Directory Graph API)**: Koristi se za pristup legacy Azure AD Graph API-ju (deprecated), koji omogućava aplikacijama čitanje i pisanje direktorijum podataka 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. To uključuje operacije kao što su kreiranje, ažuriranje i brisanje resursa poput virtuelnih mašina, storage naloga i drugih.
* **arm (Azure Resource Manager)**: Koristi se za upravljanje Azure resursima preko Azure Resource Manager API-ja. Ovo uključuje operacije poput kreiranja, ažuriranja i brisanja resursa kao što su virtuelne mašine, storage nalozi i više.
- `https://management.core.windows.net/ or https://management.azure.com/`
- **batch (Azure Batch Services)**: Koristi se za pristup Azure Batch-u, servisu koji omogućava efikasno pokretanje aplikacija za paralelne i visokoperformantne računarske zadatke u cloudu.
- **batch (Azure Batch Services)**: Koristi se za pristup Azure Batch-u, servisu koji omogućava efikasne velike paralelne i visokoperformansne kompjuterske aplikacije u cloudu.
- `https://batch.core.windows.net/`
* **data-lake (Azure Data Lake Storage)**: Koristi se za interakciju sa Azure Data Lake Storage Gen1, skalabilnim servisom za skladištenje podataka i analitiku.
* **data-lake (Azure Data Lake Storage)**: Koristi se za interakciju sa Azure Data Lake Storage Gen1, koji je skalabilan servis za skladištenje podataka i analitiku.
- `https://datalake.azure.net/`
- **media (Azure Media Services)**: Koristi se za pristup Azure Media Services, koji pruža cloud-bazirane servise za obradu i isporuku video i audio sadržaja.
- **media (Azure Media Services)**: Koristi se za pristup Azure Media Services, koji pruža cloud-bazirane servise za obradu i isporuku medija 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 endpointu za podatke iz Microsoft 365 servisa. Omogućava pristup podacima i uvidima iz servisa kao što su Azure AD, Office 365, Enterprise Mobility i Security servisi.
* **ms-graph (Microsoft Graph API)**: Koristi se za pristup Microsoft Graph API-ju, ujedinjenom endpointu za podatke Microsoft 365 servisa. Omogućava pristup podacima i uvidima iz servisa poput Azure AD, Office 365, Enterprise Mobility i Security servisa.
- `https://graph.microsoft.com`
- **oss-rdbms (Azure Open Source Relational Databases)**: Koristi se za pristup Azure Database servisima za open-source relacioni DB engine-e kao što su MySQL, PostgreSQL i MariaDB.
- **oss-rdbms (Azure Open Source Relational Databases)**: Koristi se za pristup Azure Database servisima za open-source relacioni database engine-e kao što su MySQL, PostgreSQL i MariaDB.
- `https://ossrdbms-aad.database.windows.net`
</details>
### Access Tokens Scopes "scp"
Opseg (scope) access token-a se čuva u ključu scp unutar JWT access tokena. Ovi scopes definišu čemu access token ima pristup.
Opseg access tokena je pohranjen u scp ključu unutar access token JWT-a. Ti scope-ovi definišu čemu access token ima pristup.
Ako je JWT dozvoljen da kontaktira određeni API ali **nema scope** za izvršenje tražene akcije, **neće moći da izvrši akciju** sa tim JWT-om.
Ako je JWT dozvoljen da kontaktira određeni API, ali **nema scope** za izvršenje tražene akcije, **neće moći da izvrši akciju** sa tim JWT-om.
### Primer: dobijanje refresh i access tokena
### Primer dobijanja refresh i access tokena
```python
# Code example from https://github.com/secureworks/family-of-client-ids-research
import msal
@@ -144,32 +217,32 @@ scopes=["https://graph.microsoft.com/.default"],
)
pprint(new_azure_cli_bearer_tokens_for_graph_api)
```
### Ostala polja access tokena
### Ostala polja access token-a
- **appid**: ID aplikacije koji je korišćen za generisanje tokena
- **appidacr**: The Application Authentication Context Class Reference označava kako je client autentifikovan; za public client vrednost je 0, a ako je korišćen client secret vrednost je 1
- **acr**: The Authentication Context Class Reference claim je "0" kada autentifikacija krajnjeg korisnika nije ispunila zahteve ISO/IEC 29115.
- **amr**: Metod autentifikacije pokazuje kako je token autentifikovan. Vrednost “pwd” označava da je korišćena lozinka.
- **groups**: Pokazuje grupe čiji je principal član.
- **iss**: Issuer identifikuje security token service (STS) koji je generisao token. e.g. https://sts.windows.net/fdd066e1-ee37-49bc-b08f-d0e152119b04/ (the uuid is the tenant ID)
- **appid**: ID aplikacije koji se koristi za generisanje tokena
- **appidacr**: Application Authentication Context Class Reference ukazuje kako je klijent autentifikovan; za public client vrednost je 0, a ako se koristi client secret vrednost je 1
- **acr**: Authentication Context Class Reference tvrdnja je "0" kada autentifikacija krajnjeg korisnika nije ispunila zahteve ISO/IEC 29115.
- **amr**: Authentication method ukazuje na koji način je token autentifikovan. Vrednost “pwd” označava da je korišćena lozinka.
- **groups**: Označava grupe čiji je principal član.
- **iss**: Issuer identifikuje security token service (STS) koji je generisao token. npr. https://sts.windows.net/fdd066e1-ee37-49bc-b08f-d0e152119b04/ (the uuid is the tenant ID)
- **oid**: Object ID principala
- **tid**: Tenant ID
- **iat, nbf, exp**: Issued at (vreme izdavanja), Not before (ne može se koristiti pre ovog vremena, obično ista vrednost kao iat), Expiration time (vreme isteka).
- **iat, nbf, exp**: Issued at (kada je izdat), Not before (ne može se koristiti pre tog vremena, obično ista vrednost kao iat), Expiration time (vreme isteka).
## FOCI Tokens Privilege Escalation
Ranije je pomenuto da refresh tokens treba da budu vezani za **scopes** sa kojima su generisani, za **application** i **tenant** za koje su generisani. Ako je bilo koja od ovih granica prekršena, moguće je eskalirati privilegije jer će biti moguće generisati access tokens za druge resurse i tenante kojima korisnik ima pristup i sa više scopes nego što je prvobitno bilo predviđeno.
Ranije je pomenuto da refresh tokens treba da budu vezani za **scopes** sa kojima su generisani, za **application** i **tenant** za koje su generisani. Ako se bilo koja od ovih granica prekrši, moguće je escalate privileges jer će biti moguće generisati access tokens za druge resurse i tenants kojima korisnik ima pristup i sa više scopes nego što je originalno bilo predviđeno.
Štaviše, **ovo je moguće sa svim refresh tokens** u [Microsoft identity platform](https://learn.microsoft.com/en-us/entra/identity-platform/) (Microsoft Entra accounts, Microsoft personal accounts, and social accounts like Facebook and Google) zato što, kako [**docs**](https://learn.microsoft.com/en-us/entra/identity-platform/refresh-tokens) navode: "Refresh tokens are bound to a combination of user and client, but **aren't tied to a resource or tenant**. A client can use a refresh token to acquire access tokens **across any combination of resource and tenant** where it has permission to do so. Refresh tokens are encrypted and only the Microsoft identity platform can read them."
Osim toga, **ovo je moguće sa svim refresh tokens** u [Microsoft identity platform](https://learn.microsoft.com/en-us/entra/identity-platform/) (Microsoft Entra accounts, Microsoft personal accounts, and social accounts like Facebook and Google) jer, kao što [**docs**](https://learn.microsoft.com/en-us/entra/identity-platform/refresh-tokens) navode: "Refresh tokens are bound to a combination of user and client, but **aren't tied to a resource or tenant**. A client can use a refresh token to acquire access tokens **across any combination of resource and tenant** where it has permission to do so. Refresh tokens are encrypted and only the Microsoft identity platform can read them."
Takođe, imajte na umu da su FOCI applications public applications, pa **nije potreban secret** za autentifikaciju prema serveru.
Takođe, imajte na umu da su FOCI aplikacije public applications, tako da **no secret is needed** da bi se autentifikovalo na server.
Then known FOCI clients reported in the [**original research**](https://github.com/secureworks/family-of-client-ids-research/tree/main) can be [**found here**](https://github.com/secureworks/family-of-client-ids-research/blob/main/known-foci-clients.csv).
Poznati FOCI klijenti prijavljeni u [**original research**](https://github.com/secureworks/family-of-client-ids-research/tree/main) mogu se [**found here**](https://github.com/secureworks/family-of-client-ids-research/blob/main/known-foci-clients.csv).
### Get different scope
### Zatraži drugi scope
Following with the previous example code, in this code it's requested a new token for a different scope:
Nastavljajući prethodni primer koda, u ovom kodu se zahteva novi token za drugi scope:
```python
# Code from https://github.com/secureworks/family-of-client-ids-research
azure_cli_bearer_tokens_for_outlook_api = (
@@ -186,7 +259,7 @@ scopes=[
)
pprint(azure_cli_bearer_tokens_for_outlook_api)
```
### Dohvatite drugačiji client i scope-ove
### Nabavite drugog klijenta i različite opsege
```python
# Code from https://github.com/secureworks/family-of-client-ids-research
microsoft_office_client = msal.PublicClientApplication("d3590ed6-52b3-4102-aeff-aad2292ab01c")
@@ -204,53 +277,53 @@ pprint(microsoft_office_bearer_tokens_for_graph_api)
```
## NAA / BroCI (Nested App Authentication / Broker Client Injection)
A BroCI refresh token je obrazac posredovane razmene tokena gde se postojeći refresh token koristi sa dodatnim broker parametrima da bi se zatražili tokeni kao druga pouzdana first-party aplikacija.
A BroCI refresh tokens is a brokered token exchange pattern where an existing refresh token is used with extra broker parameters to request tokens as another trusted first-party app.
Ovi refresh tokeni moraju biti izdate u tom broker kontekstu (a regular refresh token obično ne može da se koristi kao BroCI refresh token).
These refresh tokens must be minted in that broker context (a regular refresh token usually cannot be used as a BroCI refresh token).
### Cilj i svrha
Cilj BroCI-ja je da ponovo iskoristi važeću korisničku sesiju iz lanca aplikacija koje podržavaju broker i zatraži tokene za drugi par pouzdanih aplikacija/resursa. Dakle, omogućava "eskalaciju privilegija" sa originalnog tokena.
Cilj BroCI je ponovna upotreba važeće korisničke sesije iz lanca aplikacija koje podržavaju broker i zahtevanje tokena za drugi trusted first-party app/resource par. Time se omogućava "escalate privileges" iz originalnog tokena.
Sa napadačke perspektive, ovo je važno zato što:
Sa ofanzivne perspektive, ovo je važno zato što:
- Može otključati pre-consented first-party putanje koje nisu dostupne standardnim refresh razmenama.
- Može vratiti access tokene za visokovredne API-je (na primer Microsoft Graph) pod identitetima aplikacija sa širokim delegated permissions.
- Može otključati pre-consented first-party app putanje koje nisu dostupne standardnim refresh razmenama.
- Može vratiti access token-e za visokovredne API-je (na primer, Microsoft Graph) pod identitetima aplikacija sa širokim delegated permissions.
- Proširuje mogućnosti post-authentication token pivotinga izvan klasičnog FOCI client switching.
Ono što se menja kod NAA/BroCI refresh tokena nije vidljivi format tokena, već **issuance context** i broker-povezani metadata koje Microsoft validira tokom brokerovanih refresh operacija.
Ono što se menja kod NAA/BroCI refresh tokena nije vidljiv format tokena, već **issuance context** i broker-related metadata koju Microsoft validira tokom brokered refresh operacija.
NAA/BroCI token razmene **nisu** isto što i regularna OAuth refresh razmena.
NAA/BroCI token exchanges are **not** the same as a regular OAuth refresh exchange.
- A regular refresh token (na primer dobijen via device code flow) je obično validan za standard `grant_type=refresh_token` operacije.
- A BroCI request uključuje dodatni broker context (`brk_client_id`, broker `redirect_uri`, and `origin`).
- Microsoft validira da li je predstavljeni refresh token izdat u odgovarajućem brokerovanom kontekstu.
- Zbog toga, mnogi "normalni" refresh tokeni padaju u BroCI zahtevima sa greškama kao što su `AADSTS900054` ("Specified Broker Client ID does not match ID in provided grant").
- Generalno ne možete "convert" normalan refresh token u BroCI-validan u kodu.
- Potreban vam je refresh token koji je već izdat od strane kompatibilnog brokerovanog toka.
- A regular refresh token (for example obtained via device code flow) is usually valid for standard `grant_type=refresh_token` operations.
- A BroCI request includes additional broker context (`brk_client_id`, broker `redirect_uri`, and `origin`).
- Microsoft validates whether the presented refresh token was minted in a matching brokered context.
- Therefore, many "normal" refresh tokens fail in BroCI requests with errors such as `AADSTS900054` ("Specified Broker Client ID does not match ID in provided grant").
- You generally cannot "convert" a normal refresh token into a BroCI-valid one in code.
- You need a refresh token already issued by a compatible brokered flow.
Check the web **<https://entrascopes.com/>** to find BroCI configured apps an the trust relationships they have.
### Mentalni model
### Mental model
Razmislite o BroCI kao:
Think of BroCI as:
user session -> brokered refresh token issuance -> brokered refresh call (brk_client_id + redirect_uri + origin) -> access token for target trusted app/resource
`user session -> brokered refresh token issuance -> brokered refresh call (brk_client_id + redirect_uri + origin) -> access token for target trusted app/resource`
Ako se bilo koji deo tog broker lanca ne poklapa, razmena ne uspeva.
If any part of that broker chain does not match, the exchange fails.
### Gde naći BroCI-validan refresh token
### Gde pronaći BroCI-validan refresh token
Jedan praktičan način je prikupljanje saobraćaja portala u browseru:
Jedan praktičan način je prikupljanje saobraćaja iz browser portala:
1. Prijavite se na `https://entra.microsoft.com` (ili Azure portal).
2. Open DevTools -> Network.
2. Otvorite DevTools -> Network.
3. Filtrirajte po:
- `oauth2/v2.0/token`
- `management.core.windows.net`
4. Identifikujte brokerovani token response i kopirajte `refresh_token`.
5. Koristite taj refresh token sa odgovarajućim BroCI parametrima (`brk_client_id`, `redirect_uri`, `origin`) kada tražite tokene za ciljane aplikacije (na primer ADIbizaUX / Microsoft_Azure_PIMCommon scenariji).
4. Identifikujte brokered token odgovor i kopirajte `refresh_token`.
5. Koristite taj refresh token sa odgovarajućim BroCI parametrima (`brk_client_id`, `redirect_uri`, `origin`) prilikom zahtevanja tokena za ciljne aplikacije (na primer ADIbizaUX / Microsoft_Azure_PIMCommon scenariji).
### Uobičajene greške
@@ -533,24 +606,24 @@ raise SystemExit(main())
## Gde pronaći tokens
Sa aspekta napadača veoma je korisno znati gde je moguće pronaći access i refresh tokens, na primer kada je PC žrtve kompromitovan:
Sa aspekta napadača, vrlo je interesantno znati gde je moguće pronaći access i refresh tokens kada je, na primer, računar žrtve kompromitovan:
- Inside **`<HOME>/.Azure`**
- **`azureProfile.json`** sadrži informacije o korisnicima koji su bili prijavljeni ranije
- **`clouds.config contains`** informacije o subscriptions
- **`service_principal_entries.json`** sadrži kredencijale aplikacija (tenant id, clients i secret). Samo na Linux & macOS
- **`azureProfile.json`** sadrži informacije o korisnicima koji su se prethodno prijavljivali
- **`clouds.config contains`** info about subscriptions
- **`service_principal_entries.json`** sadrži credentials aplikacija (tenant id, clients and secret). Samo na Linux & macOS
- **`msal_token_cache.json`** sadrži access tokens i refresh tokens. Samo na Linux & macOS
- **`service_principal_entries.bin`** i msal_token_cache.bin se koriste na Windows-u i šifrovani su sa DPAPI
- **`msal_http_cache.bin`** je keš HTTP zahteva
- Load it: `with open("msal_http_cache.bin", 'rb') as f: pickle.load(f)`
- **`service_principal_entries.bin`** i msal_token_cache.bin se koriste na Windows i šifrovani su DPAPI-jem
- **`msal_http_cache.bin`** je keš HTTP request-a
- Učitajte ga: `with open("msal_http_cache.bin", 'rb') as f: pickle.load(f)`
- **`AzureRmContext.json`** sadrži informacije o prethodnim prijavama korišćenjem Az PowerShell (ali bez kredencijala)
- Inside **`C:\Users\<username>\AppData\Local\Microsoft\IdentityCache\*`** se nalaze nekoliko `.bin` fajlova sa **access tokens**, ID tokens i podacima o nalogu šifrovanim korisnikovim DPAPI.
- Moguće je pronaći više **access tokens** u `.tbres` fajlovima unutar **`C:\Users\<username>\AppData\Local\Microsoft\TokenBroken\Cache\`** koji sadrže base64 šifrovano DPAPI sa access tokens.
- Na Linux i macOS možete dobiti **access tokens, refresh tokens i id tokens** iz Az PowerShell (ako je korišćen) pokretanjem `pwsh -Command "Save-AzContext -Path /tmp/az-context.json"`
- Na Windows ovo generiše samo id tokens.
- Moguće je proveriti da li je Az PowerShell bio korišćen na Linux i macOS proverom da li postoji `$HOME/.local/share/.IdentityService/` (iako su sadržani fajlovi prazni i neupotrebljivi)
- Ako je korisnik **ulogovan u Azure preko browser-a**, prema ovom [**post**](https://www.infosecnoodle.com/p/obtaining-microsoft-entra-refresh?r=357m16&utm_campaign=post&utm_medium=web) moguće je pokrenuti authentication flow sa **redirect to localhost**, naterati browser da automatski autorizuje prijavu i primiti refresh token. Imajte na umu da postoji samo nekoliko FOCI aplikacija koje dozvoljavaju redirect to localhost (kao az cli ili powershell module), tako da te aplikacije moraju biti dozvoljene.
- Druga opcija objašnjena u blogu je upotreba alata [**BOF-entra-authcode-flow**](https://github.com/sudonoodle/BOF-entra-authcode-flow) koji može koristiti bilo koju aplikaciju zato što će **dohvatiti OAuth code da bi potom dobio refresh token iz title poslednje auth** stranice koristeći redirect URI `https://login.microsoftonline.com/common/oauth2/nativeclient`.
- Inside **`C:\Users\<username>\AppData\Local\Microsoft\IdentityCache\*`** se nalaze nekoliko `.bin` fajlova sa **access tokens**, ID tokens i informacijama o nalogu šifrovanim korisnikovim DPAPI-jem.
- Moguće je pronaći više **access tokens** u `.tbres` fajlovima unutar **`C:\Users\<username>\AppData\Local\Microsoft\TokenBroken\Cache\`** koji sadrže base64 šifrovano sa DPAPI-jem sa access tokens.
- Na Linuxu i macOS-u možete dobiti **access tokens, refresh tokens and id tokens** iz Az PowerShell (ako je korišćen) pokretanjem `pwsh -Command "Save-AzContext -Path /tmp/az-context.json"`
- Na Windows-u ovo generiše samo id tokens.
- Moguće je proveriti da li je Az PowerShell korišćen na Linuxu i macOS-u proverom da li postoji `$HOME/.local/share/.IdentityService/` (iako su sadržani fajlovi prazni i beskorisni)
- Ako je korisnik **logged inside Azure with the browser**, prema ovom [**post**](https://www.infosecnoodle.com/p/obtaining-microsoft-entra-refresh?r=357m16&utm_campaign=post&utm_medium=web) moguće je pokrenuti authentication flow sa **redirect to localhost**, naterati browser da automatski autorizuje prijavu i primiti refresh token. Napomena da postoji samo nekoliko FOCI aplikacija koje dozvoljavaju redirect na localhost (kao az cli ili powershell module), tako da te aplikacije moraju biti dozvoljene.
- Druga opcija objašnjena na blogu je korišćenje alata [**BOF-entra-authcode-flow**](https://github.com/sudonoodle/BOF-entra-authcode-flow) koji može koristiti bilo koju aplikaciju jer će **get the OAuth code to then get a refresh token from the title of the final auth** page koristeći redirect URI `https://login.microsoftonline.com/common/oauth2/nativeclient`.
## References
@@ -558,5 +631,6 @@ Sa aspekta napadača veoma je korisno znati gde je moguće pronaći access i ref
- [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)
- [https://specterops.io/blog/2025/10/15/naa-or-broci-let-me-explain/](https://specterops.io/blog/2025/10/15/naa-or-broci-let-me-explain/)
- [https://specterops.io/blog/2025/08/13/going-for-brokering-offensive-walkthrough-for-nested-app-authentication/](https://specterops.io/blog/2025/08/13/going-for-brokering-offensive-walkthrough-for-nested-app-authentication/)
- [https://trustedsec.com/blog/full-disclosure-a-third-and-fourth-azure-sign-in-log-bypass-found](https://trustedsec.com/blog/full-disclosure-a-third-and-fourth-azure-sign-in-log-bypass-found)
{{#include ../../../banners/hacktricks-training.md}}