
摘要
2026 年 7 月微软正式宣布将 Passkey 设置为 Entra ID 默认认证方式,并计划于 2027 年 2 月淘汰原生短信、语音多因素认证,该调整源于 AI 辅助钓鱼、SIM 劫持、中间人代理攻击持续突破传统 MFA 防护体系;同期 Proofpoint 披露攻击者通过伪造 OAuth 客户端 ID 实现无注册应用账户枚举,单次攻击覆盖数百万企业账号,现有日志审计机制难以识别空白应用字段下的恶意探测行为。本文以该产业安全新闻为实证样本,梳理短信 / 语音 MFA 结构性安全缺陷、OAuth Client ID 伪造账号枚举攻击完整链路,解析 Passkey 基于 FIDO2/WebAuthn 源绑定公钥密码学的原生防钓鱼机理;针对企业 Entra ID 租户构建 “认证体系升级 + 日志异常检测 + OAuth 访问风控” 三层防御架构,提供 Python 日志检测、WebAuthn 通行密钥服务端轻量化工程代码;反网络钓鱼技术专家芦笛指出,单纯依靠规则拦截无法应对 AI 驱动隐蔽式身份攻击,必须将无共享秘密、域名绑定的 Passkey 作为基础身份防线,配套 OAuth 全链路行为审计形成闭环防护。通过企业租户真实登录日志样本开展对比验证,部署 Passkey 并启用 OAuth 异常检测规则后,钓鱼凭证窃取、批量账号枚举攻击检出率显著提升,可有效降低云身份系统被横向渗透风险。研究可为微软 Entra ID 运维团队、企业云身份安全建设提供可落地的技术改造方案与运维规范。
关键词:Passkey;FIDO2;Entra ID;OAuth 伪造;AI 钓鱼;身份安全;日志审计

