# Az - CosmosDB

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

## Azure CosmosDB

**Azure Cosmos DB** は、単一桁ミリ秒の応答時間、自動スケーラビリティ、エンタープライズグレードのセキュリティを備えた SLA に裏打ちされた可用性を提供する完全に **管理された NoSQL、リレーショナル、ベクトルデータベース** です。これは、ターンキーのマルチリージョンデータ配信、オープンソースの API、人気のある言語向けの SDK、統合されたベクトルサポートやシームレスな Azure AI 統合などの AI データベース機能を通じて、アプリ開発を加速します。

Azure Cosmos DB は、ドキュメント、リレーショナル、キー-バリュー、グラフ、カラムファミリーデータモデルを使用して現実のデータをモデル化するための複数のデータベース API を提供しており、これらの API は NoSQL、MongoDB、PostgreSQL、Cassandra、Gremlin、および Table です。

CosmosDB の重要な側面の一つは Azure Cosmos アカウントです。**Azure Cosmos アカウント** は、データベースへの入り口として機能します。このアカウントは、グローバル配信、一貫性レベル、使用する特定の API（NoSQL など）などの主要な設定を決定します。アカウントを通じて、データが複数のリージョンで低遅延アクセスのために利用可能であることを保証するグローバルレプリケーションを構成できます。さらに、パフォーマンスとデータの正確性のバランスを取る一貫性レベルを選択でき、強い一貫性から最終的な一貫性までのオプションがあります。

Azure Cosmos DB は、リソースのライフサイクルに自動的に作成され、関連付けられる **ユーザー割り当ての ID** と **システム割り当ての管理 ID** をサポートしています。ただし、Cosmos DB には Azure Blob Storage のような外部データソースを直接クエリするための組み込みメカニズムはありません。SQL Server の外部テーブル機能とは異なり、Cosmos DB では、データをそのネイティブクエリ機能でクエリできるようにする前に、Azure Data Factory、データ移行ツール、またはカスタムスクリプトなどの外部ツールを使用してそのコンテナに取り込む必要があります。

### NoSQL
Azure Cosmos DB NoSQL API は、JSON をデータ形式として使用するドキュメントベースの API です。これは、JSON オブジェクトをクエリするための SQL に似たクエリ構文を提供し、構造化データおよび半構造化データの操作に適しています。サービスのエンドポイントは次のとおりです:
```bash
https://<Account-Name>.documents.azure.com:443/
```
#### データベース
アカウント内で、1つ以上のデータベースを作成できます。これらはコンテナの論理的なグループとして機能します。データベースは、リソース管理とユーザー権限の境界として機能します。データベースは、複数のコンテナが共有のパフォーマンス容量を使用できるようにするか、各コンテナに専用のパワーを与えることができます。

#### コンテナ
データストレージのコアユニットはコンテナであり、JSONドキュメントを保持し、効率的なクエリのために自動的にインデックスされます。コンテナは弾力的にスケーラブルで、ユーザー定義のパーティションキーによって決定されるパーティション全体に分散されています。パーティションキーは、最適なパフォーマンスと均等なデータ分配を確保するために重要です。たとえば、コンテナは顧客データを保存し、「customerId」をパーティションキーとして使用することがあります。

#### 主な機能
- **グローバル配信**: 地域間レプリケーションのためのGeo-Redundancyを有効または無効にし、可用性を向上させるためのMulti-region Writesを使用します。
- **ネットワーキングとセキュリティ**: 公開（すべて/選択されたネットワーク）またはプライベートエンドポイント間の接続性。TLS 1.2暗号化による安全な接続。リソースへの制御されたアクセスのためにCORS（Cross-Origin Resource Sharing）をサポートします。Microsoft Defender for Cloudを有効にできます。接続を行うには、キーを使用できます。
- **バックアップと復元**: 定期的、継続的（7日間）、または継続的（30日間）のバックアップポリシーから、構成可能な間隔と保持期間を持ちます。
- **データ暗号化**: デフォルトのサービス管理キーまたは顧客管理キー（CMK）による暗号化（CMKの選択は不可逆です）。

#### 列挙

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

#### 接続

