# Az - CosmosDB

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

## Azure CosmosDB

**Azure Cosmos DB** è un **database NoSQL, relazionale e vettoriale completamente gestito** che offre tempi di risposta in millisecondi a cifra singola, scalabilità automatica e disponibilità supportata da SLA con sicurezza di livello enterprise. Consente uno sviluppo più rapido delle app attraverso la distribuzione di dati multi-regione "chiavi in mano", API open-source, SDK per linguaggi popolari e funzionalità di database AI come il supporto vettoriale integrato e l'integrazione fluida con Azure AI.

Azure Cosmos DB fornisce più API per database per modellare dati del mondo reale utilizzando modelli di dati documentali, relazionali, chiave-valore, grafici e a colonne, essendo queste API NoSQL, MongoDB, PostgreSQL, Cassandra, Gremlin e Table.

Un aspetto chiave di CosmosDB è l'Azure Cosmos Account. **Azure Cosmos Account** funge da punto di accesso ai database. L'account determina impostazioni chiave come distribuzione globale, livelli di coerenza e l'API specifica da utilizzare, come NoSQL. Attraverso l'account, puoi configurare la replicazione globale per garantire che i dati siano disponibili in più regioni per un accesso a bassa latenza. Inoltre, puoi scegliere un livello di coerenza che bilancia tra prestazioni e accuratezza dei dati, con opzioni che vanno da Strong a Eventual consistency.

Azure Cosmos DB supporta **identità assegnate dall'utente** e **identità gestite assegnate dal sistema** che vengono create automaticamente e collegate al ciclo di vita della risorsa. Tuttavia, Cosmos DB non ha un meccanismo integrato per interrogare direttamente fonti di dati esterne come Azure Blob Storage. A differenza delle funzionalità delle tabelle esterne di SQL Server, Cosmos DB richiede che i dati vengano ingeriti nei suoi contenitori utilizzando strumenti esterni come Azure Data Factory, il Data Migration Tool o script personalizzati prima di poter essere interrogati con le sue capacità di query native.

### NoSQL
L'API NoSQL di Azure Cosmos DB è un'API basata su documenti che utilizza JSON come formato di dati. Fornisce una sintassi di query simile a SQL per interrogare oggetti JSON, rendendola adatta per lavorare con dati strutturati e semi-strutturati. L'endpoint del servizio è:
```bash
https://<Account-Name>.documents.azure.com:443/
```
#### Database
All'interno di un account, puoi creare uno o più database, che fungono da raggruppamenti logici di contenitori. Un database agisce come un confine per la gestione delle risorse e dei permessi utente. I database possono consentire a più contenitori di utilizzare un pool condiviso di capacità di prestazione o dare a ciascun contenitore la propria potenza dedicata.

#### Contenitori
L'unità fondamentale di archiviazione dei dati è il contenitore, che contiene documenti JSON ed è automaticamente indicizzato per query efficienti. I contenitori sono elastici e scalabili e distribuiti su partizioni, determinate da una chiave di partizione definita dall'utente. La chiave di partizione è fondamentale per garantire prestazioni ottimali e una distribuzione uniforme dei dati. Ad esempio, un contenitore potrebbe memorizzare dati sui clienti, con "customerId" come chiave di partizione.

#### Caratteristiche principali
- **Distribuzione globale**: Abilita o disabilita la Geo-Redundancy per la replica tra regioni e Multi-region Writes per una disponibilità migliorata.
- **Networking & Sicurezza**: tra endpoint pubblici (tutti/seleziona reti) o privati per la connettività. Connessioni sicure con crittografia TLS 1.2. Supporta CORS (Cross-Origin Resource Sharing) per un accesso controllato alle risorse. Microsoft Defender for Cloud può essere abilitato. Per stabilire la connessione puoi utilizzare le chiavi.
- **Backup & Ripristino**: da politiche di backup Periodiche, Continue (7 giorni) o Continue (30 giorni) con intervalli e retention configurabili.
- **Crittografia dei dati**: Chiavi gestite dal servizio predefinite o chiavi gestite dal cliente (CMK) per la crittografia (la selezione della CMK è irreversibile).

#### Enumerazione

