Azure Part 2

微软门户网站

https://msportals.io/

官方工具安装

Azure PowerShell

是用于管理 Azure 资源的官方 Microsoft PowerShell 模块集合的产品名称,可以枚举 Entra ID 和 Azure 资源

// 查看powershell版本
$PSVersionTable.PSVersion

// 安装 PowerShellGet
Install-Module -Name PowerShellGet -Force
[Y] Yes [N] No [S] Suspend [?] Help (default is "Y"): Y

// 放宽PowerShell策略
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "N"): A

// 安装 Azure PowerShell 模块
Install-Module -Name Az -Repository PSGallery -Force

// 验证
Get-InstalledModule -Name Az -AllVersions

// 更新 Azure PowerShell
Update-Module -Name Az -Force

Graph PowerShell

Microsoft Graph PowerShell SDK 是 Microsoft Graph API 的 API 封装器,将整个 API 集暴露给 PowerShell 使用,建议用于与 Microsoft Entra ID 进行交互

// 放宽PowerShell策略
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "N"): A

// 为当前用户安装
Install-Module Microsoft.Graph -Scope CurrentUser
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "N"): A

// 验证
Get-InstalledModule Microsoft.Graph

在Windows Powershell 环境下安装了 Microsoft.Graph 2.x 版本后,Az 和 Graph 会出现函数找不到的兼容问题,例如:

Get-MgGroup : 找不到方法:Void Microsoft.Graph.Authentication.AzureIdentityAccessTokenProvider..ctor

下载powershell 7 可解决

Azure CLI

是一款跨平台命令行工具,用于连接到 Azure 并通过交互式命令或脚本管理 Azure 资源

// 安装
$ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest -Uri https://aka.ms/installazurecliwindows -OutFile .\AzureCLI.msi; Start-Process msiexec.exe -Wait -ArgumentList '/I', 'AzureCLI.msi', '/quiet'; Remove-Item .\AzureCLI.msi

// 验证
az --version

凭证登录

Azure Powershell

// 弹出来门户登录
Connect-AzAccount

// 用户账号密码登录
$pass = ConvertTo-SecureString '<PASSWORD>' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential("<UserPrincipalName>", $pass)
Connect-AzAccount -Credential $cred

// 服务主体密钥登录
$pass = ConvertTo-SecureString '<SECRET>' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential("<CLIENTID>", $pass)
Connect-AzAccount -ServicePrincipal -Tenant "<TENANTID>" -Credential $cred

// Token登录
Connect-AzAccount -AccessToken "<eyJ0......>" -AccountId "<ANY_NAME>"

Graph PowerShell

// 弹出来门户登录
Connect-MgGraph

// Token登录
$pass = ConvertTo-SecureString "<PASSWORD>" -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential("<User>", $pass)
Connect-AzAccount -Credential $cred
$Token = (Get-AzAccessToken -ResourceTypeName MSGraph).Token
Connect-MgGraph -AccessToken $Token

// 添加权限范围
Connect-MgGraph -Scopes "User.Read.All","Group.Read.All","Directory.Read.All","Application.Read.All"

Azure Cli

az login --user "<username>" --password "<password>"

Portal 门户

https://portal.azure.com/

REST API

纯拿Token访问API,可以写python脚本

GET /v1.0/users HTTP/1.1
Host: graph.microsoft.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Authorization: Bearer <Token>
Accept: application/json
Connection: close

常用命令

这里只偏向记录Entra ID的命令,完整官方档案:

Az Ps

断开连接

Disconnect-AzAccount

命令格式,关于Azure AD格式均为 AzAD

Get-Command *azad*

获取为当前用户授权的所有租户

Get-AzTenant

当前身份上下文元数据

Get-AzContext

获取Graph的 Access Token

(Get-AzAccessToken -AsSecureString -ResourceTypeName MSGraph).Token

列出所有 Azure RBAC 角色分配

Get-AzRoleAssignment

获取Entra ID用户信息

// 所有用户信息
Get-AzADUser

// 数量
(Get-AzADUser -Select 'DisplayName').Count

// 获取当前登录用户
Get-AzADUser -SignedIn

// 模糊搜索
Get-AzADUser -UserPrincipalName [email protected]
Get-AzADUser | ?{$_.Displayname -match "admin"}

// 前10个
Get-AzADUser -First 10

获取Group信息

// 所有组信息
Get-AzADGroup