2つのキータイプがあります。読み書き（フル）と読み取り専用です。これらは、Cosmos DBアカウント内のすべてのデータベース、コレクション、およびデータへのアクセスを提供します。
azure-cosmosDBに接続するには（pip install azure-cosmos）、ライブラリが必要です。さらに、エンドポイントとキーは接続を確立するための重要なコンポーネントです。
```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)
```
接続を確立する別の方法は、**DefaultAzureCredential()**を使用することです。権限を持つアカウントでログイン（az login）し、それを実行するだけです。この場合、必要な権限を与える役割の割り当てを行う必要があります（詳細については参照してください）。
```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
MongoDB NoSQL APIは、JSONに似たBSON（Binary JSON）をデータ形式として使用するドキュメントベースのAPIです。これは、集約機能を持つクエリ言語を提供し、構造化データ、半構造化データ、および非構造化データの処理に適しています。サービスのエンドポイントは通常、次の形式に従います：
```bash
mongodb://<hostname>:<port>/<database>
```
#### データベース
MongoDBでは、インスタンス内に1つ以上のデータベースを作成できます。各データベースはコレクションの論理的なグループとして機能し、リソースの組織と管理の境界を提供します。データベースは、異なるアプリケーションやプロジェクトのためにデータを論理的に分離し、管理するのに役立ちます。

#### コレクション
MongoDBにおけるデータストレージのコアユニットはコレクションであり、ドキュメントを保持し、効率的なクエリと柔軟なスキーマ設計のために設計されています。コレクションは弾力的にスケーラブルで、分散セットアップ内の複数のノードで高スループットの操作をサポートできます。

#### リクエストユニット（RU）タイプの主な機能
**グローバル分散**: 地域間レプリケーションのためのGeo-Redundancyを有効または無効にし、可用性を向上させるためのマルチリージョン書き込みを行います。
**ネットワーキングとセキュリティ**: 公開（すべて/選択されたネットワーク）またはプライベートエンドポイント間の接続。TLS 1.2暗号化による安全な接続。リソースへの制御されたアクセスのためにCORS（Cross-Origin Resource Sharing）をサポートします。接続を行うには、キーを使用できます。
**バックアップとリカバリ**: 定期的、継続的（7日間、無料）、または継続的（30日間、有料）バックアップポリシーから、設定可能な間隔と保持期間でバックアップを行います。
**データ暗号化**: デフォルトのサービス管理キーまたは顧客管理キー（CMK）による暗号化（CMKの選択は不可逆です）。

#### vCoreクラスタータイプの主な機能
**グローバル分散**: 高可用性とフェイルオーバーサポートのために、別のAzureリージョンに読み取りレプリカを有効にします。レプリカ名、リージョン、およびシャードごとのストレージを設定します。
**ネットワーキングとセキュリティ**: 割り当てられたパブリックIPとプライベートアクセスを持つパブリックアクセスをサポートします。ファイアウォールルールを使用して接続を制限します—デフォルトでは、パブリックIPは許可されていません。
**暗号化された接続**: 安全なデータ送信のためにTLS暗号化を強制します。

#### 列挙

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

#### 接続

CosmoDBのRU MongoDBタイプには、読み書き（フル）と読み取り専用の2つのキータイプがあります。これらは、Cosmos DBアカウント内のすべてのデータベース、コレクション、およびデータへのアクセスを提供します。
パスワードには、キーを使用するか、特権昇格セクションで説明されている方法を使用できます。
```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}")
```
mongo内のユーザーを使用するか：
```bash
mongosh "mongodb://<myUser>:<mySecurePassword>@<account_name>.mongo.cosmos.azure.com:10255/<mymongodatabase>?ssl=true&replicaSet=globaldb&retrywrites=false"
```
## 参考文献

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

## 権限昇格

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

## ポストエクスプロイト

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

## ToDo

* ここに残りのDB、テーブル、Cassandra、Gremlin...
* ポストエクスプロイトの "Microsoft.DocumentDB/databaseAccounts/mongodbUserDefinitions/write" と "Microsoft.DocumentDB/databaseAccounts/mongodbUserDefinitions/read" およびロール定義を確認してください。ここには権限昇格の可能性があります。
* 復元を確認してください。



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