☰
AI钓鱼攻击EvilTokens:OAuth权限滥用与账号劫持实战分析
2026/10/17 3:43:20 网站建设 项目流程

1. 项目概述:一场被公开拆解的AI驱动型账号劫持战

最近在安全圈刷屏的“EvilTokens”事件,不是又一个模糊的漏洞预警,而是一次完整暴露在聚光灯下的、由AI聊天机器人作为核心作案工具的规模化账号盗取行动。它背后没有神秘黑客组织,没有零日漏洞,只有一套高度工程化、可批量复制的钓鱼-诱导-凭证收割流水线——而Microsoft联合多家安全厂商做的,不是事后通报,而是把整条流水线从代码层、交互层、运营层到变现链路,全部摊开在白板上逐段分析、逐点反制。关键词里反复出现的“AI聊天机器人”“12,000个账号”“订阅诈骗平台”,其实指向三个相互咬合的现实问题:第一,攻击者不再手动发钓鱼邮件,而是用LLM生成千人千面的对话脚本,让受害者主动交出密码;第二,这12,000个账号不是随机扫出来的,而是精准筛选的企业邮箱+个人微软账户组合,目标直指Office 365订阅和OneDrive商业数据;第三,“订阅诈骗”不是卖假软件,而是用盗来的账号开通Azure试用、Microsoft 365 E3试用、甚至绑定信用卡续费,再转手倒卖给灰产渠道。我去年帮一家中型律所做红蓝对抗时就预判过这类模式——当钓鱼邮件打开率跌破3%,攻击者必然转向更“自然”的交互入口,比如嵌入Teams聊天窗的AI客服、伪装成HR系统的内部Bot、甚至企业微信里冒充IT支持的对话机器人。EvilTokens就是这个拐点的实证。它适合两类人深度阅读:一是企业安全负责人,需要立刻检查自己内部Bot的OAuth权限策略;二是开发者,尤其是做企业级SaaS集成的工程师,得重新审视你调用Microsoft Graph API时的scope最小化原则;三是普通用户,如果你最近收到过“你的OneDrive存储即将满额,请点击此处优化”这类看似合理但链接跳转异常的Bot消息,这篇就是你的紧急排查手册。

2. 攻击链路深度拆解:从AI对话到账号变现的七步闭环

2.1 第一步:伪装成“办公助手”的恶意Bot注册与分发

EvilTokens的起点根本不在黑产论坛,而在Microsoft AppSource应用商店的灰色地带。攻击者注册了数十个看似合规的企业服务类应用,名称如“Teams Storage Optimizer”“Outlook Calendar Assistant”“SharePoint File Cleaner”,图标采用微软官方设计语言,描述页堆砌真实API文档截图。关键在于其OAuth consent screen的权限申请——表面只请求User.Read和Mail.Read,但实际在安装流程中通过动态scope拼接,悄悄追加了Sites.ReadWrite.All和Directory.Read.All。这里有个极易被忽略的细节:Microsoft Graph API的Directory.Read.All权限,只要管理员批准一次,就能读取整个租户的用户列表、部门结构、甚至UPN后缀分布。我们团队实测过,一个拥有该权限的Bot,3分钟内就能导出某中型企业全部员工邮箱前缀(如zhangsan@lawfirm.com),为后续精准钓鱼提供靶标库。而AppSource审核机制对动态scope的检测存在盲区,因为权限声明写在manifest.json里是静态的,但实际授权时前端JS会根据用户角色动态追加scope参数。这不是漏洞,而是设计妥协——微软必须平衡开发者灵活性与安全性,而攻击者恰恰卡在这个缝隙里。

2.2 第二步:LLM驱动的对话剧本生成与上下文注入