// 数量
(Get-AzADGroup -Select DisplayName).Count

// 模糊搜索
Get-AzADGroup -ObjectId 783a312d-0de2-4490-92e4-539b0e4ee03e
Get-AzADGroup | ?{$_.Displayname -match "admin"}

// 组成员
Get-AzADGroupMember -GroupObjectId xxx

Application(App Registration,应用注册)信息

// 所有app详细信息
Get-AzADApplication
Get-AzADApplication -Select DisplayName,Id,AppId

// 数量
(Get-AzADApplication -Select DisplayName).Count

// 模糊搜索
Get-AzADApplication -ObjectId a1333e88-1278-41bf-8145-155a069ebed0
Get-AzADApplication | ?{$_.DisplayName -match "app"}

// 查询所有存在 Client Secret 的app
Get-AzADApplication -Select DisplayName,Id,AppId,PasswordCredentials | Where-Object { $_.PasswordCredentials }

// 查询所有存在 Certificate 的app
Get-AzADApplication -Select DisplayName,Id,AppId,KeyCredentials | Where-Object { $_.KeyCredentials }

Application 的凭据

Get-AzADAppCredential -ObjectId xxx
Get-AzADAppCredential -DisplayName xxx
Get-AzADAppCredential -ApplicationId xxx

ServicePrincipal(Enterprise Application,服务主体)信息

// 所有主体
Get-AzADServicePrincipal
Get-AzADServicePrincipal -Select DisplayName,Id,AppId

// 数量
(Get-AzADServicePrincipal -Select DisplayName).Count

// 模糊搜索
Get-AzADServicePrincipal -ObjectId a1333e88-1278-41bf-8145-155a069ebed0
Get-AzADServicePrincipal | ?{$_.DisplayName -match "app"}

// 查询所有存在 Client Secret 的主体
Get-AzADServicePrincipal -Select DisplayName,Id,AppId,PasswordCredentials | Where-Object { $_.PasswordCredentials }

// 查询所有存在 Certificate 的主体
Get-AzADServicePrincipal -Select DisplayName,Id,AppId,KeyCredentials | Where-Object { $_.KeyCredentials }

从 ServicePrincipal 获取 appRoleAssignments

Get-AzADServicePrincipalAppRoleAssignment

ServicePrincipal的的凭据

Get-AzADSpCredential -ObjectId xxx

Graph Ps

断开连接

Disconnect-MgGraph

当前身份上下文

Get-MgContext
(Get-MgContext).Scopes

用户

// 所有用户
Get-MgUser -All

// 模糊搜索
Get-MgUser -UserId [email protected]
Get-MgUser -All | ?{ $_.Displayname -match "admin" }
Get-MgUser -Search '"DisplayName:admin"' -ConsistencyLevel eventual

// 用户所有属性
Get-MgUser -UserId [email protected] | fl *
Get-MgUser -UserId [email protected] | % { $_.PSObject.Properties.Name }

// 搜索指定属性的用户
Get-MgUser -All | % { $Properties = $_; $Properties.PSObject.Properties.Name | % { if ($Properties.$_ -match 'password') { "$($Properties.UserPrincipalName) - $_ - $($Properties.$_)" } } }

// 所有本地同步用户
Get-MgUser -All | ? { $_.OnPremisesSecurityIdentifier -ne $null }

// 所有Entra Id用户
Get-MgUser -All | ? { $_.OnPremisesSecurityIdentifier -eq $null }

// 用户创建的对象
Get-MgUserCreatedObject -UserId [email protected] | fl *

// 用户拥有的对象
Get-MgUserOwnedObject -UserId [email protected] | fl *

// 用户所属组和角色
(Get-MgUserMemberOf -UserId [email protected]).AdditionalProperties

// 所有组
Get-MgGroup -All

// 指定组
Get-MgGroup -GroupId xxxx

// 动态组
Get-MgGroup | ? { $_.GroupTypes -eq 'DynamicMembership' }

// 模糊查找
Get-MgGroup -ConsistencyLevel eventual -Search '"DisplayName:Admin"'

// 所有本地同步组
Get-MgGroup -All | ? { $_.OnPremisesSecurityIdentifier -ne $null }

// 所有Entra Id组
Get-MgGroup -All | ? { $_.OnPremisesSecurityIdentifier -eq $null }

// 组成员
Get-MgGroupMember -GroupId xxx

