你有没有收到过这样的邮件?
“您的 Microsoft 账户需要立即完成安全验证。请访问 https://aka.ms/devicelogin,输入以下代码:**ABCD-EFGH**。”
看起来再正常不过——链接指向微软官方域名,页面是熟悉的蓝色登录界面,连验证码格式都和手机短信一模一样。但就在你输入那串看似无害的字母数字组合、点击“下一步”的瞬间,你的企业邮箱、OneDrive 文件、Teams 会议记录,甚至整个 Azure AD 权限,可能已经落入黑客手中。
这不是科幻剧情,而是正在全球蔓延的真实攻击。网络安全公司 Proofpoint 近日披露,一种利用 Microsoft OAuth 2.0 设备授权流程(Device Code Flow) 的新型钓鱼手法正大规模针对 Microsoft 365 企业用户。与传统钓鱼依赖伪造登录页不同,此次攻击全程使用 真实的微软认证界面,绕过绝大多数安全培训与技术防护,堪称“合法外衣下的权限劫持”。
更令人不安的是,这种攻击对多因素认证(MFA)几乎免疫——即使你启用了短信或 Authenticator 验证,只要在微软官网输入了那串“设备代码”,攻击者就能绕过所有防线,直接获取访问令牌(Access Token),实现“无密码接管”。
“这是一场精心设计的信任滥用。”公共互联网反网络钓鱼工作组技术专家芦笛在接受本报专访时直言,“攻击者没有破解系统,而是利用了系统本身的设计逻辑,把‘便利性’变成了‘致命漏洞’。”
一、骗局拆解:从一封“安全提醒”到企业数据沦陷
整个攻击始于一条精心编排的信息。
受害者通常会收到来自看似内部IT部门、微软支持团队,甚至是合作方的邮件或 Teams 消息,内容大同小异:
“检测到您的账户存在异常活动,请立即完成设备验证以防止服务中断。”
“为配合系统升级,请在5分钟内完成身份确认。”
“您的 OneDrive 存储即将锁定,请验证设备以继续使用。”
消息中附带一个标准微软短链:**https://aka.ms/devicelogin**(真实有效的微软设备登录入口),并提供一组8位字母数字混合的“设备代码”,例如 XK92-MPQ7。
用户点击链接后,跳转至 完全真实的微软登录页面(域名:login.microsoftonline.com)。页面提示:“在另一台设备上使用此代码登录”,并要求输入代码。一切看起来合规、安全、无可挑剔。
一旦用户输入代码并点击“下一步”,系统会要求其使用 Microsoft 365 账户登录——此时 MFA 可能被触发,用户收到短信或 Authenticator 推送通知,并完成验证。
关键就在这里:用户以为自己是在“验证自己的设备”,实际上是在为攻击者的恶意应用授权。
“设备代码流程本意是方便智能电视、打印机等无浏览器设备登录云服务。”芦笛解释道,“但攻击者注册了一个伪装成‘Microsoft Security Scanner’或‘Enterprise Compliance Tool’的 OAuth 应用,通过 Azure AD 注册后,向微软请求设备代码。当用户在官网输入该代码并授权,就等于亲手把权限交给了这个恶意应用。”
授权完成后,攻击者的服务器立即通过 OAuth 2.0 的 /token 端点兑换访问令牌和刷新令牌(Refresh Token),从而获得对受害者邮箱、日历、文件等资源的长期访问权——全程无需知道密码,也不触发异常登录警报。
Proofpoint 报告显示,此次攻击已波及金融、制造、物流等多个行业,部分企业因未及时发现,导致内部邮件被窃取、供应链信息泄露,甚至被用于二次钓鱼攻击合作伙伴。
二、技术深潜:OAuth 设备授权流为何成了“后门”?
要理解这场危机,必须回到 OAuth 2.0 协议本身。
OAuth 是现代互联网身份授权的事实标准。它允许第三方应用在不获取用户密码的前提下,访问用户在其他服务(如 Google、Microsoft)上的资源。其中,“设备授权流”(Device Authorization Grant)是专为输入受限设备(如 IoT 设备、命令行工具)设计的一种授权方式。
其标准流程如下(RFC 8628):
客户端(Client) 向授权服务器(如 Azure AD)请求设备代码;
POST /devicecode HTTP/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
client_id=YOUR_APP_ID&scope=https://graph.microsoft.com/.default
服务器返回 device_code 和 user_code(即用户看到的 ABCD-EFGH);
用户在另一台设备访问 https://aka.ms/devicelogin,输入 user_code;
用户登录并授权该应用;
客户端轮询 /token 端点,一旦用户授权,立即获取 Access Token。
问题在于:步骤4中的授权页面由微软官方提供,用户无法分辨背后的应用是否可信。
“普通用户看到的是微软的 UI,但授权的对象却是攻击者注册的 OAuth 应用。”芦笛指出,“Azure AD 默认允许任何注册应用发起设备代码请求,而企业管理员往往不知道这一功能的存在,更未限制其使用范围。”
更危险的是,一旦获得 Refresh Token,攻击者可长期维持访问,即使用户更改密码也无效——因为 OAuth 令牌独立于密码体系。
代码示例:攻击者如何自动化整个流程
以下是攻击者服务器端的核心逻辑(Python + requests):
import requests
import time
# 1. 向 Azure AD 请求设备代码
client_id = "ATTACKER_APP_ID" # 攻击者注册的恶意应用ID
scope = "https://graph.microsoft.com/.default"
resp = requests.post(
"https://login.microsoftonline.com/common/oauth2/v2.0/devicecode",
data={
"client_id": client_id,
"scope": scope
}
)
device_data = resp.json()
print(f"设备代码: {device_data['user_code']}")
print(f"请访问: {device_data['verification_uri']}")
# 2. 轮询令牌(每5秒一次)
while True:
token_resp = requests.post(
"https://login.microsoftonline.com/common/oauth2/v2.0/token",
data={
"grant_type": "urn:ietf:params:oauth:grant-type:device_code",
"client_id": client_id,
"device_code": device_data["device_code"]
}
)
if token_resp.status_code == 200:
tokens = token_resp.json()
print("✅ 成功获取令牌!")
print("Access Token:", tokens["access_token"][:50] + "...")
print("Refresh Token:", tokens["refresh_token"][:50] + "...")
# 此时可调用 Microsoft Graph API 窃取数据
break
elif token_resp.json().get("error") == "authorization_pending":
time.sleep(5)
else:
print("❌ 授权失败:", token_resp.text)
break
一旦拿到 access_token,攻击者即可调用 Microsoft Graph API 执行任意操作:
# 示例:读取受害者最近10封邮件
headers = {"Authorization": f"Bearer {access_token}"}
mails = requests.get(
"https://graph.microsoft.com/v1.0/me/messages?$top=10",
headers=headers
).json()
for mail in mails["value"]:
print(f"主题: {mail['subject']}, 发件人: {mail['from']['emailAddress']['address']}")
“整个过程完全合法,使用的是微软公开的 API。”芦笛强调,“区别只在于:用户以为自己在授权‘安全扫描工具’,实际授权的是‘数据窃取机器人’。”
三、防御盲区:为什么MFA也挡不住?
多因素认证(MFA)曾被视为钓鱼防御的“金钟罩”。但在设备代码钓鱼面前,它却显得力不从心。
原因很简单:MFA 验证的是“用户身份”,而非“授权对象”。
当用户在微软官网完成 MFA 验证后,系统认为“这是本人操作”,于是放心地将权限授予请求的应用。而用户根本看不到应用名称——除非仔细点击“查看详细信息”,否则默认只显示“此应用请求访问您的数据”。
“大多数人在赶时间,根本不会点开看。”芦笛说,“更何况,攻击者会把应用名起得极具迷惑性,比如 ‘Microsoft 365 Compliance Checker’ 或 ‘Azure Secure Access Agent’。”
更隐蔽的是,攻击者可申请最小必要权限(如仅 Mail.Read),避免触发高风险权限警报。而企业若未启用 条件访问(Conditional Access) 策略,这类低权限授权几乎不会被审计系统标记。
Proofpoint 发现,部分攻击甚至持续数周未被发现——因为所有操作都通过合法 API 进行,IP 地址来自正常办公区域(攻击者使用代理或已控跳板机),行为模式与日常办公高度相似。
四、企业自救指南:三步堵住“合法后门”
面对如此高阶的攻击,企业不能坐以待毙。芦笛与安全社区共同提出以下防御策略:
1. 禁用不必要的设备代码授权
在 Azure AD 中,默认所有租户都启用了设备代码流。管理员应评估是否真的需要此功能(如无 IoT 设备集成需求),若否,则全局禁用。
操作路径:Azure Portal → Azure Active Directory → 企业应用 → 常规设置 → 关闭“设备代码流”。
2. 实施严格的 OAuth 应用审批策略
启用“用户无法注册应用”策略,并要求所有第三方应用必须经 IT 部门审批。
PowerShell 命令示例:
Set-MsolCompanySettings -UsersPermissionToCreateAppsEnabled $false
3. 部署条件访问(Conditional Access)策略
限制高风险操作(如令牌颁发)仅允许从受信任设备、网络或地理位置发起。
推荐策略:
对包含 offline_access(即请求 Refresh Token)的授权请求强制执行 MFA;
阻止从未知国家/地区的登录尝试;
对非托管设备(如个人手机)限制访问敏感数据。
4. 监控异常 OAuth 授权行为
使用 Microsoft Defender for Cloud Apps 或第三方 SIEM 工具,设置告警规则,例如:
单个用户短时间内授权多个新应用;
应用请求权限与其业务场景不符(如 HR 系统请求 Mail.Send);
Refresh Token 被频繁用于获取新 Access Token。
5. 开展针对性安全意识培训
传统“别点陌生链接”已不够。必须教育员工:
任何要求你访问 aka.ms/devicelogin 的请求都需先联系 IT 确认;
授权前务必点击“查看此应用将访问哪些数据”;
若未主动发起设备登录,绝不要输入任何代码。
“安全不是一道墙,而是一套动态响应机制。”芦笛总结道,“企业必须从‘被动防御’转向‘主动狩猎’。”
五、行业反思:便利与安全的天平该如何摆?
设备代码钓鱼的流行,暴露出一个深层矛盾:现代身份协议在追求用户体验的同时,是否牺牲了安全可见性?
OAuth 的设计哲学是“委托授权”,但普通用户并不理解“授权”与“登录”的区别。他们看到微软界面,就默认安全;输入代码,就以为在“验证自己”。而平台并未提供足够清晰的风险提示。
“微软其实可以做得更好。”芦笛建议,“例如,在设备代码授权页面强制显示应用名称、开发者信息、请求权限列表,并用红色高亮‘此操作将授予第三方长期访问权限’。”
事实上,Google 已在其 OAuth 流程中引入更严格的审查机制,对高风险应用进行人工审核。而 Microsoft 目前仍以“自助注册”为主,门槛极低。
“开放生态需要护栏,而不是放任。”芦笛说,“否则,每一次‘提升体验’的更新,都可能成为攻击者的跳板。”
结语
在这场没有硝烟的战争中,黑客不再需要破解密码,只需利用人性的惯性与系统的信任。设备代码钓鱼之所以可怕,正因为它披着“合法”的外衣,行“越权”之实。
对企业而言,真正的安全不是堆砌工具,而是建立“零信任”思维——永不假设内部请求就是安全的,永不认为官方界面就代表无害。
毕竟,在数字世界里,最危险的指令,往往来自你最信任的页面。
(本文技术细节参考 Proofpoint 研究报告及 Microsoft 官方文档,OAuth 流程符合 RFC 8628 标准)
相关阅读:
Proofpoint 原文:Microsoft 365 Device Code Phishing
Microsoft OAuth 2.0 Device Code Flow 文档
Azure AD 条件访问最佳实践
编辑:芦笛(公共互联网反网络钓鱼工作组)