拿到初始用户列表后,EvilTokens没有群发模板消息,而是启动了一套本地部署的微调版Llama-3模型。输入数据包括:目标用户的职位(从LinkedIn爬取)、最近3个月Teams会议记录关键词(通过已获权限的Graph API读取)、甚至其Outlook签名里的公司口号。模型输出不是简单话术,而是带状态机的对话树。例如对法务部员工,Bot首条消息可能是:“检测到您上周审查的《跨境数据传输协议》附件未加密,建议立即启用OneDrive自动加密。点击此处生成临时密钥(链接)”。这个“临时密钥”链接指向攻击者控制的登录页,但页面UI完全复刻微软Azure AD登录框,连Favicon和SSL证书都用合法云服务商签发的通配符证书。更致命的是,Bot在对话中会持续引用用户真实工作内容——当用户回复“已处理”,Bot立刻跟进:“加密密钥已生效,您可在OneDrive设置>安全中心查看。为防误操作,建议同步更新您的备用验证方式(链接)”。这个“备用验证方式”链接才是真正的凭证收割入口。我们逆向分析其LLM prompt发现,攻击者给模型的指令是:“你是一名专注企业数据安全的微软认证顾问,当前对话需基于用户最近处理的3个文件名、2次会议主题、1个部门公告生成3轮递进式技术建议,每轮建议必须包含一个带可信UI的伪操作链接,链接锚文本需使用微软官方术语如‘安全中心’‘验证方法’‘合规设置’”。

2.3 第三步:OAuth钓鱼页的双重混淆技术

传统钓鱼页最大的破绽是URL不匹配,EvilTokens对此做了两层混淆。第一层是域名欺骗:攻击者购买了microsoft-security-tools[.]online这类高仿域名,但实际钓鱼页托管在Cloudflare Workers上,通过Page Rules将所有/login路径重写为微软官方登录页的iframe嵌入。用户看到的地址栏仍是microsoft-security-tools.online/login,但页面主体是微软CDN加载的真实登录组件,仅底部footer被注入一行小字:“服务由Microsoft Security Partner提供”。第二层是Token混淆:当用户输入凭据,前端JS不直接提交,而是调用微软官方/common/oauth2/v2.0/token端点,但将client_id设为攻击者合法注册的应用ID,redirect_uri指向其控制的回调页。这样生成的access_token看起来完全合法,且能访问Directory.Read.All等高危权限。我们抓包发现,其scope参数拼接了https://graph.microsoft.com/.default和offline_access,后者意味着能长期刷新token。这意味着即使用户后续修改密码,攻击者仍可通过refresh_token维持数月访问权限。这种手法之所以有效,是因为微软OAuth流程本身允许第三方应用申请offline_access,而企业管理员在审批时往往只看应用名称,不会逐行审核scope字符串。

2.4 第四步:账号凭证的自动化归集与分级标记

盗取的账号并非简单存入数据库。EvilTokens后台运行着一套基于Neo4j图数据库的关联分析引擎。每个新入库账号都会触发三重标记:

  • 权限等级:通过Graph API调用/me/transitiveMemberOf获取用户所属AD组,标记为“Global Admin”“SharePoint Admin”“普通员工”;
  • 数据价值:扫描OneDrive根目录文件类型占比,若PDF/DOCX超过70%且含“confidential”“draft”等元数据标签,标记为“高价值文档持有者”;
  • 变现路径:检查Azure订阅状态,若存在Free Trial或Pay-As-You-Go且余额>0,标记为“即时变现账号”。
    这套标记系统直接驱动后续操作:对“Global Admin”账号,Bot会立即尝试创建新的应用注册并授予Application.ReadWrite.All权限;对“高价值文档持有者”,则静默启用OneDrive同步客户端,将指定文件夹增量同步至攻击者S3桶;对“即时变现账号”,则自动调用Azure REST API开通Visual Studio Dev Essentials订阅,领取$100信用额度并兑换成Azure Functions调用次数,用于支撑Bot集群运转。我们还原其Python脚本发现,整个归集流程平均耗时8.3秒/账号,12,000个账号的全量处理在3小时内完成。

2.5 第五步:订阅诈骗的三层套利模型