// 组owner
Get-MgGroupOwner

角色

// 所有可用的角色模板
Get-MgDirectoryRoleTemplate

// 启用角色
Get-MgDirectoryRole

// 模糊查询
Get-MgRoleManagementDirectoryRoleDefinition -Filter "DisplayName eq 'AS-ADCRADLC8'" | Format-List

// 所有被分配了角色的用户
$RoleId = (Get-MgDirectoryRole -Filter "DisplayName eq 'Global Administrator'").Id
(Get-MgDirectoryRoleMember -DirectoryRoleId $RoleId).AdditionalProperties

// 角色拥有的权限
(Get-MgRoleManagementDirectoryRoleDefinition -Filter "DisplayName eq 'AS-ADCRADLC8'").RolePermissions.AllowedResourceActions

设备

// 所有已加入和已注册的 Azure 设备
Get-MgDevice –All | fl *

// 活动设备
Get-MgDevice –All | ? { $_.ApproximateLastSignInDateTime -ne $null }

// 所有设备的注册所有者
$Ids = (Get-MgDevice –All).Id; foreach($i in $Ids) { (Get-MgDeviceRegisteredOwner -DeviceId $i).AdditionalProperties }
$Ids = (Get-MgDevice –All).Id; foreach($i in $Ids) { (Get-MgDeviceRegisteredOwner -DeviceId $i).AdditionalProperties.userPrincipalName }

// 所有设备的注册用户
$Ids = (Get-MgDevice –All).Id; foreach($i in $Ids) { (Get-MgDeviceRegisteredUser -DeviceId $i).AdditionalProperties }
$Ids = (Get-MgDevice –All).Id; foreach($i in $Ids) { (Get-MgDeviceRegisteredUser -DeviceId $i).AdditionalProperties.userPrincipalName }

// 用户拥有的设备
(Get-MgUserOwnedDevice -UserId [email protected]).AdditionalProperties

// 用户注册设备
(Get-MgUserRegisteredDevice -UserId [email protected]).AdditionalProperties

// Intune 管理的设备
Get-MgDevice -All | ? { $_.IsCompliant -eq "True" } | fl *

Application

Get-MgApplication -All

// 指定app
Get-MgApplicationByAppId -AppId f072c4a6-b440-40de-983f-a7f3bd317d8f | fl *

// 模糊搜索
Get-MgApplication -All | ? { $_.DisplayName -match "app" }

// app拥有者
(Get-MgApplicationOwner -ApplicationId 35589758-714e-43a9-be9e-94d22fdd34f6).AdditionalProperties.userPrincipalName

// 某个用户被授予了哪些应用权限
Get-MgUserAppRoleAssignment -UserId [email protected] | fl *

// 某个组被授予了哪些应用权限
Get-MgGroupAppRoleAssignment -GroupId 57ada729-a581-4d6f-9f16-3fe0961ada82 | fl *

ServicePrincipal

Get-MgServicePrincipal -All

// 指定服务主体
Get-MgServicePrincipal -ServicePrincipalId fd518680-b290-4db2-b92a-5dbd025c6791 | fl *

// 模糊搜索
Get-MgServicePrincipal –All | ? { $_.DisplayName -match "app" }

// 服务主体的拥有者
(Get-MgServicePrincipalOwner -ServicePrincipalId fd518680-b290-4db2-b92a-5dbd025c6791).AdditionalProperties.userPrincipalName

// 服务主体拥有的对象
Get-MgServicePrincipalOwnedObject -ServicePrincipalId fd518680-b290-4db2-b92a-5dbd025c6791

// 服务主体创建的对象
Get-MgServicePrincipalCreatedObject -ServicePrincipalId fd518680-b290-4db2-b92a-5dbd025c6791

// 服务主体的组成员身份和角色成员身份
Get-MgServicePrincipalMemberOf -ServicePrincipalId fd518680-b290-4db2-b92a-5dbd025c6791 | fl *

身份验证

Microsoft Identity Platform(微软身份平台)使用两种不同的协议完成两件不同的事

  • OpenID Connect(OIDC):身份验证(Authentication)即 你是谁
  • OAuth2:授权(Authorization)即 你能做什么

Token

