diff --git a/src/pentesting-cloud/azure-security/az-basic-information/az-tokens-and-public-applications.md b/src/pentesting-cloud/azure-security/az-basic-information/az-tokens-and-public-applications.md index ccf9a4090..caf6e068c 100644 --- a/src/pentesting-cloud/azure-security/az-basic-information/az-tokens-and-public-applications.md +++ b/src/pentesting-cloud/azure-security/az-basic-information/az-tokens-and-public-applications.md @@ -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//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//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š.
-aud examples +primeri aud -- **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`
### 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 **** 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 **`/.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\\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\\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\\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\\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}}