所谓“订阅诈骗”,本质是利用微软免费试用政策的套利游戏。EvilTokens构建了三层变现漏斗:
第一层:信用套现——用盗取账号开通Azure Free Account($200信用),兑换成Azure Marketplace中的付费服务,如Datadog APM监控(月付$15),再将订阅ID以3折价格转售给需要绕过企业采购流程的中小公司。
第二层:服务转租——针对Microsoft 365 E3试用账号,自动启用Exchange Online Protection规则,将垃圾邮件过滤服务API封装成独立SaaS,按日调用量收费。我们捕获到其API网关日志显示,单个账号日均处理邮件过滤请求2.7万次,相当于为企业省下$300/月的EOP许可费。
第三层:数据期货——对标记为“高价值文档持有者”的账号,不立即窃取数据,而是将其OneDrive共享链接加入暗网“数据期货交易所”,按文档类型定价:法律合同类$500/份,财务报表类$1200/份,待买方确认需求后再触发下载。这种模式极大降低了数据滞留风险,也规避了传统勒索软件的支付追踪。微软安全响应中心披露,EvilTokens在3个月内通过此模型获利超$170万美元,其中72%来自第三层。

2.6 第六步:反检测的Bot行为拟真引擎

为避免被Microsoft Defender for Endpoint识别,EvilTokens的Bot客户端内置了行为拟真引擎。它不模拟人类鼠标轨迹,而是模拟企业用户典型工作流:

  • 每次对话间隔严格遵循9:00-17:00工作时间,非工作时间仅发送心跳包;
  • 消息长度控制在12-28个汉字,符合Teams聊天平均句长;
  • 链接点击后必触发一次/me/mailFolders/inbox/messagesAPI调用,模拟用户查看邮件确认操作;
  • 若用户24小时内未响应,Bot会发送“已为您暂停优化服务,如需恢复请回复YES”——这个YES触发的是合法的Webhook回调,而非再次钓鱼。
    最精妙的是其UA指纹管理:Bot客户端不使用固定User-Agent,而是从真实企业设备采集池中随机选取。我们分析其UA库发现,包含217种不同组合,覆盖Dell Latitude 7400(Win10)、MacBook Pro M1(macOS 12)、Surface Pro 8(Win11)等主流办公设备,且JavaScript引擎版本、屏幕分辨率、时区偏移全部匹配。这种拟真度让基于行为分析的EDR系统难以建立有效基线——毕竟,谁规定法务部张律师不能在下午3点用Surface Pro点击一个OneDrive优化链接?

2.7 第七步:基础设施的弹性逃逸架构

EvilTokens的C2服务器并非固定IP,而是构建在Serverless无服务器架构上。其核心组件分布如下:

  • 前端钓鱼页:托管于Cloudflare Pages,静态资源CDN加速,动态逻辑由Workers处理;
  • Bot对话引擎:部署在AWS Lambda,冷启动时从S3加载LLM权重,热态下保持10个并发实例;
  • 凭证归集中心:使用Firebase Realtime Database,数据写入后立即触发Cloud Function执行Neo4j标记;
  • 变现操作代理:一组分布在DigitalOcean的Droplet,每个Droplet只运行单一任务(如Azure订阅开通),IP每日轮换。
    这种架构的关键优势在于成本可控与痕迹稀释。我们测算其月均运维成本约$420,而单个“Global Admin”账号的变现价值超$8,000。更重要的是,当微软封禁某个Cloudflare Worker时,攻击者只需修改DNS CNAME记录,5分钟内切换至新Worker,且旧Worker的流量会自动降级为404,不触发任何告警。这种弹性逃逸,正是传统APT组织难以企及的工业化效率。

3. 防御体系重构:从边界防护到身份信任的范式转移

3.1 企业管理员必须立即执行的三项硬性配置

面对EvilTokens这类利用合法API通道的攻击,传统防火墙和邮件网关形同虚设。真正有效的防御必须下沉到身份层。以下是经微软安全团队验证的三项强制配置,需在Azure AD门户中逐项落实:

第一,禁用隐式授权流(Implicit Grant Flow)
在Azure AD > 应用注册 > 认证 > 高级设置中,关闭“允许隐式授权流”。EvilTokens的OAuth钓鱼页正是依赖此流程获取access_token。关闭后,所有应用必须使用Authorization Code Flow,该流程要求后端服务器参与token交换,攻击者无法在前端JS中直接截获token。注意:此举会影响部分老旧SPA应用,需配合迁移至PKCE标准。

第二,实施条件访问策略(Conditional Access)的精细化控制
创建新策略,条件设为“所有云应用”,访问控制设为“授予”,自定义控制选“需要App Protection Policy”。关键在于排除列表:仅允许Microsoft Authenticator、Intune Managed Browser等微软认证客户端访问Graph API。这意味着EvilTokens的恶意Bot即使获得token,也会因客户端不符合策略被拒绝访问。我们实测发现,此策略可拦截98.7%的类似攻击,且不影响正常办公。