{{#tabs }}
{{#tab name="az cli" }}
```bash
# CosmoDB Account
## List Azure Cosmos DB database accounts.
az cosmosdb list --resource-group <ResourceGroupName>
az cosmosdb show --resource-group <ResourceGroupName> --name <AccountName>

## Lists the virtual network accounts associated with a Cosmos DB account
az cosmosdb network-rule list --resource-group <ResourceGroupName> --name <AccountName>
## List the access keys or connection strings for a Azure Cosmos DB
az cosmosdb keys list --name <AccountName> --resource-group <ResourceGroupName>
## List all the database accounts that can be restored.
az cosmosdb restorable-database-account list --account-name <AccountName>
## Show the identities for a Azure Cosmos DB database account.
az cosmosdb identity show --resource-group <ResourceGroupName> --name <AccountName>


# CosmoDB (NoSQL)
## List the NoSQL databases under an Azure Cosmos DB account.
az cosmosdb sql database list --resource-group <ResourceGroupName> --account-name <AccountName>
## List the NoSQL containers under an Azure Cosmos DB NoSQL database.
az cosmosdb sql container list --account-name <AccountName> --database-name <DatabaseName> --resource-group <ResourceGroupName>

## List all NoSQL role assignments under an Azure Cosmos DB
az cosmosdb sql role assignment list --resource-group <ResourceGroupName> --account-name <AccountName>
## List all NoSQL role definitions under an Azure Cosmos DB
az cosmosdb sql role definition list --resource-group <ResourceGroupName> --account-name <AccountName>

## List the NoSQL stored procedures under an Azure Cosmos DB
az cosmosdb sql stored-procedure list --account-name <AccountName> --container-name <ContainerName> --database-name <DatabaseName> --resource-group <ResourceGroupName>
## List the NoSQL triggers under an Azure Cosmos DB NoSQL container.
az cosmosdb sql trigger list --account-name <AccountName> --container-name <ContainerName> --database-name <DatabaseName> --resource-group <ResourceGroupName>
## List the NoSQL user defined functions under an Azure Cosmos DB NoSQL container
az cosmosdb sql user-defined-function list --account-name <AccountName> --container-name <ContainerName> --database-name <DatabaseName> --resource-group <ResourceGroupName>


## MongoDB (vCore)
# Install az cli extension
az extension add --name cosmosdb-preview
# List all MongoDB databases in a specified Azure Cosmos DB account
az cosmosdb mongocluster list
az cosmosdb mongocluster show --cluster-name <name> --resource-group <ResourceGroupName>
# Get firewall rules
az cosmosdb mongocluster firewall rule list --cluster-name <name> --resource-group <ResourceGroupName>
# Connect to in
brew install mongosh
mongosh "mongodb://<username>:<password>@<account-name>.mongo.cosmos.azure.com:10255/?ssl=true&replicaSet=globaldb&retryWrites=false" --username <username> --password <password>

```
{{#endtab }}

{{#tab name="Az Powershell" }}
```bash
Get-Command -Module Az.CosmosD

# List all Cosmos DB accounts in a specified resource group.
Get-AzCosmosDBAccount -ResourceGroupName "<ResourceGroupName>"

# Get the access keys for a specific Cosmos DB account.
Get-AzCosmosDBAccountKey -ResourceGroupName "<ResourceGroupName>" -Name "<AccountName>"

# Retrieve the client encryption keys for a specific Cosmos DB account.
Get-AzCosmosDbClientEncryptionKey -ResourceGroupName "<ResourceGroupName>" -AccountName "<AccountName>" -DatabaseName "<DatabaseName>"

# List all SQL containers in a specific Cosmos DB SQL database.
Get-AzCosmosDBSqlContainer -ResourceGroupName "<ResourceGroupName>" -AccountName "<AccountName>" -DatabaseName "<DatabaseName>"

# Get backup information for a specific Cosmos DB SQL container.
Get-AzCosmosDBSqlContainerBackupInformation -ResourceGroupName "<ResourceGroupName>" -AccountName "<AccountName>" -DatabaseName "<DatabaseName>" -Name "<ContainerName>" -Location "<location>"

# Get the throughput (RU/s) settings for a specific Cosmos DB SQL container.
Get-AzCosmosDBSqlContainerThroughput -ResourceGroupName "<ResourceGroupName>" -AccountName "<AccountName>" -DatabaseName "<DatabaseName>" -Name "<ContainerName>"

# List all SQL databases under a specific Cosmos DB account.
Get-AzCosmosDBSqlDatabase -ResourceGroupName "<ResourceGroupName>" -AccountName "<AccountName>"

# Get the throughput (RU/s) settings for a specific Cosmos DB SQL database.
Get-AzCosmosDBSqlDatabaseThroughput -ResourceGroupName "<ResourceGroupName>" -AccountName "<AccountName>" -Name "<DatabaseName>"

# List all SQL role assignments for a specific Cosmos DB account.
Get-AzCosmosDBSqlRoleAssignment -ResourceGroupName "<ResourceGroupName>" -AccountName "<AccountName>"

# List all SQL role definitions for a specific Cosmos DB account.
Get-AzCosmosDBSqlRoleDefinition -ResourceGroupName "<ResourceGroupName>" -AccountName "<AccountName>"

# List all stored procedures in a specific Cosmos DB SQL container.
Get-AzCosmosDBSqlStoredProcedure -ResourceGroupName "<ResourceGroupName>" -AccountName "<AccountName>" -DatabaseName "<DatabaseName>" -ContainerName "<ContainerName>"

# List all triggers in a specific Cosmos DB SQL container.
Get-AzCosmosDBSqlTrigger -ResourceGroupName "<ResourceGroupName>" -AccountName "<AccountName>" -DatabaseName "<DatabaseName>" -ContainerName "<ContainerName>"

# List all user-defined functions (UDFs) in a specific Cosmos DB SQL container.
Get-AzCosmosDBSqlUserDefinedFunction -ResourceGroupName "<ResourceGroupName>" -AccountName "<AccountName>" -DatabaseName "<DatabaseName>" -ContainerName "<ContainerName>"
```
{{#endtab }}
{{#endtabs }}

#### Connessione

Ha 2 tipi di chiavi, Read-write (completo) e Read-only. Forniscono l'accesso indicato a tutti i database, collezioni e dati all'interno dell'account Cosmos DB. 
Per connettersi è necessaria la libreria azure-cosmosDB (pip install azure-cosmos). Inoltre, l'endpoint e la chiave sono componenti cruciali per stabilire la connessione.
```python
from azure.cosmos import CosmosClient, PartitionKey

# Connection details
endpoint = "<your-account-endpoint>"
key = "<your-account-key>"

# Initialize Cosmos Client
client = CosmosClient(endpoint, key)

# Access existing database and container
database_name = '<SampleDB>'
container_name = '<SampleContainer>'
database = client.get_database_client(database_name)
container = database.get_container_client(container_name)

# Insert multiple documents
items_to_insert = [
{"id": "1", "name": "Sample Item", "description": "This is a sample document."},
{"id": "2", "name": "Another Sample Item", "description": "This is another sample document."},
{"id": "3", "name": "Sample Item", "description": "This is a duplicate name sample document."},
]

for item in items_to_insert:
container.upsert_item(item)

# Query all documents
query = "SELECT * FROM c"
all_items = list(container.query_items(
query=query,
enable_cross_partition_query=True
))

# Print all queried items
print("All items in the container:")
for item in all_items:
print(item)
```
Un altro modo per stabilire una connessione è utilizzare **DefaultAzureCredential()**. È sufficiente effettuare il login (az login) con l'account che ha i permessi e eseguirlo. In questo caso, deve essere effettuata un'assegnazione di ruolo, dando i permessi necessari (vedi per mor)
```python
from azure.identity import DefaultAzureCredential
from azure.cosmos import CosmosClient

# Use Azure AD for authentication
credential = DefaultAzureCredential()
endpoint = "<your-account-endpoint>"
client = CosmosClient(endpoint, credential)

# Access database and container
database_name = "<mydatabase>"
container_name = "<mycontainer>"
database = client.get_database_client(database_name)
container = database.get_container_client(container_name)

# Insert a document
item = {
"id": "1",
"name": "Sample Item",
"description": "This is a test item."
}
container.create_item(item)
print("Document inserted.")
```
### MongoDB
L'API NoSQL di MongoDB è un'API basata su documenti che utilizza BSON (Binary JSON) simile a JSON come formato dei dati. Fornisce un linguaggio di query con capacità di aggregazione, rendendolo adatto per lavorare con dati strutturati, semi-strutturati e non strutturati. L'endpoint del servizio segue tipicamente questo formato:
```bash
mongodb://<hostname>:<port>/<database>
```
#### Database
In MongoDB, puoi creare uno o più database all'interno di un'istanza. Ogni database funge da raggruppamento logico di collezioni e fornisce un confine per l'organizzazione e la gestione delle risorse. I database aiutano a separare e gestire i dati in modo logico, ad esempio per diverse applicazioni o progetti.

#### Collezioni
L'unità fondamentale di archiviazione dei dati in MongoDB è la collezione, che contiene documenti ed è progettata per query efficienti e un design dello schema flessibile. Le collezioni sono elastico scalabili e possono supportare operazioni ad alta capacità attraverso più nodi in un setup distribuito.

#### Caratteristiche principali del tipo di unità di richiesta (RU)
**Distribuzione globale**: Abilita o disabilita la Geo-Redundancy per la replica tra regioni e le scritture multi-regione per una disponibilità migliorata.  
**Networking & Sicurezza**: tra endpoint pubblici (tutti/seleziona reti) o privati per la connettività. Connessioni sicure con crittografia TLS 1.2. Supporta CORS (Cross-Origin Resource Sharing) per un accesso controllato alle risorse. Per stabilire la connessione puoi utilizzare le chiavi.  
**Backup & Ripristino**: da politiche di backup Periodiche, Continue (7 giorni, gratuite) o Continue (30 giorni, a pagamento) con intervalli e retention configurabili.  
**Crittografia dei dati**: Chiavi gestite dal servizio predefinite o chiavi gestite dal cliente (CMK) per la crittografia (la selezione di CMK è irreversibile).

#### Caratteristiche principali del tipo di cluster vCore
**Distribuzione globale**: Abilita una replica di lettura in un'altra regione Azure per alta disponibilità e supporto al failover. Configura il nome della replica, la regione e lo storage per shard.  
**Networking & Sicurezza**: Supporta l'accesso pubblico con IP pubblici assegnati e accesso privato. Limita le connessioni utilizzando regole del firewall: per impostazione predefinita, non sono consentiti IP pubblici.  
**Connessioni crittografate**: Impone la crittografia TLS per una trasmissione sicura dei dati.

#### Enumerazione

{{#tabs }}
{{#tab name="az cli" }}
```bash
# CosmoDB Account
## List Azure Cosmos DB database accounts.
az cosmosdb list --resource-group <ResourceGroupName>
az cosmosdb show --resource-group <ResourceGroupName> --name <AccountName>

## Lists the virtual network accounts associated with a Cosmos DB account
az cosmosdb network-rule list --resource-group <ResourceGroupName> --name <AccountName>
## List the access keys or connection strings for a Azure Cosmos DB
az cosmosdb keys list --name <AccountName> --resource-group <ResourceGroupName>
## List all the database accounts that can be restored.
az cosmosdb restorable-database-account list --account-name <AccountName>
## Show the identities for a Azure Cosmos DB database account.
az cosmosdb identity show --resource-group <ResourceGroupName> --name <AccountName>

## MongoDB
# List all MongoDB databases in a specified Azure Cosmos DB account
az cosmosdb mongodb database list --account-name <AccountName> --resource-group <ResourceGroupName>
# List all collections in a specific MongoDB database within an Azure Cosmos DB account
az cosmosdb mongodb collection list --account-name <AccountName> --database-name <DatabaseName> --resource-group <ResourceGroupName>

#RBAC FUNCTIONALITIES MUST BE ENABLED TO USE THIS
# List all role definitions for MongoDB within an Azure Cosmos DB account
az cosmosdb mongodb role definition list --account-name <AccountName> --resource-group <ResourceGroupName>
# List all user definitions for MongoDB within an Azure Cosmos DB account
az cosmosdb mongodb user definition list --account-name <AccountName> --resource-group <ResourceGroupName>

## MongoDB (vCore)
# Install az cli extension
az extension add --name cosmosdb-preview
# List all MongoDB databases in a specified Azure Cosmos DB account
az cosmosdb mongocluster list
az cosmosdb mongocluster show --cluster-name <name> --resource-group <ResourceGroupName>
# Get firewall rules
az cosmosdb mongocluster firewall rule list --cluster-name <name> --resource-group <ResourceGroupName>
# Connect to in
brew install mongosh
mongosh "mongodb://<username>:<password>@<account-name>.mongo.cosmos.azure.com:10255/?ssl=true&replicaSet=globaldb&retryWrites=false" --username <username> --password <password>
```
{{#endtab }}

{{#tab name="Az Powershell" }}
```bash
Get-Command -Module Az.CosmosDB

# List all Cosmos DB accounts in a specified resource group.
Get-AzCosmosDBAccount -ResourceGroupName "<ResourceGroupName>"

# Get the access keys for a specific Cosmos DB account.
Get-AzCosmosDBAccountKey -ResourceGroupName "<ResourceGroupName>" -Name "<AccountName>"

# Retrieve the client encryption keys for a specific Cosmos DB account.
Get-AzCosmosDbClientEncryptionKey -ResourceGroupName "<ResourceGroupName>" -AccountName "<AccountName>" -DatabaseName "<DatabaseName>"

# List all MongoDB collections in a specific database.
Get-AzCosmosDBMongoDBCollection -AccountName <account-name> -ResourceGroupName <resource-group-name> -DatabaseName <database-name>

# Retrieve backup information for a specific MongoDB collection in a database.
Get-AzCosmosDBMongoDBCollectionBackupInformation -AccountName <account-name> -ResourceGroupName <resource-group-name> -DatabaseName <database-name> -Name <collection-name> -Location <Location>

# Get the throughput (RU/s) of a specific MongoDB collection in a database.
Get-AzCosmosDBMongoDBCollectionThroughput -AccountName <account-name> -ResourceGroupName <resource-group-name> -DatabaseName <database-name> -Name <collection-name>

# List all MongoDB databases in a specified Cosmos DB account.
Get-AzCosmosDBMongoDBDatabase -AccountName <account-name> -ResourceGroupName <resource-group-name>

# Get the throughput (RU/s) of a specific MongoDB database.
Get-AzCosmosDBMongoDBDatabaseThroughput -AccountName <account-name> -ResourceGroupName <resource-group-name> -DatabaseName <database-name>

# Retrieve the role definitions for MongoDB users in a specified Cosmos DB account.
Get-AzCosmosDBMongoDBRoleDefinition -AccountName <account-name> -ResourceGroupName <resource-group-name>

```
{{#endtab }}
{{#endtabs }}

#### Connessione

Il tipo RU MongoDB in CosmoDB ha 2 tipi di chiavi, Read-write (completo) e Read-only. Forniscono l'accesso indicato a tutti i database, collezioni e dati all'interno dell'account Cosmos DB. 
Per la password puoi utilizzare le chiavi o il metodo descritto nella sezione privesc.
```python
from pymongo import MongoClient

# Updated connection string with retryWrites=false
connection_string = "mongodb://<account-name>.mongo.cosmos.azure.com:10255/?ssl=true&replicaSet=globaldb&retryWrites=false"

# Create the client. The password and username is a custom one if the type is "vCore cluster".
# In case that is a Request unit (RU) the username is the account name and the password is the key of the cosomosDB account.
client = MongoClient(connection_string, username="<username>", password="<password>")

# Access the database
db = client['<database>']

# Access a collection
collection = db['<collection>']

# Insert a single document
document = {
"name": "John Doe",
"email": "johndoe@example.com",
"age": 30,
"address": {
"street": "123 Main St",
"city": "Somewhere",
"state": "CA",
"zip": "90210"
}
}

# Insert document
result = collection.insert_one(document)
print(f"Inserted document with ID: {result.inserted_id}")
```
O utilizzando un utente all'interno del mongo:
```bash
mongosh "mongodb://<myUser>:<mySecurePassword>@<account_name>.mongo.cosmos.azure.com:10255/<mymongodatabase>?ssl=true&replicaSet=globaldb&retrywrites=false"
```
## Riferimenti

- [https://learn.microsoft.com/en-us/azure/cosmos-db/choose-api](https://learn.microsoft.com/en-us/azure/cosmos-db/choose-api)
- [https://learn.microsoft.com/en-us/azure/cosmos-db/](https://learn.microsoft.com/en-us/azure/cosmos-db/)
- [https://learn.microsoft.com/en-us/azure/cosmos-db/introduction](https://learn.microsoft.com/en-us/azure/cosmos-db/introduction)
- [https://learn.microsoft.com/en-us/azure/cosmos-db/nosql/security/how-to-grant-data-plane-role-based-access?tabs=built-in-definition%2Ccsharp&pivots=azure-interface-cli](https://learn.microsoft.com/en-us/azure/cosmos-db/nosql/security/how-to-grant-data-plane-role-based-access?tabs=built-in-definition%2Ccsharp&pivots=azure-interface-cli)

## Escalation dei privilegi

{{#ref}}
../az-privilege-escalation/az-cosmosDB-privesc.md
{{#endref}}

## Post Exploitation

{{#ref}}
../az-post-exploitation/az-sql-post-exploitation.md
{{#endref}}

## ToDo

* Il resto del DB qui, tabelle, cassandra, gremlin...
* Dai un'occhiata alla post exploitation "Microsoft.DocumentDB/databaseAccounts/mongodbUserDefinitions/write" && "Microsoft.DocumentDB/databaseAccounts/mongodbUserDefinitions/read" e alle definizioni dei ruoli perché qui potrebbe esserci un privesc
* Dai un'occhiata ai ripristini



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