微软通常会同时返回三种token

  • ID Token:客户端从授权服务器接收此令牌,它包含用户的基本信息,用作登录身份
  • Access Token:客户端向资源服务器提供此令牌以访问资源,它只能用于特定的用户、客户端和资源组合,并且在过期前(默认为 1 小时)无法撤销,用作通过API进行资源访问
  • Refresh Token:用于获取新的 Access Token 和 ID Token,非活跃刷新令牌的默认过期时间为 90 天,活跃令牌没有过期时间,可以被撤销

攻击流程

Recon → Initial Access → Post-Ex → Persistence → 横向移动 → 特殊攻击(SAML/MFA) 分层整理

External Reconnaissance
Initial Access
Token Acquisition
Internal Enumeration
Privilege Escalation
Lateral Movement
Persistence
Defense Evasion
Data Exfiltration

---

外部侦察
初始访问
令牌获取
内部枚举
权限提升
横向移动
持久化
防御规避
数据泄露

信息收集/枚举

目标:摸清 Entra ID / Azure / O365 结构

  • AzureHound:类似 BloodHound,但针对 Azure / Entra ID
  • ROADtools(ROADrecon)
    • 枚举 Azure AD / Entra ID(非常核心)
    • 支持 Graph API、token 操作
  • Stormspotter
    • 可视化 Azure 资源关系(图形化攻击路径)
  • MicroBurst
    • Azure 资产发现 + 弱配置扫描
  • o365recon / o365creeper
    • 枚举 O365 用户、邮箱

初始访问

云红队最常见:账号攻击

工具

  • MSOLSpray
  • o365spray
  • TrevorSpray
  • CredMaster(配合代理)

主要攻击:

  • Password spraying
  • 用户名枚举
  • MFA 疲劳攻击

权限提升/后渗透

获取 token 后才是真正开始

工具

  • GraphRunner
    • Microsoft Graph API 后渗透框架
  • GraphSpy
    • GUI 操作 O365 数据(邮件 / OneDrive / Teams)
  • APEX
    • Azure 后渗透框架(整合 ROADtools 等)
  • PowerZure
    • PowerShell Azure 攻击框架

凭证获取/Token攻击

Azure 和传统 AD 最大区别:Token 即权限

工具

  • AADInternals
    • 获取 token、dump 信息、滥用 Azure AD
  • adconnectdump
    • dump Azure AD Connect 凭证
  • EntraTokenAid(社区工具)
    • 获取 access / refresh token(红队常用)

持久化

云环境 persistence 很隐蔽

技术

  • Service Principal backdoor
  • 恶意 App 注册
  • Guest 用户植入

相关工具:

  • ROADtools
  • GraphRunner
  • AADInternals

攻击方式示例:

  • 创建隐藏角色绑定
  • 添加高权限应用
  • 修改 API 权限

横向移动

在云里 = 权限链移动

工具

  • AzureHound + BloodHound
  • Stormspotter

核心思想:

  • 找 ‘谁可以控制谁’
  • 利用 RBAC / App / Role 关系

O365 专用攻击工具

偏数据窃取

  • MailSniper
    • 搜索邮箱敏感信息
  • GraphSpy
    • 跨 OneDrive / SharePoint / Teams 搜索
  • github.com/admindroid-community/powershell-scripts

高级攻击

这部分是云红队精髓

Evilginx

  • 反向代理钓鱼
  • 窃取 session cookie
  • 绕过 MFA

云红队必备

Golden SAML

  • 伪造 SAML token
  • 直接登录 O365 / Azure

类似 Kerberos Golden Ticket(云版)

MFA 攻击

  • MFASweep
  • MFA fatigue(骚扰认证)

综合工具链总结

Recon:
AzureHound + ROADrecon

Initial Access:
o365spray / MSOLSpray

Post-Ex:
GraphRunner / AADInternals

Persistence:
App backdoor / Service Principal

Data Access:
GraphSpy / MailSniper

Advanced:
Evilginx2 / Golden SAML

重点深入这几个方向

  1. Microsoft Graph API 攻击面
  2. OAuth / Token 滥用
  3. App Registration 攻击
  4. Conditional Access 绕过
  5. PRT(Primary Refresh Token)攻击

Reference

https://learn.microsoft.com/en-us/powershell/azure/

https://learn.microsoft.com/en-us/powershell/microsoftgraph/

https://learn.microsoft.com/en-us/cli/azure/

https://johnermac.github.io/notes/cartp/cartp1/

https://johnermac.github.io/notes/cartp/cartp2/

https://johnermac.github.io/notes/cartp/cartp3/