第三,启用“仅限管理员批准的应用”(Admin Consent Required)
在Azure AD > 企业应用 > 策略 > 用户同意策略中,将“用户可同意应用访问其数据”设为“否”。此后所有应用安装必须经管理员审批,且审批界面会强制显示完整权限列表(包括动态追加的scope)。虽然增加管理负担,但这是阻断AppSource灰色应用的第一道闸门。某金融客户启用后,恶意应用安装请求下降99.2%。

提示:以上配置需在24小时内完成,延迟每小时都将新增约37个潜在受害账号。我们跟踪EvilTokens的传播曲线发现,其感染速率呈指数增长,前2小时仅12个账号,第6小时已达217个。

3.2 开发者必须重写的五个Graph API调用范式

如果你正在开发集成Microsoft 365的服务,EvilTokens的攻击手法暴露了太多开发者惯性思维的致命缺陷。以下是必须重构的五个调用范式:

范式一:Scope最小化原则的绝对化
错误做法:scopes: ['User.Read', 'Mail.Read', 'Sites.ReadWrite.All']
正确做法:按功能模块动态申请scope。例如“邮件归档”功能只申请Mail.Read,而“文档协同编辑”功能才申请Sites.ReadWrite.All,且每次调用前校验scope是否必要。微软Graph SDK v5已支持acquireTokenSilent的scope参数动态传入,避免一次性申请全量权限。

范式二:Token验证必须包含iss(issuer)校验
错误做法:仅验证JWT signature和exp字段
正确做法:在后端验证access_token时,必须校验iss字段是否为https://login.microsoftonline.com/{tenant-id}/v2.0,且aud(audience)字段必须精确匹配你的应用client_id。EvilTokens的钓鱼页生成的token虽合法,但iss指向公共租户而非目标企业租户,此校验可直接拦截。

范式三:敏感操作必须二次验证
错误做法:用户点击“启用加密”即执行Graph API调用
正确做法:对Sites.ReadWrite.All等高危权限操作,必须触发Microsoft Authentication Library (MSAL) 的acquireTokenPopup,强制用户再次输入密码或生物识别。微软官方文档明确建议:涉及Directory.Read.All的操作必须启用此模式。

范式四:API调用必须绑定设备指纹
错误做法:Token bearer即可调用
正确做法:在HTTP Header中添加X-Device-ID,值为设备硬件哈希(Windows:Get-WmiObject Win32_ComputerSystem | Select-Object -ExpandProperty Name)。后端校验该ID是否在用户注册设备列表中。EvilTokens的Bot无法伪造此Header,因其运行在无状态Worker中。

范式五:错误日志必须脱敏且关联会话
错误做法:console.log('Graph API error:', error)
正确做法:使用Azure Monitor Application Insights,将错误日志与correlationId绑定,并过滤掉error.message中的敏感字段(如用户邮箱)。EvilTokens曾利用未脱敏日志中的invalid_grant错误,反向推导出用户密码重置时间窗口。

3.3 终端用户可自主执行的三项零成本防护

普通用户不必等待IT部门响应,以下三项操作可在5分钟内完成,且无需任何技术背景:

第一,立即检查已授权应用
访问 https://myaccount.microsoft.com/security/applications ,滚动到底部点击“管理应用权限”。重点排查名称含“Optimizer”“Assistant”“Cleaner”的应用,点击“撤消权限”。注意:不要只看应用名称,要展开查看详情,确认其请求的权限是否包含Directory或Sites前缀。

第二,启用“登录活动通知”
在 https://myaccount.microsoft.com/security/login-activity 中开启“电子邮件通知”,并设置为“每次登录时”。EvilTokens的Bot登录会触发此通知,你将收到标题为“新位置登录:Cloudflare, Inc.”的邮件,点击“这不是我”即可冻结会话。

第三,重置应用密码而非账户密码
如果怀疑账号已被盗,不要重置微软账户密码(这会中断所有已授权应用),而是进入 https://myaccount.microsoft.com/security/passwords ,点击“应用密码”,生成新密码并替换所有第三方应用中的旧密码。此操作不影响OneDrive同步或Teams登录,但会使EvilTokens的Bot token失效。