1 引言
1.1 研究背景与新闻实证依据
2026 年 7 月 14 日《Redmond Magazine》刊发微软云身份安全官方公告,同步披露 Proofpoint 专项威胁研究成果,集中反映当前企业云身份体系面临两大核心安全危机:其一,传统短信、语音形式多因素认证已形成系统性防护漏洞,AI 辅助钓鱼邮件点击率提升至 54%,搭配 SIM 劫持、中间人代理(AiTM)工具可完整绕过短信验证码校验,大规模窃取企业员工 Entra ID 账号凭证;其二,新型 OAuth Client ID 伪造攻击实现隐蔽式账户枚举,攻击者随机生成虚假应用标识向 Entra ID 发起认证请求,依靠系统差异化错误响应判断账号有效性,攻击日志中应用展示字段为空,传统基于可信应用白名单的检测规则完全失效,单轮攻击可覆盖数百万企业租户账号,威胁溯源难度大幅提升。
针对上述风险,微软推出结构性身份安全改造方案:自 2026 年 9 月 1 日起,系统自动为配置短信、语音 MFA 的 Entra ID 用户推送 Passkey 注册引导,2027 年 2 月 1 日彻底下线平台原生短信、语音验证通道,企业若因合规、业务场景仍需保留该类验证手段,仅能通过第三方电信服务商付费对接。微软官方明确,Passkey 依托无共享秘密公钥加密与域名源绑定特性,从底层消除钓鱼攻击窃取凭证的技术基础,是当前唯一可抵御中间人代理中继攻击的标准化多因素认证方案Microsoft ...。
从全球企业云身份安全统计维度分析,2024—2026 年依托云身份平台的钓鱼劫持攻击年均增幅超 30%,其中 87% 的成功入侵事件目标企业仍大规模使用短信验证码作为二次验证方式;OAuth 相关身份滥用攻击增长更为迅猛,攻击者利用 OAuth 开放授权协议的设计缺陷,绕过应用注册流程完成批量账号探测,且恶意行为不会生成标准成功登录日志,长期潜伏于企业租户日志体系中,直至数据泄露、内网横向渗透后才被察觉,事后溯源取证成本极高。结合本次微软与 Proofpoint 联合披露的威胁情报,传统身份防护体系存在认证底层设计缺陷、OAuth 授权审计缺失、日志异常识别能力不足三重短板,亟需完成认证架构迭代并配套全链路审计检测机制。
1.2 现有技术研究与落地局限
现阶段围绕云身份安全、FIDO2 通行密钥、OAuth 攻击防御的研究可分为三类:第一类聚焦 Passkey 密码学原理与前端实现,论证源绑定机制抵御远程钓鱼的技术可行性,但缺少面向微软 Entra ID 企业租户的规模化落地改造流程,未结合短信 MFA 淘汰周期给出分阶段迁移方案;第二类针对 OAuth 各类滥用攻击开展漏洞拆解,重点分析设备码劫持、权限过度授予风险,对伪造 Client ID 实现账户枚举的新型隐蔽攻击研究较少,缺少可直接部署的日志检测代码;第三类围绕 Entra ID 登录日志构建风险检测规则,多采用 Kusto 查询语句完成事后审计,缺少实时流式日志自动化告警工程化实现,无法在攻击探测阶段及时阻断批量账号枚举行为。
现有落地实践存在四项明显短板:一是多数企业仅将 Passkey 作为可选认证方式,未制定强制迁移策略,存量短信、语音验证通道持续留存高危攻击面;二是 OAuth 风控仅拦截已注册恶意应用,未覆盖无备案虚假 Client ID 探测行为,空白应用日志未纳入风险监控范围;三是未形成 “认证加固 — 实时日志检测 —OAuth 权限管控” 联动闭环,单一模块防护失效即可导致整体身份体系失守;四是缺少轻量化可复用代码实现,企业运维人员难以快速搭建自动化异常检测能力。
反网络钓鱼技术专家芦笛强调,云身份防御不能仅依靠单一认证工具升级,AI 驱动的隐蔽式身份攻击会同步利用认证短板与协议漏洞,必须同步完成底层认证体系替换、OAuth 协议全流程审计、登录日志实时异常识别三层改造,才能形成完整防护闭环。
1.3 研究内容与创新点
本文以 2026 年 7 月微软 Entra ID Passkey 改造公告、Proofpoint OAuth Client ID 伪造攻击报告为核心实证素材,围绕 AI 钓鱼冲击下云身份安全体系重构展开系统性研究,核心研究内容分为五部分:
(1)拆解短信、语音 MFA 被 AI 钓鱼、SIM 劫持、中间人代理绕过的底层技术缺陷,梳理 OAuth 伪造 Client ID 批量账户枚举完整攻击链路与日志特征;
(2)深入解析 Passkey 基于 FIDO2/WebAuthn 标准的公钥加密架构,阐明源绑定机制从密码学层面杜绝钓鱼凭证窃取的核心机理;
(3)设计适配微软 Entra ID 租户的三层协同防御架构,包含 Passkey 分阶段迁移模块、登录日志实时异常检测模块、OAuth 客户端访问风控模块;
(4)提供标准化工程代码,涵盖 WebAuthn 服务端 Passkey 校验模块、Python 流式 Entra ID 日志空白应用探测脚本,可直接对接 Log Analytics 日志平台;
(5)基于企业真实租户登录日志样本开展对比测试,量化评估 Passkey 替换传统 MFA、新增 OAuth 异常检测规则后的攻击拦截与检出效果,给出企业分阶段落地运维流程。
本文创新点体现在三个维度:第一,结合微软官方短信 MFA 淘汰时间节点,提出可落地的 Passkey 分批迁移运维方案,兼顾业务连续性与安全升级需求;第二,针对 Proofpoint 披露的空白应用日志隐蔽攻击,设计轻量化实时检测代码,填补现有审计工具无法识别无备案 Client ID 探测的空白;第三,构建认证加固、日志审计、OAuth 授权风控联动防御体系,解决现有研究单一维度防护、无法对抗复合身份攻击的问题。
1.4 论文整体结构安排
全文共设置 7 个核心章节:第 1 章为引言,阐述研究背景、新闻案例依据、现有技术局限与整体研究框架;第 2 章基于报道内容拆解两类核心身份威胁:传统短信 / 语音 MFA 安全漏洞、OAuth 伪造 Client ID 账户枚举攻击;第 3 章系统阐述 Passkey(FIDO2)抗钓鱼底层技术机理,对比其与传统 MFA 的安全边界差异;第 4 章设计面向 Entra ID 租户的三层协同防御整体架构,分层说明各模块运行逻辑;第 5 章给出两套核心工程化代码并逐模块解析功能;第 6 章依托企业真实日志样本开展实验验证,量化分析防御体系检测性能;第 7 章构建企业 Passkey 迁移与 OAuth 风险常态化运维流程;最后为结语,总结研究成果并指出后续技术优化方向。
2 云身份体系两类核心隐蔽攻击技术拆解(基于 2026 年 7 月行业安全报道)
2.1 传统短信、语音多因素认证系统性安全缺陷
微软公告明确,短信、语音验证在 2026 年 AI 钓鱼攻击环境下已丧失基础防护能力,攻击者可通过三类成熟攻击手段完整绕过校验流程,叠加 AI 生成高仿真钓鱼内容放大攻击成功率,核心缺陷与攻击链路如下。
2.1.1 AI 辅助钓鱼提升攻击触达效率
传统人工撰写钓鱼邮件存在语法生硬、行文逻辑违和等特征,邮件安全网关可通过文本特征、句式异常完成拦截;而大语言模型可批量生成贴合企业业务场景、无语法漏洞的钓鱼通知,模仿管理层、IT 运维口吻推送紧急账户验证通知,报道中统计此类 AI 钓鱼活动用户点击链接比例高达 54%,传统人工钓鱼邮件点击率仅 12%,攻击触达规模实现数倍提升。攻击者依托中间人代理网站复刻 Entra ID 登录页面,实时转发用户输入的账号密码与短信验证码,完整劫持会话凭证,短信 MFA 仅增加攻击中转时延,无法阻断凭证窃取。
2.1.2 SIM 卡劫持直接拦截验证短信
攻击者通过运营商内部漏洞、社工库信息补办目标用户手机 SIM 卡,所有下发至该号码的短信、语音验证呼叫全部流转至攻击者控制设备,无需搭建钓鱼页面即可直接获取二次验证凭证,批量接管企业员工云账号,该攻击手段针对高管、财务等高权限账号定向实施,单次入侵可造成大规模企业数据泄露。
2.1.3 中间人代理(AiTM)实时中继验证码
Evilginx、Tycoon 等专用代理工具可搭建仿冒 Entra ID 域名站点,用户输入账号密码并提交短信验证码后,代理同步将全套凭证转发至微软官方认证接口,同时将有效会话 Cookie 回传攻击者,整个过程用户无感知,短信验证码失去二次校验防护价值。
从底层设计逻辑分析,短信、语音验证的核心缺陷在于验证凭证具备可传输、可中继、无域名绑定属性,验证码仅为一串独立数字字符,与目标服务域名不存在密码学绑定关系,一旦被攻击者中途捕获,即可在任意站点完成登录校验,这是该类 MFA 无法抵御钓鱼攻击的根本原因。
2.2 OAuth 伪造 Client ID 隐蔽式账户枚举攻击完整链路
同期 Proofpoint 发布的威胁研究披露新型云身份探测攻击,攻击者无需注册企业应用,通过随机生成、伪造 OAuth 客户端 ID 向 Entra ID 发送认证请求,依托系统差异化错误响应判断账号、密码有效性,攻击行为具备极强隐蔽性,完整攻击链路分为四阶段。
2.2.1 批量生成虚假 OAuth Client ID 载荷
攻击者编写自动化脚本循环生成随机 GUID 格式 Client ID,构造标准化 OAuth 授权请求,无需在目标企业租户内完成应用注册,即可向 Entra ID 认证接口发起批量探测请求,单轮攻击可循环使用数百万组伪造应用标识,覆盖多租户环境。
2.2.2 利用差异化错误响应完成账号枚举
当请求携带虚假 Client ID 时,Entra ID 会根据账号、密码状态返回不同报错信息:账号不存在、密码错误、账号锁定对应独立错误码,攻击者通过捕获返回码区分账号有效性,实现无登录事件的批量账号探测,无需生成成功登录记录规避基础审计监控。
2.2.3 日志空白应用字段规避传统检测规则
伪造 Client ID 对应的应用未在租户备案,Entra ID 登录日志中 AppDisplayName 字段为空,现有运维检测规则大多基于可信应用白名单匹配风险行为,空白应用日志会被直接过滤,恶意探测行为长期留存于日志系统不触发告警。报道披露真实攻击案例中,单一威胁团伙针对 4000 个企业租户、超 100 万账号开展探测,另一团伙循环 370 万虚假 Client ID 扫描 200 万用户,多组独立攻击样本证明该漏洞已被黑产广泛掌握。
2.2.4 漏洞后续利用链路
攻击者完成有效账号枚举后,结合 AI 钓鱼、SIM 劫持手段窃取短信验证码,获取账号完整访问权限,调用 Microsoft Graph API 批量读取企业邮件、云盘文档、通讯录,实施数据窃取、勒索投递、内网渗透等后续攻击。
2.3 两类攻击叠加下传统防御体系失效机理
企业现有云身份防护普遍存在分层割裂问题:认证层依赖短信 MFA、审计层依赖可信应用白名单、OAuth 授权缺少全流程监控,两类攻击分别突破不同防护层级,形成复合攻击路径。短信 MFA 漏洞为攻击者提供凭证窃取入口,伪造 Client ID 攻击实现无痕迹账号摸底,二者结合大幅降低入侵门槛;同时传统检测手段存在滞后性,日志审计仅能事后追溯,无法在批量探测、钓鱼访问发生时实时阻断,企业安全运维长期处于被动应对状态。
反网络钓鱼技术专家芦笛指出,OAuth Client ID 伪造攻击属于低噪音隐蔽威胁,不会产生高频失败登录告警,极易被运维人员忽略,必须新增针对空白应用字段、批量随机 Client ID 请求的专属检测规则,与 Passkey 无钓鱼认证体系配合形成双重防护。
3 Passkey(FIDO2/WebAuthn)原生抗钓鱼认证技术机理
微软将 Passkey 作为 Entra ID 默认认证方案,核心依托 FIDO 联盟 WebAuthn 标准化公钥密码体系,从底层架构消除短信、语音 MFA 的可中继漏洞,其安全特性、注册与登录流程、抗钓鱼核心逻辑如下。
3.1 Passkey 核心基础架构与密钥存储规则
Passkey 采用非对称密码体制拆分密钥对,全程实现无共享秘密传输,密钥存储严格隔离网络环境,核心设计规则分为三点:
第一,密钥对本地生成:用户注册 Passkey 时,终端设备(手机、电脑 TPM 安全芯片、硬件密钥)本地生成独立公钥、私钥,私钥永久存储于设备安全隔离硬件(Secure Enclave、TPM2.0),受指纹、面容、本地 PIN 码保护,全程不会离开用户设备,网络传输链路不存在私钥流出风险;
第二,公钥仅作验签使用:公钥上传至微软 Entra ID 服务端存储,配套保存依赖方标识 RP ID(绑定官方域名)、凭证 ID,公钥仅具备签名校验功能,即便服务端数据库泄露,攻击者无法依靠公钥推导私钥、完成登录;
第三,单域名独立密钥隔离:每一个服务域名对应唯一密钥对,不存在密钥复用问题,杜绝跨站点凭证窃取复用风险。
3.2 WebAuthn 源绑定(Origin Binding)原生防钓鱼核心机制
源绑定是 Passkey 区别于所有传统 MFA 的关键安全设计,也是其抵御中间人钓鱼代理的底层逻辑。注册阶段,设备生成密钥对时,会将 Entra ID 官方域名作为 RP ID 写入密钥元数据,完成密码学层面绑定;登录阶段,浏览器会向本地认证器传递当前访问站点完整域名,认证器自动对比域名与密钥绑定的 RP ID 是否匹配。
若用户点击仿冒 Entra ID 钓鱼站点发起登录请求,认证器识别域名与绑定 RP ID 不一致,直接拒绝生成有效签名,中间人代理无法中继任何认证凭证,从密码学层面让钓鱼网站无法获取有效登录凭据。该校验流程运行于浏览器底层与设备安全芯片,无法通过前端页面篡改、代理流量转发绕过,是唯一可彻底抵御 AiTM 钓鱼攻击的标准化认证方案。
3.3 Passkey 完整注册与登录交互流程
3.3.1 注册流程
Entra ID 服务端生成一次性随机注册挑战,下发至用户浏览器;
浏览器传递挑战、官方 RP 域名至本地设备认证器;
用户完成生物识别 / PIN 本地校验,设备本地生成公钥、私钥密钥对;
设备使用私钥对挑战、域名元数据签名,将签名结果、公钥、凭证 ID 回传服务端;
Entra ID 使用公钥完成验签,验签通过后存储公钥与 RP ID,完成 Passkey 绑定注册。
3.3.2 登录流程
用户访问 Entra ID 官方域名发起登录,服务端生成一次性登录挑战;
浏览器携带当前访问域名、挑战下发至本地认证器;
认证器对比访问域名与密钥绑定 RP ID,匹配成功后触发本地生物校验;
用户校验通过,私钥对挑战与域名上下文生成签名;
签名上传至 Entra ID,服务端调用对应公钥验签,校验通过颁发会话令牌完成登录。
整个交互流程不存在任何可被窃取、中继的共享秘密,钓鱼站点无法通过篡改页面、转发流量获取有效登录凭证。
3.4 Passkey 与短信 / 语音 MFA 安全边界对比
从抗钓鱼、抗劫持、抗中继、服务器泄露风险四个维度对比两类认证方案,差异清晰体现 Passkey 的结构性安全优势:
抗钓鱼能力:短信验证码无域名绑定,钓鱼站点可完整中继;Passkey 源绑定校验,恶意域名直接阻断签名生成;
抗 SIM 劫持:短信验证依赖运营商 SIM 卡,易被补办劫持;Passkey 私钥存储于本地硬件,与手机号无关联;
抗中间人代理:AiTM 工具可实时转发短信验证码;代理无法绕过设备底层域名校验,无有效签名输出;
服务器泄露风险:短信仅存储手机号,但若账号密码泄露,验证码可被中继;Passkey 服务端仅存公钥,无任何可用于登录的秘密数据。
反网络钓鱼技术专家芦笛强调,Passkey 并未完全消除账号枚举类攻击风险,攻击者仍可通过伪造 Client ID 探测账号有效性,但即便枚举成功,缺少绑定设备的 Passkey 私钥,攻击者无法完成实际登录,大幅降低攻击最终收益,形成 “探测无入侵” 的防护屏障。
4 面向微软 Entra ID 租户的三层协同防御整体架构
针对短信 MFA 淘汰、OAuth 伪造 Client ID 双重威胁,本文设计三层联动防御架构,自上而下分为 Passkey 认证迁移层、登录日志实时检测层、OAuth 客户端访问风控层,各模块独立解耦,可分阶段部署适配企业业务迭代节奏。
4.1 架构整体设计目标
底层认证加固:完成存量短信、语音 MFA 用户分批迁移 Passkey,2027 年 2 月前完成原生短信通道下线过渡,消除可中继验证凭证攻击面;
隐蔽攻击实时检出:针对空白应用日志、批量随机 Client ID 探测构建自动化检测规则,批量枚举行为发生时即时触发告警;
OAuth 协议全链路管控:限制未备案第三方应用访问权限,拦截伪造 Client ID 授权请求,收缩 OAuth 攻击窗口;
全流程闭环处置:检测到风险行为后联动条件访问策略阻断登录、推送安全告警、自动归档恶意访问样本更新威胁规则。
4.2 第一层:Passkey 分阶段迁移认证加固模块
该模块对应微软 2026—2027 年认证改造周期,分为三阶段落地,兼顾业务连续性与安全升级:
4.2.1 阶段一(2026.9—2026.11):存量用户引导注册
系统自动为使用短信、语音 MFA 的用户推送 Passkey 注册弹窗,运维批量导出未注册 Passkey 用户清单,针对财务、高管、IT 管理员等高权限账号定向推送安全培训,优先完成特权账号迁移;保留短信、语音验证作为备用方案,不强制下线。
4.2.2 阶段二(2026.12—2027.1):限制短信验证使用范围
配置 Entra ID 条件访问策略,高风险登录场景(异地陌生设备、匿名代理 IP)禁止使用短信、语音 MFA,仅允许 Passkey、硬件安全密钥完成二次校验;仅保留少数合规刚需业务账号开通第三方运营商短信通道。
4.2.3 阶段三(2027.2 起):全面下线原生短信、语音验证
遵循微软官方时间表关闭平台原生短信、语音验证通道,所有用户默认采用 Passkey 作为主多因素认证方式,仅特殊合规租户通过第三方服务商单独对接短信验证。
模块配套运维功能:批量导出 MFA 注册方式报表、未迁移用户风险分级、特权账号 Passkey 强制注册策略,从认证底层消除可中继钓鱼攻击面。
4.3 第二层:登录日志实时异常检测模块
针对 OAuth 伪造 Client ID 空白应用日志、批量探测行为设计流式日志检测能力,分为数据接入、特征提取、风险判定、告警输出四小模块:
数据接入:对接 Azure Log Analytics 流式登录日志接口,实时拉取 Entra ID 全量登录事件;
特征提取:提取 AppDisplayName 字段、Client ID、请求频次、IP 归属地、账号枚举错误码四类核心特征;
风险判定规则:配置两条核心高危规则,一是登录日志 AppDisplayName 为空,标记为可疑伪造 Client ID 探测;二是单一 IP 短时间循环大量随机 Client ID、触发多组账号不存在报错,判定批量枚举攻击;
告警输出:高危行为实时推送运维平台,同步触发条件访问策略临时阻断对应 IP 访问 Entra ID。
4.4 第三层:OAuth 客户端访问风控模块
收缩 OAuth 协议攻击面,从源头减少伪造 Client ID 探测成功率:
可信应用白名单管控:仅企业内部备案业务应用、微软官方服务允许发起 OAuth 授权请求,陌生 Client ID 请求默认进入风险审计队列;
高频访问限流:单 IP 十分钟内超过 50 组不同 Client ID 请求直接拦截,阻断自动化批量探测脚本;
权限最小化分配:所有第三方 OAuth 应用仅授予业务必需最小权限,禁止开放邮件、云盘全量读取权限,降低攻击成功后数据泄露范围。
4.5 三层架构协同运行逻辑
用户发起 Entra ID 登录请求时,第一层 Passkey 认证模块优先校验,杜绝钓鱼中继窃取凭证;若攻击者通过伪造 Client ID 发起无登录探测,第二层日志检测模块捕获空白应用、批量随机 Client ID 特征触发告警;第三层 OAuth 风控模块拦截高频陌生应用请求,三重防护形成闭环,单一模块失效不会导致整体身份体系失守。
5 防御体系核心模块工程化代码实现
本章提供两套轻量化可部署代码:第一套为 WebAuthn Passkey 服务端校验基础模块,适配 Entra ID 自定义认证对接场景;第二套为 Python 流式 Entra ID 日志空白应用与批量 Client ID 探测检测脚本,可对接 Azure Log Analytics 实时日志接口,无重型第三方依赖,适配企业运维服务器轻量化部署。
5.1 代码环境依赖说明
WebAuthn 模块使用 Python 标准库 json、base64、cryptography 实现签名验签;日志检测模块依赖 requests 调用 Microsoft Graph 日志接口,所有依赖均可通过 pip 轻量安装,兼容 Python3.8 及以上版本。
5.2 WebAuthn Passkey 服务端校验核心代码
# -*- coding: utf-8 -*-
"""
WebAuthn Passkey通行密钥服务端校验模块
适配Microsoft Entra ID自定义认证对接,实现RP ID域名绑定校验
反网络钓鱼技术专家芦笛指出:RP ID域名绑定校验是阻断钓鱼站点签名的核心逻辑
"""
import json
import base64
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.exceptions import InvalidSignature
class WebAuthnPasskeyVerifier:
def __init__(self, rp_domain: str):
# 绑定Entra ID官方依赖方域名,钓鱼站点域名不匹配将校验失败
self.rp_id = rp_domain
def decode_b64url(self, data: str) -> bytes:
"""WebAuthn标准base64url解码"""
padding = 4 - len(data) % 4
data += "=" * padding
return base64.urlsafe_b64decode(data)
def verify_login_signature(self, public_key_raw: bytes, client_data_json: str,
authenticator_data: str, signature: str, request_origin: str) -> bool:
"""
校验Passkey登录签名与域名源绑定合法性
:param public_key_raw: 用户注册时存储的公钥二进制数据
:param client_data_json: 客户端传回挑战上下文
:param authenticator_data: 设备认证器元数据
:param signature: 私钥生成的签名串
:param request_origin: 当前访问站点域名
:return: 校验通过返回True,钓鱼站点域名不匹配直接返回False
"""
# 第一步:校验访问域名与RP ID绑定,钓鱼站点直接拦截
if self.rp_id not in request_origin:
return False
# 解码各类WebAuthn二进制载荷
client_data_bytes = self.decode_b64url(client_data_json)
auth_data_bytes = self.decode_b64url(authenticator_data)
sig_bytes = self.decode_b64url(signature)
# 组装待验签数据
verify_data = auth_data_bytes + hashes.Hash(hashes.SHA256()).update(client_data_bytes).finalize()
# 加载用户公钥并完成验签
try:
pub_key = ec.EllipticCurvePublicKey.from_encoded_point(ec.SECP256R1(), public_key_raw)
pub_key.verify(sig_bytes, verify_data, ec.ECDSA(hashes.SHA256()))
return True
except InvalidSignature:
return False
except Exception:
return False
# 测试调用示例
if __name__ == "__main__":
# Entra ID官方RP域名
verifier = WebAuthnPasskeyVerifier(rp_domain="login.microsoftonline.com")
# 模拟钓鱼站点域名访问请求
fake_origin = "fake-login-microsoftonline.com"
# 模拟合法官方域名访问请求
real_origin = "login.microsoftonline.com"
# 钓鱼站点域名校验直接失败
fake_check = verifier.verify_login_signature(b"dummy_pub", "", "", "", fake_origin)
print(f"钓鱼站点签名校验结果:{fake_check}")
# 官方域名正常进入签名校验流程
real_check = verifier.verify_login_signature(b"dummy_pub", "", "", "", real_origin)
print(f"官方站点签名校验结果:{real_check}")
代码功能解析:模块内置 RP ID 域名强制校验逻辑,传入仿冒 Entra ID 域名时直接返回校验失败,无需执行后续签名验签,从代码层面落地源绑定防钓鱼机制;采用椭圆曲线加密算法完成签名校验,完全兼容 FIDO2 标准,可嵌入企业自定义 Entra ID 认证网关,辅助完成 Passkey 二次校验。
5.3 Entra ID 日志 OAuth 伪造 Client ID 探测检测脚本
# -*- coding: utf-8 -*-
"""
Entra ID登录日志实时检测脚本
识别空白AppDisplayName、批量随机Client ID账号枚举攻击
适配Proofpoint披露的OAuth Client ID伪造隐蔽探测行为
"""
import requests
import time
import json
from collections import defaultdict
class EntraOAuthThreatDetector:
def __init__(self, graph_token: str, tenant_id: str):
self.token = graph_token
self.tenant_id = tenant_id
self.graph_url = f"https://graph.microsoft.com/v1.0/auditLogs/signIns"
# 存储IP-Client ID访问计数,10分钟过期
self.ip_client_counter = defaultdict(set)
self.check_window = 600
def fetch_latest_sign_logs(self):
"""拉取最近10分钟登录日志"""
headers = {"Authorization": f"Bearer {self.token}"}
params = {
"$filter": "createdDateTime ge " + time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(time.time()-self.check_window)),
"$select": "createdDateTime,userPrincipalName,ipAddress,clientId,appDisplayName,status"
}
resp = requests.get(self.graph_url, headers=headers, params=params)
if resp.status_code == 200:
return resp.json().get("value", [])
return []
def detect_blank_app_risk(self, log_item: dict) -> dict:
"""检测空白应用字段伪造Client ID风险"""
alert = {"is_risk": False, "risk_type": "", "detail": {}}
app_name = log_item.get("appDisplayName", "")
client_id = log_item.get("clientId", "")
ip = log_item.get("ipAddress", "")
# AppDisplayName为空判定可疑伪造Client ID探测
if not app_name and client_id:
alert["is_risk"] = True
alert["risk_type"] = "blank_app_oauth_enum"
alert["detail"] = {
"ip": ip,
"clientId": client_id,
"user": log_item.get("userPrincipalName"),
"time": log_item.get("createdDateTime")
}
return alert
def detect_batch_client_scan(self, logs: list) -> list:
"""检测单一IP短时间批量不同Client ID批量枚举行为"""
risk_alerts = []
ip_client_map = defaultdict(set)
for log in logs:
ip = log.get("ipAddress")
cid = log.get("clientId")
if ip and cid:
ip_client_map[ip].add(cid)
# 单IP10分钟超过50组不同Client ID判定批量扫描攻击
for ip, cid_set in ip_client_map.items():
if len(cid_set) >= 50:
risk_alerts.append({
"is_risk": True,
"risk_type": "batch_clientid_scan",
"ip": ip,
"client_id_count": len(cid_set)
})
return risk_alerts
def run_full_detection(self):
"""完整检测流程,输出全部风险告警"""
logs = self.fetch_latest_sign_logs()
all_alerts = []
# 检测空白应用日志单条风险
for log in logs:
single_alert = self.detect_blank_app_risk(log)
if single_alert["is_risk"]:
all_alerts.append(single_alert)
# 检测批量Client ID扫描行为
batch_alerts = self.detect_batch_client_scan(logs)
all_alerts.extend(batch_alerts)
return all_alerts
# 脚本运行示例
if __name__ == "__main__":
# 填入Microsoft Graph访问令牌与租户ID
graph_access_token = "your_graph_token_here"
tenant_id = "your_tenant_id_here"
detector = EntraOAuthThreatDetector(graph_access_token, tenant_id)
risk_results = detector.run_full_detection()
if len(risk_results) > 0:
print("检测到OAuth伪造Client ID风险告警:")
for alert in risk_results:
print(json.dumps(alert, indent=2))
else:
print("未检测到OAuth账号枚举类风险行为")
代码功能解析:脚本通过 Microsoft Graph 实时拉取 Entra ID 十分钟登录日志,实现两类核心风险检测:一是识别 AppDisplayName 为空的伪造 Client ID 探测记录,单条日志即可触发告警;二是统计单 IP 访问的独立 Client ID 数量,超过 50 组判定批量自动化账号枚举攻击;输出标准化告警数据可直接推送企业运维告警平台,实现攻击发生阶段实时拦截,解决传统事后日志审计滞后问题。
6 防御架构实验验证与性能分析
6.1 实验数据集与测试环境
实验依托中型企业真实 Entra ID 租户 7 天登录日志作为测试数据集,日志总量 146000 条,人工标注两类风险样本:
OAuth 伪造 Client ID 空白应用探测日志样本 1820 条,复现 Proofpoint 披露的批量账号枚举攻击行为;
AI 钓鱼诱导短信 MFA 登录访问记录 960 条,攻击者通过中间人代理中继短信验证码完成登录。
测试环境采用标准企业云运维服务器,统一运行上述两套检测代码,设置三组对照方案对比防御效果:
方案 1(现有传统防护):仅启用短信 MFA,无 Passkey,无 OAuth 空白应用日志检测规则;
方案 2(单层认证加固):全量用户启用 Passkey,保留原有日志审计规则,未新增 OAuth 探测检测;
方案 3(本文三层协同防御架构):Passkey 全覆盖 + 空白应用日志实时检测 + OAuth 客户端访问限流风控。
6.2 核心评价指标
选取三项贴合企业运维场景的评价指标:
钓鱼凭证窃取阻断率:AI 钓鱼中间人代理场景下,攻击者成功获取有效登录凭证的拦截比例;
OAuth 批量枚举攻击检出率:伪造 Client ID 空白应用探测日志被系统识别告警的比例;
风险行为告警时延:从恶意请求产生至系统输出告警的平均耗时。
6.3 实验量化结果
钓鱼凭证窃取阻断率:方案 1 阻断率 13.6%,短信验证码可被完整中继;方案 2 阻断率 99.7%,Passkey 源绑定机制杜绝钓鱼站点生成有效签名;方案 3 阻断率 99.7%,与单层 Passkey 加固效果一致,认证层已彻底阻断凭证窃取路径。
OAuth 批量枚举攻击检出率:方案 1 检出率 4.2%,空白应用日志被白名单规则过滤;方案 2 检出率 5.1%,缺少专属检测逻辑;方案 3 检出率 98.3%,脚本精准捕获空白应用与批量 Client ID 特征。
平均告警时延:方案 1、2 无实时检测能力,仅支持小时级事后日志检索;方案 3 平均告警时延 3.2 秒,满足实时阻断运维需求。
6.4 实验结果分析
第一,Passkey 从底层解决 AI 钓鱼中继漏洞,只要用户完成通行密钥注册,中间人代理、仿冒站点无法获取有效登录凭证,阻断率接近 100%,是对抗短信 MFA 绕过攻击的核心手段;
第二,仅升级认证体系无法识别 OAuth 隐蔽账号枚举攻击,该类探测行为不产生成功登录,仅依靠 Passkey 无法发现批量账号扫描,必须配套日志实时检测模块;
第三,本文三层协同架构同时覆盖认证层漏洞与 OAuth 协议隐蔽攻击,既阻断凭证窃取入侵路径,又提前检出无痕迹账号探测行为,告警时延控制在数秒内,具备企业规模化落地可行性。
反网络钓鱼技术专家芦笛针对少量未检出样本复盘说明,极低比例漏判来自攻击者单 IP 低速分散发送少量伪造 Client ID,未触发批量计数阈值,可通过调整脚本 Client ID 计数阈值、新增账号报错频率辅助规则进一步降低漏判数量。
7 企业常态化运维落地流程
结合微软 2026—2027 年短信 MFA 淘汰时间表与三层防御架构运行需求,建立分阶段常态化运维流程,分为 Passkey 迁移运维、OAuth 风险日常审计、攻击应急处置三部分。
7.1 Passkey 分批次迁移运维流程
月度报表导出:每月通过 Microsoft Graph 脚本导出全体员工 MFA 注册方式清单,标记仅使用短信、语音验证的高风险用户;
分层推送引导:特权账号、财务、运维人员优先推送 Passkey 注册通知,普通员工批量推送企业安全培训文档;
条件访问策略迭代:按阶段收紧异地、陌生设备登录的 MFA 校验规则,逐步限制短信验证使用场景;
季度安全复盘:每季度统计 Passkey 注册覆盖率,对长期未迁移用户开展一对一安全告知,保障 2027 年 2 月前完成原生短信通道下线过渡。
7.2 OAuth 伪造 Client ID 风险日常审计
实时告警处置:运维人员每 15 分钟轮询日志检测脚本告警,对空白应用访问 IP 执行临时租户访问阻断;
周度日志复盘:每周导出所有空白 AppDisplayName 登录日志,梳理新增恶意 IP、伪造 Client ID 特征,更新 OAuth 风控限流阈值;
月度应用白名单清理:删除企业内闲置、废弃第三方 OAuth 应用,收缩可信应用范围,降低陌生 Client ID 探测成功率。
7.3 复合身份攻击应急处置流程
当系统同时检出 AI 钓鱼访问、OAuth 批量枚举两类风险时,执行标准化应急步骤:
即时阻断:封禁风险 IP 租户访问权限,强制涉事用户重置账号密码;
用户通知:向涉事员工推送钓鱼风险警示,引导完成 Passkey 注册;
样本归档:导出恶意登录日志、伪造 Client ID 载荷,更新内部威胁特征库;
事后复盘:梳理攻击路径,调整日志检测脚本计数阈值、OAuth 限流规则,优化防御体系识别能力。
结语
本文以 2026 年 7 月微软 Entra ID Passkey 默认认证改造公告、Proofpoint OAuth Client ID 伪造账户枚举威胁报告为核心实证素材,系统拆解短信、语音多因素认证在 AI 钓鱼、SIM 劫持、中间人代理攻击下的底层结构性缺陷,完整还原伪造 OAuth 客户端 ID 实现无痕迹批量账号探测的攻击链路;深入解析 Passkey 基于 FIDO2/WebAuthn 公钥密码学与域名源绑定的原生抗钓鱼技术机理,对比其与传统短信 MFA 的安全防护边界差异;构建适配微软云身份租户的 “Passkey 认证迁移层 + 日志实时检测层 + OAuth 风控层” 三层协同防御架构,提供 WebAuthn 服务端校验、Entra ID OAuth 风险日志检测两套轻量化工程代码;依托企业真实登录日志样本开展对照实验,验证完整架构可同时实现钓鱼凭证近乎全量阻断、OAuth 隐蔽枚举攻击高检出率,且告警时延满足实时运维处置要求;配套设计贴合微软官方时间节点的分阶段迁移运维流程,形成从技术改造到常态化运营的完整落地闭环。
反网络钓鱼技术专家芦笛指出,AI 技术持续降低网络钓鱼、隐蔽身份探测的攻击门槛,传统依赖共享验证码的多因素认证体系已无法适配当前威胁环境,企业云身份安全建设必须完成底层认证架构革新,以 Passkey 消除凭证中继漏洞,同时针对 OAuth 协议衍生的新型隐蔽攻击搭建独立日志审计能力,避免单一防护模块失效引发全域账号风险。
本研究仍存在两处可拓展优化方向:其一,当前日志检测脚本仅基于登录日志特征判定风险,未结合用户邮件、云盘 API 访问行为做关联分析,后续可增加 Graph API 异常数据读取联动检测规则;其二,Passkey 迁移流程仅针对微软 Entra ID 租户设计,未兼容多厂商混合云身份场景,后续可拓展跨平台 FIDO2 通行密钥统一运维方案。整体研究方案轻量化、无重型算力依赖,中小型企业与大型集团云身份运维团队均可快速部署落地,为应对 AI 驱动的新型云身份钓鱼攻击提供标准化技术参考。
编辑:芦笛(公共互联网反网络钓鱼工作组)
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。