# Az - CosmosDB

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

## Azure CosmosDB

**Azure Cosmos DB** is a fully **managed NoSQL, relational, and vector database** offering single-digit millisecond response times, automatic scalability, and SLA-backed availability with enterprise-grade security. It enables faster app development through turnkey multi-region data distribution, open-source APIs, SDKs for popular languages, and AI database features like integrated vector support and seamless Azure AI integration.

Azure Cosmos DB provides multiple database APIs to model real-world data using documents, relational, key-value, graph, and column-family data models, being this APIs NoSQL, MongoDB, PostgreSQL, Cassandra, Gremlin and Table. 

One key aspect of CosmosDB is Azure Cosmos Account. **Azure Cosmos Account**, acts as the entry point to the databases. The account determines key settings such as global distribution, consistency levels, and the specific API to be used, such as NoSQL. Through the account, you can configure global replication to ensure data is available across multiple regions for low-latency access. Additionally, you can choose a consistency level that balances between performance and data accuracy, with options ranging from Strong to Eventual consistency.

Azure Cosmos DB supports **user-assigned identities** and **system-assigned managed identities** that are automatically created and tied to the resource's lifecycle. However, Cosmos DB doesn't have a built‑in mechanism to directly query external data sources like Azure Blob Storage. Unlike SQL Server's external table features, Cosmos DB requires data to be ingested into its containers using external tools such as Azure Data Factory, the Data Migration Tool, or custom scripts before it can be queried with its native query capabilities.

### NoSQL
The Azure Cosmos DB NoSQL API is a document-based API that uses JSON as its data format. It provides a SQL-like query syntax for querying JSON objects, making it suitable for working with structured and semi-structured data. The endpoint of the service is:

```bash
https://<Account-Name>.documents.azure.com:443/
```

#### Databases
Within an account, you can create one or more databases, which serve as logical groupings of containers. A database acts as a boundary for resource management and user permissions. Databases can either let multiple containers use a shared pool of performance capacity or give each container its own dedicated power. 

#### Containers
The core unit of data storage is the container, which holds JSON documents and is automatically indexed for efficient querying. Containers are elastically scalable and distributed across partitions, which are determined by a user-defined partition key. The partition key is critical for ensuring optimal performance and even data distribution. For example, a container might store customer data, with "customerId" as the partition key.

#### Key Features
 - **Global Distribution**: Enable or disable Geo-Redundancy for cross-region replication and Multi-region Writes for improved availability.
 - **Networking & Security**: between public (all/select networks) or private endpoints for connectivity. Secure connections with TLS 1.2 encryption. Supports CORS (Cross-Origin Resource Sharing) for controlled access to resources. Microsoft Defender for Cloud can be enabled. To make the connection you can make use of keys.
 - **Backup & Recovery**: from Periodic, Continuous (7 days), or Continuous (30 days) backup policies with configurable intervals and retention.
 - **Data Encryption**: Default service-managed keys or customer-managed keys (CMK) for encryption (CMK selection is irreversible).

#### Enumeration

{{#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 }}

#### Connection

It has 2 key types, Read-write (full) and Read-only. They give the indicated access all databases, collections, and data inside the Cosmos DB account.
To connect the azure-cosmosDB (pip install azure-cosmos) library is needed. Additionally the endpoint and the key are crutial components to make the connection.

```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)
```

Another way of stablishing a connection is to use the **DefaultAzureCredential()**. Just need to login (az login) with the account that has the permissions and execute it. For this case a role assigment must be done, giving the necesary permissions (see  for 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
The MongoDB NoSQL API is a document-based API that uses JSON-like BSON (Binary JSON) as its data format. It provides a query language with aggregation capabilities, making it suitable for working with structured, semi-structured, and unstructured data. The endpoint of the service typically follows this format:

```bash
mongodb://<hostname>:<port>/<database> 
``` 

#### Databases
In MongoDB, you can create one or more databases within an instance. Each database serves as a logical grouping of collections and provides a boundary for resource organization and management. Databases help separate and manage data logically, such as for different applications or projects.

#### Collections
The core unit of data storage in MongoDB is the collection, which holds documents and is designed for efficient querying and flexible schema design. Collections are elastically scalable and can support high-throughput operations across multiple nodes in a distributed setup.

#### Key Features of Request unit (RU) type
**Global Distribution**: Enable or disable Geo-Redundancy for cross-region replication and Multi-region Writes for improved availability.
**Networking & Security**: between public (all/select networks) or private endpoints for connectivity. Secure connections with TLS 1.2 encryption. Supports CORS (Cross-Origin Resource Sharing) for controlled access to resources. To make the connection you can make use of keys.
**Backup & Recovery**: from Periodic, Continuous (7 days, free), or Continuous (30 days, paid) backup policies with configurable intervals and retention.
**Data Encryption**: Default service-managed keys or customer-managed keys (CMK) for encryption (CMK selection is irreversible).

#### Key Features of vCore cluster type
**Global Distribution**: Enable a read replica in another Azure region for high availability and failover support. Configure the replica name, region, and storage per shard.
**Networking & Security**: Supports public access with assigned public IPs and private access. Restrict connections using firewall rules—by default, no public IPs are allowed.
**Encrypted Connections**: Enforces TLS encryption for secure data transmission.


#### Enumeration

{{#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 }}

#### Connection

RU MongoDB type in CosmoDB has 2 key types, Read-write (full) and Read-only. They give the indicated access all databases, collections, and data inside the Cosmos DB account.
For the pasword you can use the keys or with the method decribed in the privesc section. 
```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}")
```

Or using a user within the mongo:

```bash
mongosh "mongodb://<myUser>:<mySecurePassword>@<account_name>.mongo.cosmos.azure.com:10255/<mymongodatabase>?ssl=true&replicaSet=globaldb&retrywrites=false"
```

## References

- [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)

## Privilege Escalation

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

## Post Exploitation

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

## ToDo

* The rest of the DB here, tables, cassandra, gremlin...
* Take a look to the post exploitation "Microsoft.DocumentDB/databaseAccounts/mongodbUserDefinitions/write" && "Microsoft.DocumentDB/databaseAccounts/mongodbUserDefinitions/read" and role definitions cause here might be a privesc
* Take a look to restores



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