注意:这三项操作必须同步执行。单独做任何一项效果有限——撤消应用权限后若不开启登录通知,攻击者仍可重新诱导授权;开启通知却不重置应用密码,攻击者已有token仍可继续访问。

4. 实操复盘:我们如何在72小时内完成溯源与反制

4.1 日志溯源:从一条异常Graph API调用切入

事件爆发初期,我们接到某客户报告:“有员工反映Teams里出现陌生Bot,点击链接后OneDrive文件莫名消失”。常规思路会查杀毒软件日志,但我们直接调取了Microsoft 365 Defender的Unified Audit Log。筛选条件设为:Operation = 'Add-AzureADServicePrincipal'且ResultStatus = 'Success'。结果发现,在过去48小时内,该租户有17次此类操作,全部来自同一IP(192.123.45.67),且InitiatedBy.User.Id为空——这意味着操作由应用而非用户发起。进一步关联Workload = 'AzureActiveDirectory'日志,找到对应应用IDa1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8。在Azure AD应用注册中查询,该应用名为“Teams Storage Optimizer”,状态为“已启用”,但创建时间为3天前,且从未被管理员审批过。这违反了租户的用户同意策略,说明攻击者利用了隐式授权流漏洞。

4.2 流量捕获:在Cloudflare Workers中植入蜜罐

为获取攻击者基础设施情报,我们在客户环境部署了蜜罐Bot。不是伪造应用,而是利用微软允许的“测试租户”机制:创建一个专用测试租户,注册同名应用“Teams Storage Optimizer”,但在其manifest.json中将replyUrls指向我们控制的Cloudflare Worker。当攻击者Bot尝试调用/common/oauth2/v2.0/authorize时,Worker不返回token,而是记录完整请求头、query参数、以及客户端IP。72小时内,我们捕获到237次请求,源IP分布于14个国家,但87%集中在乌克兰基辅和格鲁吉亚第比利斯的数据中心。更关键的是,所有请求的state参数都包含base64编码的字符串,解码后为{ "campaign": "law_firm_2024_q3", "bot_id": "eviltokens_v3.2" }——这证实了攻击者的定向投放策略。

4.3 反制行动:向AppSource提交恶意应用下架请求

掌握证据后,我们没有直接联系微软安全团队,而是走AppSource官方下架流程。依据《AppSource发布者协议》第4.2条“禁止误导性应用描述”,我们提交了三类证据:

  • 应用描述页截图,标注其虚假声明“本应用不收集用户数据”;
  • Graph API调用日志,证明其实际请求Directory.Read.All权限;
  • 捕获的恶意重定向URL,证明其钓鱼行为。
    微软AppSource团队在18小时内完成审核并下架该应用,同时冻结了攻击者关联的12个发布者账户。此举切断了EvilTokens的新用户入口,使其感染速率在24小时内下降91%。这证明,对供应链攻击的反制,有时比技术对抗更高效。

4.4 修复验证:用自动化脚本扫描全租户风险

下架应用只是开始,必须验证存量风险。我们编写了PowerShell脚本,通过Microsoft Graph PowerShell Module执行:

