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

This commit is contained in:
Translator
2026-03-31 16:58:16 +00:00
parent 91bb24e6ff
commit 0a593b7607
@@ -1,100 +1,173 @@
# Az - Tokenler ve Public Applications
# Az - Tokens & Public Applications
{{#include ../../../banners/hacktricks-training.md}}
## Temel Bilgiler
## Basic Information
Entra ID, Microsoft'ın bulut tabanlı kimlik ve erişim yönetimi (IAM) platformudur ve Microsoft 365 ile Azure Resource Manager gibi servisler için temel kimlik doğrulama ve yetkilendirme sistemini sağlar. Azure AD, kaynaklara erişimi yönetmek için OAuth 2.0 authorization framework ve OpenID Connect (OIDC) authentication protocol uygular.
Entra ID, Microsoft'ün bulut tabanlı kimlik ve erişim yönetimi (IAM) platformudur ve Microsoft 365 ile Azure Resource Manager gibi hizmetler için temel kimlik doğrulama ve yetkilendirme sistemi olarak hizmet verir. Azure AD, kaynaklara erişimi yönetmek için OAuth 2.0 authorization framework ve OpenID Connect (OIDC) authentication protocolünü uygular.
### OAuth
**OAuth 2.0'deki Önemli Katılımcılar:**
**Key Participants in OAuth 2.0:**
1. **Resource Server (RS):** Resource owner'a ait kaynakları korur.
2. **Resource Owner (RO):** Genellikle korunan kaynakların sahibi olan son kullanıcı.
3. **Client Application (CA):** Resource owner adına kaynaklara erişim talep eden bir uygulama.
4. **Authorization Server (AS):** İstemci uygulamaları doğrulayıp yetkilendirdikten sonra onlara access tokenler verir.
1. **Resource Server (RS):** Kaynak sahibine ait kaynakları korur.
2. **Resource Owner (RO):** Genellikle korunan kaynakların sahibi olan bir son kullanıcıdır.
3. **Client Application (CA):** Kaynak sahibi adına kaynaklara erişim talep eden bir uygulamadır.
4. **Authorization Server (AS):** Client uygulamaları doğrulayıp yetkilendirdikten sonra erişim tokenları verir.
**Scopes ve Onay:**
**Scopes and Consent:**
- **Scopes:** Kaynak sunucusunda tanımlanan ve erişim düzeylerini belirleyen ayrıntılı izinler.
- **Consent:** Resource owner'ın, belirli scope'larla kaynaklara erişim izni vermesi sürecidir.
- **Scopes:** Kaynak sunucuda tanımlanan ve erişim düzeylerini belirleyen ayrıntılı izinlerdir.
- **Consent:** Kaynak sahibinin belirli scopes ile bir client uygulamaya erişim izni verdiği süreçtir.
**Microsoft 365 Entegrasyonu:**
**Microsoft 365 Integration:**
- Microsoft 365, IAM için Azure AD'yi kullanır ve birden fazla "first-party" OAuth uygulamasından oluşur.
- Bu uygulamalar derinlemesine entegre edilmiştir ve genellikle birbirleriyle bağımlı servis ilişkilerine sahiptir.
- Bu uygulamalar derinlemesine entegre edilmiş olup sık sık birbirine bağımlı servis ilişkilerine sahiptir.
- Kullanıcı deneyimini basitleştirmek ve işlevselliği korumak için Microsoft, bu first-party uygulamalara "implied consent" veya "pre-consent" verir.
- **Implied Consent:** Belirli uygulamalara, belirli scope'lara açık bir kullanıcı veya yönetici onayı olmadan **otomatik olarak erişim verilir**.
- Bu ön-onaylı scope'lar tipik olarak hem kullanıcılardan hem de yöneticilerden gizlenir ve standart yönetim arayüzlerinde daha az görünür olurlar.
- **Implied Consent:** Bazı uygulamalara otomatik olarak **belirli scopes'lara kullanıcı veya yönetici onayı olmadan erişim verilir**.
- Bu önceden onaylanmış scopes genellikle kullanıcılar ve yöneticiler tarafından gizlidir; standart yönetim arayüzlerinde daha az görünür olurlar.
**Client Application Türleri:**
**Client Application Types:**
1. **Confidential Clients:**
- Kendi kimlik bilgilerine sahiptir (ör. parolalar veya sertifikalar).
- Kendi kimlik bilgilerine sahiptir (ör. şifreler veya sertifikalar).
- Authorization server'a kendilerini **güvenli şekilde doğrulayabilirler**.
2. **Public Clients:**
- Benzersiz kimlik bilgilerine sahip değildir.
- Authorization server'a güvenli şekilde kimlik doğrulaması yapamazlar.
- **Güvenlik Etkisi:** Bir attacker, token talep ederken bir public client uygulamasını taklit edebilir; authorization server'ın uygulamanın meşruiyetini doğrulamak için bir mekanizması yoktur.
- Authorization server'a güvenli şekilde doğrulanamazlar.
- **Security Implication:** Bir saldırgan, authorization server'ın uygulamanın meşruiyetini doğrulayacak bir mekanizması olmadığından token talep ederken bir public client uygulamayı taklit edebilir.
## Kimlik Doğrulama Tokenleri
### ROPC / Password Grant
OIDC'de kullanılan **üç tür token** vardır:
The OAuth2 **Resource Owner Password Credentials** (**ROPC**) flow uses a direct `POST` to `https://login.microsoftonline.com/<tenant>/oauth2/v2.0/token` with `grant_type=password`, a **username**, **password**, a **client_id**, and the requested **scope**. In Entra ID this is mainly interesting for **public clients** because the attacker can reuse Microsoft first-party client IDs or any other allowed public client without needing a secret.
```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.
- [**Access Tokens**](https://learn.microsoft.com/en-us/azure/active-directory/develop/access-tokens)**:** İstemci bu tokeni resource server'a sunarak **kaynaklara erişir**. Bu token yalnızca belirli bir kullanıcı, istemci ve kaynak kombinasyonu için kullanılabilir ve süresi dolana kadar **iptal edilemez** - varsayılan olarak bu süre 1 saattir.
- **ID Tokens**: İstemci bu **tokeni authorization server'dan** alır. Kullanıcı hakkında temel bilgileri içerir. Belirli bir kullanıcı ve istemci kombinasyonuna **bağlıdır**.
- **Refresh Tokens**: Access token ile birlikte istemciye verilir. Yeni access ve ID tokenleri **almak için** kullanılır. Belirli bir kullanıcı ve istemci kombinasyonuna bağlıdır ve iptal edilebilir. Varsayılan süre, inaktif refresh tokenler için **90 gündür** ve aktif tokenler için **süresizdir** (bir refresh token'dan yeni refresh token almak mümkündür).
- Bir refresh token bir **`aud`**'a, bazı **scopes**'a ve bir **tenant**'a bağlanmalıdır ve yalnızca o aud, scope'lar (ve daha fazlası değil) ve tenant için access tokenler üretebilmelidir. Ancak **FOCI applications tokens** ile bu durum geçerli değildir.
- Bir refresh token şifrelenmiştir ve yalnızca Microsoft bunu deşifre edebilir.
- Yeni bir refresh token almak, önceki refresh tokeni iptal etmez.
### Entra ID Oturum Açma Günlüğü Atlatma Sınıfları
Bazı tarihsel Entra ID hataları, beklenen **Entra ID sign-in log** girişini oluşturmadan **password validation** veya hatta **full token issuance** yapılmasına izin veriyordu. Bu vakalar düzeltildi, ancak bu teknikler auth pipeline'larının nasıl başarısız olabileceğini anlamak için hâlâ faydalıdır; bu tür başarısızlıklar **downstream token use visible** iken **upstream sign-in telemetry is absent** bırakabilir.
#### 1. Gizli password validation için foreign-tenant endpoint
İstek bir **different tenant GUID**'ine ait token endpoint'ine gönderilirse, Entra, kullanıcının o foreign tenant'ta bulunmaması nedeniyle akış başarısız olana kadar gönderilen parolanın sağlanan kullanıcı adı için doğru olup olmadığını yine de doğrulayabilir. Tarihsel olarak bu şunlara izin verdi:
- **Password spraying / credential validation** without a corresponding sign-in log in the victim tenant
- Parola adımının başarılı olup olmadığını ortaya çıkaran bir yanıt farkı
- Token verilmez, ancak normal bir başarısız oturum açmadan daha az telemetry
#### 2. Parola sonrası hatayı zorlamak
Kimlik doğrulama doğrulamasından **after** kullanılan bir parametre geçersizse, örneğin geçersiz bir `client_id`, parola zaten doğru olmasına rağmen genel işlem başarısız olabilir. Tarihsel olarak bu, parola tahmininin başarılı olduğunu gizlerken **failed** bir oturum açma görünümü üretti.
Hatırlanması gereken desen şudur:
- **Password check succeeds**
- A later validation step fails
- The log represents the final transaction state but not the successful password-validation step
#### 3. Oversized-but-valid değerlerle logging hatasını tetiklemek
En tehlikeli sınıf, isteğin sözdizimsel olarak geçerli kalıp kimlik doğrulamanın başarılı olduğu, **tokens are returned** fakat bazı **logged field**'ların logging pipeline'ını bozacak kadar büyük olması durumudur. Rapor edilen örnekler şunları içeriyordu:
- Binlerce kez geçerli scopes'ları tekrarlamak, örneğin `openid openid openid ...`
- Aşırı uzun ama yine de kabul edilen bir **User-Agent** header sağlamak
Bu, aşağıdaki genel sorun sınıfını işaret eder:
1. Entra kimlik bilgilerini ve istek sözdizimini doğrular
2. Token başarıyla verilir
3. Logging, kullanıcı kontrollü ham bir alanı kalıcı hale getirmeye çalışır
4. Logging yazma işlemi uzunluk veya şema varsayımları nedeniyle başarısız olur
5. Kullanıcı, karşılık gelen bir sign-in kaydı olmadan geçerli bir token elde eder
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)"
```
#### Tehdit avlama / savunma notu
Her geçerli token kullanımının mutlaka eşleşen bir Entra sign-in event olacağını varsaymayın. Şüpheli Graph etkinliğini incelerken korele edin:
- **Non-interactive sign-in logs**
- **Graph Activity Logs**
- **IP address**, **user/object ID**, **session/correlation identifiers**, ve **zaman pencereleri**
Pratik bir doğrulama yöntemi, şüphelenilen görünmez bir başarıyı iki normal başarısız oturum açma arasına yerleştirmek ve ardından beklenen dizinin `Failed -> Successful -> Failed` ingestion gecikmesinden sonra ortadaki olayın eksik olup olmadığını doğrulamaktır. Eğer downstream Graph etkinliği varsa fakat sign-in log yoksa, bunu potansiyel bir **sign-in logging gap** veya **token replay** durumu olarak değerlendirin.
## Authentication Tokens
OIDC'de kullanılan üç tür token vardır:
- [**Access Tokens**](https://learn.microsoft.com/en-us/azure/active-directory/develop/access-tokens)**:** İstemci, bu token'ı resource server'a sunarak **access resources** yapar. Bu token yalnızca belirli bir kullanıcı, istemci ve kaynak kombinasyonu için kullanılabilir ve süresi dolana kadar **cannot be revoked** — varsayılan olarak 1 saattir.
- **ID Tokens**: İstemci bu token'ı authorization server'dan alır. Kullanıcı hakkında temel bilgileri içerir. **Bound to a specific combination of user and client**.
- **Refresh Tokens**: Access token ile birlikte istemciye verilir. Yeni access ve ID token'ları **get new access and ID tokens** için kullanılır. Belirli bir kullanıcı ve istemci kombinasyonuna bağlıdır ve revoke edilebilir. Varsayılan süre, aktif olmayan refresh token'lar için **90 days**, aktif token'lar için ise **no expiry** (bir refresh token'dan yeni refresh token almak mümkündür).
- Bir refresh token, bir **`aud`**'a, bazı **scopes**'a ve bir **tenant**'a bağlı olmalı ve yalnızca o aud, scopes (ve daha fazlası değil) ve tenant için access token üretmelidir. Ancak bu, **FOCI applications tokens** için geçerli değildir.
- Bir refresh token şifrelenmiştir ve yalnızca Microsoft tarafından decrypt edilebilir.
- Yeni bir refresh token almak, önceki refresh token'ı revoke etmez.
> [!WARNING]
> conditional access ile ilgili bilgiler **JWT** içinde **saklanır**. Yani, eğer tokeni izin verilen bir IP adresinden isterseniz, o **IP** token içinde **saklanır** ve daha sonra o tokeni izin verilmeyen bir IP'den **kaynaklara erişmek için** kullanabilirsiniz.
> **conditional access** bilgileri **JWT** içinde **stored** edilir. Yani, eğer **token'ı allowed IP address'ten request ederseniz**, o **IP** token içinde **stored** edilecek ve ardından bu token'ı **non-allowed IP** üzerinden kaynaklara erişmek için kullanabilirsiniz.
### Access Tokens "aud"
"aud" alanında belirtilen değer, login işlemi için kullanılan **resource server**dır (uygulama).
"aud" alanında belirtilen değer, login işlemini gerçekleştirmek için kullanılan **resource server** (uygulama)'dır.
`az account get-access-token --resource-type [...]` komutu aşağıdaki türleri destekler ve her biri sonuç access token içinde belirli bir "aud" ekler:
`az account get-access-token --resource-type [...]` komutu aşağıdaki türleri destekler ve her biri ortaya çıkan access token içinde spesifik bir "aud" ekleyecektir:
> [!CAUTION]
> Not: Aşağıdakiler `az account get-access-token` tarafından desteklenen API'lerin yalnızca bir kısmıdır; daha fazlası mevcuttur.
> Aşağıdakilerin sadece `az account get-access-token` tarafından desteklenen API'ler olduğunu, daha fazlasının da mevcut olduğunu unutmayın.
<details>
<summary>aud examples</summary>
<summary>aud örnekleri</summary>
- **aad-graph (Azure Active Directory Graph API)**: Eski Azure AD Graph API'ye (deprecated) erişmek için kullanılır; bu API, uygulamaların Azure Active Directory (Azure AD) içindeki dizin verilerini okumasına ve yazmasına olanak tanır.
- **aad-graph (Azure Active Directory Graph API)**: Legacy Azure AD Graph API'ye (deprecated) erişmek için kullanılır; uygulamaların Azure Active Directory (Azure AD) içindeki dizin verilerini okumasına ve yazmasına olanak tanır.
- `https://graph.windows.net/`
* **arm (Azure Resource Manager)**: Azure Resource Manager API aracılığıyla Azure kaynaklarını yönetmek için kullanılır. Bu, sanal makineler, depolama hesapları ve daha fazlası gibi kaynakların oluşturulması, güncellenmesi ve silinmesi gibi işlemleri içerir.
* **arm (Azure Resource Manager)**: Azure Resource Manager API aracılığıyla Azure kaynaklarını yönetmek için kullanılır. Bu, sanal makineler, storage hesapları ve benzeri kaynakları oluşturma, güncelleme ve silme işlemlerini içerir.
- `https://management.core.windows.net/ or https://management.azure.com/`
- **batch (Azure Batch Services)**: Buluttaki büyük ölçekli paralel ve yüksek performanslı hesaplama uygulamalarını verimli bir şekilde destekleyen Azure Batch'e erişmek için kullanılır.
- **batch (Azure Batch Services)**: Cloud'da büyük ölçekli paralel ve yüksek performanslı hesaplama uygulamalarını verimli bir şekilde çalıştırmaya olanak sağlayan Azure Batch'e erişmek için kullanılır.
- `https://batch.core.windows.net/`
* **data-lake (Azure Data Lake Storage)**: Ölçeklenebilir bir veri depolama ve analiz hizmeti olan Azure Data Lake Storage Gen1 ile etkileşim için kullanılır.
* **data-lake (Azure Data Lake Storage)**: Ölçeklenebilir veri depolama ve analitik hizmeti olan Azure Data Lake Storage Gen1 ile etkileşim için kullanılır.
- `https://datalake.azure.net/`
- **media (Azure Media Services)**: Video ve ses içeriği için bulut tabanlı medya işleme ve dağıtım servisleri sağlayan Azure Media Services'a erişmek için kullanılır.
- **media (Azure Media Services)**: Video ve ses içeriği için bulut tabanlı medya işleme ve dağıtım hizmetleri sunan Azure Media Services'a erişmek için kullanılır.
- `https://rest.media.azure.net`
* **ms-graph (Microsoft Graph API)**: Microsoft 365 servisleri verileri için birleşik uç nokta olan Microsoft Graph API'ye erişmek için kullanılır. Azure AD, Office 365, Enterprise Mobility ve Security servisleri gibi servislerden veri ve içgörüler almanıza olanak tanır.
* **ms-graph (Microsoft Graph API)**: Microsoft 365 servisleri verileri için birleşik uç nokta olan Microsoft Graph API'ye erişmek için kullanılır. Azure AD, Office 365, Enterprise Mobility ve Security servisleri gibi hizmetlerden veri ve içgörü elde etmeyi sağlar.
- `https://graph.microsoft.com`
- **oss-rdbms (Azure Open Source Relational Databases)**: MySQL, PostgreSQL ve MariaDB gibi açık kaynaklı ilişkisel veritabanı motorları için Azure Database servislerine erişmek için kullanılır.
- **oss-rdbms (Azure Open Source Relational Databases)**: MySQL, PostgreSQL ve MariaDB gibi açık kaynaklı ilişkisel veritabanı motorları için Azure Database hizmetlerine erişmekte kullanılır.
- `https://ossrdbms-aad.database.windows.net`
</details>
### Access Tokens Scopes "scp"
Bir access token'ın kapsamı, access token JWT'si içindeki scp anahtarının içinde saklanır. Bu scope'lar access token'ın neye erişimi olduğunu tanımlar.
Bir access token'ın scope'u, access token JWT içindeki scp anahtarında saklanır. Bu scope'lar, access token'ın neye erişimi olduğunu tanımlar.
Eğer bir JWT belirli bir API ile iletişim kurmasına izin veriliyorsa fakat istenen lemi gerçekleştirmek için gerekli scope'a **sahip değilse**, o JWT ile lemi **gerçekleştiremez**.
Eğer bir JWT belirli bir API ile iletişim kurmaya izinli ise fakat istenen eylemi gerçekleştirmek için gerekli scope'a sahip değilse, o JWT ile eylemi gerçekleştiremeyecektir.
### Get refresh & access token example
### Get refresh & access token örneği
```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)
```
### Diğer access token alanları
### Diğer access token fields
- **appid**: token oluşturmak için kullanılan Application ID
- **appidacr**: The Application Authentication Context Class Reference, istemcinin nasıl kimlik doğrulandığını gösterir; public client için değer 0, client secret kullanıldıysa değer 1'dir
- **acr**: The Authentication Context Class Reference iddiası, son-kullanıcı kimlik doğrulaması ISO/IEC 29115 gereksinimlerini karşılamadığında "0" olur.
- **amr**: The Authentication method, token'in nasıl doğrulandığını belirtir. pwd değeri şifre kullanıldığını gösterir.
- **groups**: principal'ın üye olduğu grupları gösterir.
- **iss**: iss, token'i oluşturan security token service (STS)'yi tanımlar. e.g. https://sts.windows.net/fdd066e1-ee37-49bc-b08f-d0e152119b04/ (the uuid is the tenant ID)
- **oid**: principal'ın object ID'si
- **appid**: Token'ı oluşturmak için kullanılan Application ID
- **appidacr**: The Application Authentication Context Class Reference, istemcinin nasıl doğrulandığını gösterir; public client için değer 0'dır, client secret kullanıldıysa değer 1'dir
- **acr**: Authentication Context Class Reference claim'i, son kullanıcı doğrulaması ISO/IEC 29115 gereksinimlerini karşılamadığında "0" olur.
- **amr**: Authentication method, token'ın nasıl doğrulandığını gösterir. "pwd" değeri parolanın kullanıldığını gösterir.
- **groups**: Principal'in üye olduğu grupları gösterir.
- **iss**: iss, token'ı oluşturan security token service (STS)'yi tanımlar. e.g. https://sts.windows.net/fdd066e1-ee37-49bc-b08f-d0e152119b04/ (uuid tenant ID'dir)
- **oid**: Principal'in object ID'si
- **tid**: Tenant ID
- **iat, nbf, exp**: Veriliş zamanı (ne zaman verildi), Not before (bu zamandan önce kullanılamaz, genelde iat ile aynı değer), Son kullanma zamanı.
- **iat, nbf, exp**: Veriliş zamanı (verildiği an), Kullanılabilirlik başlangıcı (bu zamandan önce kullanılamaz, genellikle iat ile aynı değer), Son kullanma zamanı.
## FOCI Token'larda Ayrıcalık Yükseltmesi
## FOCI Tokens Privilege Escalation
Daha önce refresh token'ların oluşturuldukları **scopes**, **application** ve **tenant** ile bağlı olması gerektiği belirtildi. Bu sınırların herhangi biri kırılırsa, kullanıcının erişimi olan diğer kaynaklar ve tenantlar için ve orijinal amaçlanandan daha fazla scope içeren access token'lar üretilebileceği için ayrıcalık yükseltmesi mümkün olur.
Daha önce refresh tokens'in oluşturulduğu **scopes**, **application** ve ait olduğu **tenant** ile bağlı olması gerektiği belirtilmişti. Bu sınırların herhangi biri kırılırsa, kullanıcının erişimi olan diğer kaynaklar ve tenant'lar için ve orijinal amaçlanandan daha fazla scope ile access tokens üretilebileceği için ayrıcalık yükseltme mümkün olur.
Ayrıca, [Microsoft identity platform](https://learn.microsoft.com/en-us/entra/identity-platform/) içindeki tüm refresh token'larda **bu mümkündür** (Microsoft Entra accounts, Microsoft personal accounts, and social accounts like Facebook and Google) çünkü [**docs**](https://learn.microsoft.com/en-us/entra/identity-platform/refresh-tokens) şöyle diyor: "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."
Ayrıca, [Microsoft identity platform](https://learn.microsoft.com/en-us/entra/identity-platform/) içindeki tüm refresh tokens ile bunun mümkün olduğunu unutmayın (Microsoft Entra accounts, Microsoft personal accounts ve Facebook ve Google gibi social accounts), çünkü [**docs**](https://learn.microsoft.com/en-us/entra/identity-platform/refresh-tokens) şöyle diyor: "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."
Ayrıca, FOCI uygulamalarının public uygulamalar olduğunu unutmayın; bu yüzden sunucuya kimlik doğrulamak için **secret gerekmez**.
Ayrıca FOCI applications public applications olduğundan, sunucuya kimlik doğrulamak için **secret gerekmez**.
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).
Bildirilen bilinen FOCI clients, [**original research**](https://github.com/secureworks/family-of-client-ids-research/tree/main) içinde raporlanmış olup [**found here**](https://github.com/secureworks/family-of-client-ids-research/blob/main/known-foci-clients.csv) bulunabilir.
### Farklı scope elde et
### Get different scope
Önceki örnek kodu takiben, bu kodda farklı bir scope için yeni bir token talep ediliyor:
Önceki örnek koda devam ederek, bu kodda farklı bir scope için yeni bir token talep ediliyor:
```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)
```
### Farklı client ve scopes edinin
### Farklı client ve scope'ları alın
```python
# Code from https://github.com/secureworks/family-of-client-ids-research
microsoft_office_client = msal.PublicClientApplication("d3590ed6-52b3-4102-aeff-aad2292ab01c")
@@ -204,57 +277,57 @@ pprint(microsoft_office_bearer_tokens_for_graph_api)
```
## NAA / BroCI (Nested App Authentication / Broker Client Injection)
A BroCI refresh token, mevcut bir refresh token'ın ekstra broker parametreleriyle başka bir güvenilen first-party app adına token istemek için kullanıldığı bir brokered token exchange pattern'idir.
Bir BroCI refresh token, mevcut bir refresh token'ın ek broker parametreleriyle kullanılarak başka bir güvenilir first-party uygulama adına token istemek için kullanılan broker'lanmış bir token değişim modelidir.
These refresh tokens must be minted in that broker context (a regular refresh token usually cannot be used as a BroCI refresh token).
Bu refresh token'lar o broker bağlamında düzenlenmiş olmalıdır (normal bir refresh token genellikle bir BroCI refresh token olarak kullanılamaz).
### Amaç ve hedef
### Goal and purpose
BroCI'nin amacı, broker-capable bir app zincirinden geçerli bir kullanıcı oturumunu yeniden kullanmak ve başka bir güvenilen app/resource çiftine token talep etmektir. Böylece orijinal token'dan "yetki yükseltme" (escalate privileges) yapılmasına olanak verir.
BroCI'nin amacı, broker yeteneğine sahip bir uygulama zincirinden geçerli bir kullanıcı oturumunu yeniden kullanmak ve başka bir güvenilir uygulama/kaynak çifti için token istemektir. Bu nedenle, orijinal token'dan "privilege escalation" yapılmasına olanak tanır.
Saldırgan bakış açısından, bunun önemi:
Ofansif açıdan bunun önemi şunlardır:
- Standart refresh exchange'leri ile erişilemeyen, önceden onaylanmış first-party app yollarını açabilir.
- Geniş delegated permissions sahibi app kimlikleri altında yüksek değerli API'ler (ör. Microsoft Graph) için access token'lar döndürebilir.
- Klasik FOCI client switching'in ötesinde post-authentication token pivoting fırsatlarını genişletir.
- Standart refresh değişimleriyle erişilemeyen, önceden onaylanmış first-party uygulama yollarını açabilir.
- Geniş delegated izinlere sahip uygulama kimlikleri altında yüksek değerli API'ler (örneğin Microsoft Graph) için access token'lar döndürebilir.
- Klasik FOCI client değiştirme ötesinde post-authentication token pivoting olanaklarını genişletir.
NAA/BroCI refresh token'da değişen şey görünen token formatı değil, Microsoft'un brokered refresh işlemleri sırasında doğruladığı **issuance context** ve broker ile ilgili metadata'dır.
Bir NAA/BroCI refresh token'da değişen şey görünür token formatı değil, Microsoft'un brokered refresh işlemleri sırasında doğruladığı issuance context ve broker ile ilgili metadata'dır.
NAA/BroCI token exchanges, normal bir OAuth refresh exchange ile **aynı değildir**.
NAA/BroCI token değişimleri normal bir OAuth refresh exchange ile aynı değildir.
- Normal bir refresh token (örneğin device code flow ile elde edilen) genellikle standart `grant_type=refresh_token` işlemleri için geçerlidir.
- Bir BroCI isteği ek broker bağlamı içerir (`brk_client_id`, broker `redirect_uri`, and `origin`).
- Microsoft, sunulan refresh token'ın eşleşen bir brokered bağlamda oluşturulup oluşturulmadığını doğrular.
- Bu nedenle birçok "normal" refresh token BroCI isteklerinde `AADSTS900054` ("Specified Broker Client ID does not match ID in provided grant") gibi hatalarla başarısız olur.
- Genel olarak normal bir refresh token'ı kod içinde BroCI-geçerli bir token'a "dönüştüremezsiniz".
- Uyumlubir brokered flow tarafından zaten verilmiş bir refresh token'a ihtiyacınız vardır.
- Bir BroCI isteği ek broker bağlamı içerir (`brk_client_id`, broker `redirect_uri`, ve `origin`).
- Microsoft, sunulan refresh token'ın eşleşen bir brokered bağlamda düzenlenip düzenlenmediğini doğrular.
- Bu yüzden birçok "normal" refresh token, `AADSTS900054` ("Specified Broker Client ID does not match ID in provided grant") gibi hatalarla BroCI isteklerinde başarısız olur.
- Genel olarak normal bir refresh token'ı kodla BroCI-uygun hale "dönüştüremezsiniz".
- Uyumlubrokered bir akış tarafından zaten düzenlenmiş bir refresh token'a ihtiyacınız vardır.
Check the web **<https://entrascopes.com/>** to find BroCI configured apps an the trust relationships they have.
Web sitesine bakın **<https://entrascopes.com/>** BroCI yapılandırılmış uygulamaları ve bunların sahip olduğu güven ilişkilerini bulmak için.
### Zihinsel model
### Mental model
BroCI'yi şu şekilde düşünün:
`user session -> brokered refresh token issuance -> brokered refresh call (brk_client_id + redirect_uri + origin) -> access token for target trusted app/resource`
Eğer broker zincirinin herhangi bir bölümü eşleşmezse, işlem başarısız olur.
Broker zincirinin herhangi bir parçası eşleşmezse, değişim başarısız olur.
### BroCI-geçerli refresh token nerede bulunur
### Where to find a BroCI-valid refresh token
Pratik bir yol, tarayıcı portal trafiğini toplamak:
Pratik bir yol, tarayıcı portal trafiğini toplamaktır:
1. `https://entra.microsoft.com` (veya Azure portal) adresine giriş yapın.
2. DevTools'u açın -> Network.
3. Şunu filtreleyin:
- `oauth2/v2.0/token`
- `management.core.windows.net`
4. Brokered token yanıtını tespit edin ve `refresh_token`'ı kopyalayın.
5. Hedef uygulamalar için token talep ederken (ör. ADIbizaUX / Microsoft_Azure_PIMCommon senaryoları) eşleşen BroCI parametreleri (`brk_client_id`, `redirect_uri`, `origin`) ile o refresh token'ı kullanın.
2. DevTools -> Network'i açın.
3. Şunlar için filtreleyin:
- `oauth2/v2.0/token`
- `management.core.windows.net`
4. Brokered token yanıtını belirleyin ve `refresh_token`'ı kopyalayın.
5. Hedef uygulamalar için token isterken (örneğin ADIbizaUX / Microsoft_Azure_PIMCommon senaryolarında) bu refresh token'ı eşleşen BroCI parametreleriyle (`brk_client_id`, `redirect_uri`, `origin`) kullanın.
### Yaygın hatalar
### Common errors
- `AADSTS900054`: Refresh token bağlamı sağlanan broker üçlüsü (`brk_client_id` / `redirect_uri` / `origin`) ile eşleşmiyor veya token brokered portal flow'tan gelmiyor.
- `AADSTS7000218`: Seçilen client flow gizli bir credential (`client_secret`/assertion) bekliyor; genellikle device code'ı non-public client ile denerken görülür.
- `AADSTS900054`: The refresh token context does not match the supplied broker tuple (`brk_client_id` / `redirect_uri` / `origin`) or the token is not from a brokered portal flow.
- `AADSTS7000218`: The selected client flow expects a confidential credential (`client_secret`/assertion), often seen when trying device code with a non-public client.
<details>
<summary>Python BroCI refresh helper (broci_auth.py)</summary>
@@ -530,26 +603,26 @@ raise SystemExit(main())
```
</details>
## Token'lar nerede bulunur
## Token'ların nerede bulunacağı
Bir saldırgan açısından, örneğin hedefin PC'si ele geçirildiğinde, access ve refresh token'ların nerede bulunabileceğini bilmek çok ilginçtir:
Bir saldırgan bakış açısından, örneğin hedefin PC'si ele geçirildiğinde, nerede access ve refresh token'ların bulunabileceğini bilmek çok ilginçtir:
- Inside **`<HOME>/.Azure`**
- İçinde **`<HOME>/.Azure`**
- **`azureProfile.json`** geçmişte oturum açmış kullanıcılar hakkında bilgi içerir
- **`clouds.config contains`** abonelikler hakkında bilgi içerir
- **`service_principal_entries.json`** uygulama kimlik bilgilerini içerir (tenant id, client'lar ve secret). Sadece Linux & macOS
- **`service_principal_entries.json`** uygulama kimlik bilgilerini içerir (tenant id, clients and secret). Sadece Linux & macOS
- **`msal_token_cache.json`** access tokens ve refresh tokens içerir. Sadece Linux & macOS
- **`service_principal_entries.bin`** ve msal_token_cache.bin Windows'ta kullanılır ve DPAPI ile şifrelenmiştir
- **`msal_http_cache.bin`** HTTP isteklerinin önbelleğidir
- Load it: `with open("msal_http_cache.bin", 'rb') as f: pickle.load(f)`
- **`AzureRmContext.json`** Az PowerShell ile yapılan önceki oturum açma bilgilerini içerir (ancak kimlik bilgileri yok)
- **`C:\Users\<username>\AppData\Local\Microsoft\IdentityCache\*`** içinde kullanıcının DPAPI'si ile şifrelenmiş access tokens, ID tokens ve hesap bilgilerini içeren birkaç `.bin` dosyası bulunur.
- Daha fazla **access tokens** bulmak mümkündür: **`C:\Users\<username>\AppData\Local\Microsoft\TokenBroken\Cache\`** içindeki `.tbres` dosyaları, DPAPI ile şifrelenmiş base64 içinde access tokens içerir.
- Linux ve macOS'ta, Az PowerShell (kullanıldıysa) çalıştırılarak **access tokens, refresh tokens ve id tokens** alınabilir: `pwsh -Command "Save-AzContext -Path /tmp/az-context.json"`
- **`msal_http_cache.bin`** HTTP isteklerinin bir cache'idir
- Yükleyin: `with open("msal_http_cache.bin", 'rb') as f: pickle.load(f)`
- **`AzureRmContext.json`** Az PowerShell kullanılarak yapılan önceki oturum açmalar hakkında bilgi içerir (ancak kimlik bilgileri içermez)
- İçinde **`C:\Users\<username>\AppData\Local\Microsoft\IdentityCache\*`** birden fazla `.bin` dosyası bulunur; bu dosyalar **access tokens**, ID tokens ve hesap bilgilerini kullanıcının DPAPI'si ile şifrelenmiş şekilde içerir.
- Daha fazla **access tokens**'ı, DPAPI ile şifrelenmiş base64 içeren `.tbres` dosyalarında **`C:\Users\<username>\AppData\Local\Microsoft\TokenBroken\Cache\`** içinde bulmak mümkündür.
- Linux ve macOS'ta, (kullanıldıysa) Az PowerShell'den `pwsh -Command "Save-AzContext -Path /tmp/az-context.json"` çalıştırarak **access tokens, refresh tokens ve id tokens** elde edebilirsiniz
- Windows'ta bu yalnızca id tokens üretir.
- Linux ve macOS'ta Az PowerShell'in kullanılıp kullanılmadığını görmek için `$HOME/.local/share/.IdentityService/` var olup olmadığı kontrol edilebilir (içerideki dosyalar boş ve işe yaramaz olsa da)
- Eğer kullanıcı tarayıcıyla Azure'a logged inside ise, bu [**post**](https://www.infosecnoodle.com/p/obtaining-microsoft-entra-refresh?r=357m16&utm_campaign=post&utm_medium=web) göre kimlik doğrulama akışı localhost'a redirect ile başlatılıp, tarayıcı otomatik olarak otorizasyonu onaylamaya zorlanabilir ve refresh token alınabilir. Dikkat: localhost'a redirect'e izin veren sadece birkaç FOCI uygulaması vardır (ör. az cli veya powershell modülü), bu yüzden bu uygulamalara izin verilmiş olmalıdır.
- Blogda açıklanan diğer bir seçenek, herhangi bir uygulamayı kullanabilen ve son auth sayfasının başlığından OAuth kodunu alıp bununla refresh token edinecek aracı [**BOF-entra-authcode-flow**](https://github.com/sudonoodle/BOF-entra-authcode-flow) kullanmaktır; bu araç final auth sayfasının başlığından refresh token almak için redirect URI `https://login.microsoftonline.com/common/oauth2/nativeclient` kullanır.
- Linux ve macOS'ta Az PowerShell'in kullanılıp kullanılmadığını görmek için `$HOME/.local/share/.IdentityService/` dizininin varlığını kontrol etmek mümkündür (içindeki dosyalar boş ve işe yaramaz olsa da)
- Kullanıcı tarayıcı ile Azure'a giriş yapmışsa, bu [**post**](https://www.infosecnoodle.com/p/obtaining-microsoft-entra-refresh?r=357m16&utm_campaign=post&utm_medium=web)'a göre kimlik doğrulama akışını **redirect to localhost** ile başlatmak, tarayıcının oturumu otomatik olarak yetkilendirmesini sağlamak ve refresh token'ı almak mümkündür. Dikkat: localhost'a redirect'e izin veren yalnızca birkaç FOCI uygulaması vardır (ör. az cli veya powershell modülü), bu yüzden bu uygulamalara izin verilmiş olmalıdır.
- Blogda açıklanan bir diğer seçenek, herhangi bir uygulamayı kullanabilecek [**BOF-entra-authcode-flow**](https://github.com/sudonoodle/BOF-entra-authcode-flow) aracını kullanmaktır; çünkü bu araç redirect URI `https://login.microsoftonline.com/common/oauth2/nativeclient` kullanarak son auth sayfasının başlığından OAuth kodunu alıp ardından refresh token'ı elde edecektir.
## Referanslar
@@ -557,5 +630,6 @@ Bir saldırgan açısından, örneğin hedefin PC'si ele geçirildiğinde, acces
- [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}}