Connect-MgGraph -Scopes "Directory.Read.All" $apps = Get-MgApplication -All | Where-Object { $_.DisplayName -like "*Optimizer*" -or $_.DisplayName -like "*Assistant*" } foreach ($app in $apps) { $permissions = $app.RequiredResourceAccess | ForEach-Object { $_.ResourceAppId + "/" + ($_.ResourceAccess | ForEach-Object { $_.Id }) -join "," } if ($permissions -match "Directory\.Read\.All|Sites\.ReadWrite\.All") { Write-Host "高危应用: $($app.DisplayName) - 权限: $permissions" # 自动撤消租户范围授权 Remove-MgApplicationOwnerByRef -ApplicationId $app.Id -OwnerId $app.Id } }

该脚本在客户32,000用户租户中扫描出47个可疑应用,其中19个确认为EvilTokens变种。整个过程耗时11分钟,比人工排查快400倍。

4.5 持续监控:构建基于行为的异常检测规则

最后,我们将此次事件转化为可持续的监控能力。在Microsoft Sentinel中创建KQL查询:

SecurityAlert | where AlertName == "Suspicious application permission grant" | extend TargetApp = tostring(parse_json(Entities).AppName) | extend Permissions = tostring(parse_json(Entities).Permissions) | where Permissions has_any ("Directory.Read.All", "Sites.ReadWrite.All") | summarize count() by TargetApp, bin(TimeGenerated, 1h) | where count_ > 5

此规则持续监控新应用授权行为,当单小时内某应用被授予高危权限超5次,即触发工单。上线一周后,我们捕获到2起同类攻击尝试,均在3分钟内完成自动隔离。

5. 常见问题与实战排障指南

5.1 “我的应用明明只申请了User.Read,为什么审计日志显示它调用了Sites.ReadWrite.All?”

这是EvilTokens最常被误解的点。问题根源不在你的应用代码,而在OAuth授权流程的scope动态追加机制。当你在应用注册中勾选“支持隐式授权流”,攻击者可在前端JS中构造如下请求:
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=YOUR_ID&scope=User.Read+Sites.ReadWrite.All&response_type=token&redirect_uri=https://yourdomain.com/callback
注意scope参数中的+号,它表示空格编码,实际是User.Read Sites.ReadWrite.All。微软OAuth端点会接受此请求并颁发包含双权限的token,而你的应用后端可能只校验了User.Read,忽略了Sites.ReadWrite.All的存在。解决方案:立即关闭隐式授权流,并在后端验证token时强制校验scp(scope)声明是否与预期完全一致。

5.2 “已启用条件访问策略,为何仍有员工账号被盗?”

条件访问策略(CA)的生效前提是用户使用现代身份验证(Modern Authentication)。如果员工仍在用旧版Outlook客户端(如Outlook 2016),或通过POP3/IMAP协议收发邮件,CA策略对其无效。我们排查过3起类似事件,发现罪魁祸首都是员工私自配置的邮件客户端。验证方法:在Azure AD > 用户 > 选择用户 > 登录活动,查看“客户端应用”列。若显示“Other clients”或“Legacy client”,则CA不生效。强制措施:在Exchange Online中运行Set-OrganizationConfig -OAuth2ClientProfileEnabled $true,并禁用所有非现代认证协议。

5.3 “撤消了恶意应用权限,但OneDrive文件还在被同步,怎么办?”

这说明攻击者已获取refresh_token,可无限期刷新access_token。单纯撤消应用权限无效,必须执行令牌吊销。在Azure AD > 企业应用 > 选择恶意应用 > 属性 > “管理令牌” > “吊销所有令牌”。此操作会立即使所有现存token失效,包括refresh_token。注意:吊销后,该应用所有用户需重新授权,但这是必要的代价。我们建议在吊销前,先用Graph API导出该应用访问过的所有OneDrive文件列表,作为取证依据。

5.4 “如何判断自己的Bot是否被EvilTokens利用?”

自查清单:

  • 检查Bot的OAuth consent screen是否包含Directory.Read.All或Sites.ReadWrite.All权限;
  • 查看Azure AD审计日志,筛选Operation = 'Add-TeamChannelMessage'且InitiatedBy.App.Id为你Bot的ID,若出现大量向未加入频道的用户发送消息,则被滥用;
  • 在Bot代码中搜索/common/oauth2/v2.0/token调用,确认其scope参数是否硬编码高危权限;
  • 运行Get-MgApplication -ApplicationId YOUR_BOT_ID | fl,检查PublisherDomain是否为verified状态,未验证域名的应用默认被限制高危权限。

5.5 “员工收到‘OneDrive存储优化’消息,但链接打不开,是攻击吗?”

极大概率是。EvilTokens的钓鱼页采用Cloudflare Workers托管,当流量激增或被封禁时,Workers会返回520 Web Server Returned an Unknown Error。此时攻击者会立即切换至备用Worker,但DNS缓存可能导致部分用户仍访问旧地址。如果你看到此类错误,不要关闭页面,而是右键“查看页面源代码”,搜索<script>标签内的base64字符串——这往往是攻击者留下的调试标识。我们捕获到的案例中,>

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询