文章总结: 本文详细分析了一起通过企业微信日程邀请发起的钓鱼攻击案例。攻击者利用内部日程的信任机制,以’高温补贴’为诱饵,诱导用户点击链接进入仿冒页面。页面通过多维设备检测绕过安全环境,并严格校验身份证格式以获取真实信息。在采集银行卡号、余额及手机号后,后台操作员可实时操控,针对不同受害者定制后续的验证码或密码窃取流程。文章强调此类攻击可快速换皮,核心检测指纹在于脚本哈希和接口行为,并建议用户对要求’当天办理’且’离开微信打开链接’的消息保持警惕。 综合评分: 90 文章分类: 安全意识,实战经验,社会工程学,WEB安全,恶意软件
我的同事”被组织”了一场钓鱼会议
原创
MessFeel MessFeel
MessFreeSecurity
2026年8月12日 23:23 北京
在小说阅读器读本章
去阅读
下午打开企业微信,日历里躺着一条陌生日程。标题叫”高温补贴申请通知”,组织人是我不认识的一个同事,参与人列表拉了整个公司。
我把那条链接复制到手机浏览器。下面是我拆开的东西。
日程入口
先想一个问题:你上班收到一条日程邀请,组织人是部门同事,头像名字都对,标题写着”补贴申请”,描述里说要今天内完成——你会觉得这是钓鱼吗?
不会。日程邀请是协作平台里最接近内部通知的形态。它不是群消息,群消息会被折叠会被截屏发到安全群。日程是平台原生的分发通道,组织人写完标题和描述,系统自动推给所有参与人。恶意链接套上了”内部通知”的壳,你连怀疑的入口都没有。
链接指向 wap[.]wafnhci[.]cn。每次访问 302 跳转到新的随机子域。同事之间互相转发,最终拿到的地址都不一样。封一个 URL 没用——攻击者早就算好了。
在微信内置浏览器里打开,页面会藏掉一部分菜单,然后弹提示让你”复制到手机浏览器”。这不是适配问题。微信浏览器有安全拦截和风险提示,他们想绕过去。
一个特征记住就行:一条消息同时要求”当天办理”和”离开微信打开链接”,先停。核实发送账号,联系发送人。别点。
同事的账号出了什么事
他说上午点过钓鱼链接。但”点过链接”和”终端失陷”是两回事。日程能以他的身份创建,有三种可能。
最可能的:登录会话被接管
不需要密码。他上午钓鱼页面里填完资料,页面”审核中”的时候,后台操作员可能已经诱导他扫了码,或者拿到了浏览器里的登录 cookie。用他的身份登企业微信,建全天日程,从通讯录拉人——五分钟的事。
截图里组织人是他,只说明日程用他的身份创建,不说明他本人操作了。
次之:应用凭证泄露
企业微信开放接口允许应用建日程,传主题、描述和 attendees 列表。如果某个自建或第三方应用的 Secret 被拿走,攻击者直接调接口批量创建。日程详情里如果有”由应用创建”的标记,或者日志里有异常 agentid 和 token 调用,就往这个方向查。
要排除:外部日历邀请同步
伪造显示名称,往邮箱发日历邀请,协作平台同步后也会出现在日历里。查原始邮件头、ICS 里的 UID 和 ORGANIZER,能区分内部创建和外部投递。
我把情况同步给了安全团队,建议按这个顺序查:账号会话先看,再查授权应用,最后排除外部邀请。日志没出来之前,别急着下结论说同事电脑被控了。但不管哪种路径,先冻结组织人账号的活跃会话,撤回恶意日程,这两件事不能等。
链条在攻击之前就铺好了
1收集部门结构、员工账号、群聊列表。参与人接近 100,大概率对应某个部门或群成员集合。
2拿日程创建入口。接管会话、窃取应用凭证、或者伪造外部邀请。
3建全天日程,把诱饵文案和钓鱼域名写进描述,加批量参与人。
4平台自动同步。内部头像、组织人姓名、参与人列表——全都在帮攻击者做背书。
5像我这样点开链接的人,进了手机浏览器之后,踩进一套完整的信息采集流水线。
要区分三条路径,调这几组记录
- 日程的
schedule_id、cal_id、创建和修改时间、创建来源、组织人 userid、参与人清单、有没有应用创建标记。 - 组织人账号事件前后的登录 IP、设备、扫码授权、网页登录、会话续期和安全告警。
- 组织人的手机、电脑、浏览器有没有同时段的异常进程、插件、下载或会话窃取痕迹。
- 日程权限配置、第三方应用授权、Secret 变更记录、token 获取和日程创建接口的调用日志。
- 如果是邮件同步,原始邮件头和 ICS 文件。
拿到创建来源、组织人登录记录、应用调用记录,三组数据交叉,基本就能定是哪条路径。
第一道关:不是手机就别想看
手机浏览器打开,页面秒加载,仿冒人社部门的申领界面。后来我在电脑上试同一个地址,跳出来的是个二维码过渡页。
看了源码,不是简单读 UA。它同时查了四样东西:UA 里有没有手机关键词、设备支不支持触摸(maxTouchPoints 和 ontouchstart)、navigator.platform 是不是桌面系统、屏幕短边宽度有没有超过 1200 像素。
mobileUa = UA 命中 Android / iPhone / Mobile / 微信等touch = maxTouchPoints > 0 或存在 ontouchstartdesktop = platform 命中 Windows / MacIntel / Linux x86如果 UA 不像手机、没有触摸、命中桌面平台或屏幕过宽: 跳转到电脑端二维码页
光改 UA 没用。Chrome DevTools 切个 iPhone UA,platform 还是 MacIntel,直接踢到二维码页。后面身份页和银行卡页还会再查一次平台。攻击者很在意分析环境能不能摸到真的采集页面。
图 1|原始域名移动端实测:页面仿冒人社部门视觉,并强调“一次性最高 1500 元”和“立即申领”。截图只支持页面呈现,不支持页面中的政策主张。
身份页校验比某些政务网站还严
点了”立即申领”,进姓名和身份证页面。我随手编了个 18 位数字,前端直接报格式错误。
翻源码,它不止查长度。省份码、出生日期、最后一位校验码全验了一遍。瞎编的号过不去,你得给一个格式正确的真实身份证号才能进入下一步。
代码里还有 Tesseract OCR 的调用、后置摄像头和相册读取,能从证件照片上自动提 18 位号码。页面上那个扫描入口被注释掉了,但 OCR 和摄像头的代码还在运行文件里。换句话说,这个套件有能力直接从身份证照片读号,只是当前页面没把入口亮出来。
图 2|同集群关联节点实测:姓名与身份证表单。关联节点和原始目标的核心控制脚本、Canvas 话术库哈希完全一致;截图不作为原始域名当次会话的直接回包。
银行卡页问余额,跟”补贴”没关系
姓名和身份证先写进 localStorage,然后进银行卡确认。三个必填项:卡号、余额、预留手机号。
页面说余额是用来”核实本人领取”的。发补贴不需要知道你卡里有多少钱。余额的真正用途是告诉后台操作员:这张卡值不值得继续。卡里三千和卡里三十万,后续的操作是不一样的。
前端读银行卡 BIN 判断发卡行和卡种。借记卡只收基础字段。信用卡和准贷记卡会多弹两个框:有效期、卡背后三位安全码。卡种和银行名称一起上报服务器,后台按卡类型决定下一步怎么处理。
提交的包:姓名、身份证、银行卡号、余额、手机号、卡种,信用卡再加有效期和安全码。服务器返回 current_order_id,每个受害者从这开始有自己的独立记录。
图 3|同集群关联节点实测:页面索要银行卡号和余额,并用“资金发放确认”包装采集目的。信用卡会继续出现有效期与安全码字段。
审核中?后台操作员正在看你的资料
银行卡提交完,页面停在”审核验证”界面,写着约 1490 元、3%。金额和我的”补贴资格”没有半点关系,脚本里写死的。
这时候看网络请求就有意思了。首页加载完就生成了 index_online_tk,每三秒心跳。进采集流程后又生了一个 tk,大约每两秒向 commands.html 发请求,问”下一步干什么”。
返回的指令里有 action、url、msg、showtype 和 command_version。url 可以覆盖默认流程,action 决定跳不跳新页面,command_version 用来防止同一个命令反复执行。断网了页面会提示”正在自动重连”,恢复之后继续轮询。
所以你看到的”审核验证”不是一个自动流程。它是个等命令的状态。你的银行卡信息已经到了后台,操作员在另一块屏幕前看着,决定下一步推给你什么。
后台可以按人逐一定制
1推六位银行卡密码页面。
2推第一轮短信验证码页面。
3换一套话术,再要第二轮验证码。
4显示失败、成功,或者后台指定的随便什么页面。
验证码页最狠的地方是文案
三套验证码页面都要六位数字,设了 autocomplete=one-time-code。技术实现不复杂,厉害的是上面写的话。
其中两套页面提前告诉你:你收到的银行短信里会有一个陌生商户名和一个”1到10000″的金额,那是系统生成的,不会真的扣款,放心把验证码填进来。
银行短信本来靠商户名、金额和风险提示来帮你识别交易。这是最后一道防线。钓鱼页面先动手,把这些信息套上”补贴核验”的解释。你看到陌生商户名和扣款金额的时候,已经有人提前告诉过你”这是正常的”。你就不犹豫了。
第二轮页面换说法,用”操作异常””资金保护”继续制造紧迫感。你不填,好像就会出问题。
前端配置里有 /getauthcode.html、/appendauthcode.html 和 /appendcardpass.html,分别对应获取验证码、追加验证码、追加银行卡密码。我分析到深层采集阶段的时候拦掉了所有敏感 POST,没有创建真实受害者记录。
别盯着”高温补贴”,这东西能换一百张皮
重点文件是 initcanvas.min.js。里面不只有”高温补贴”这一套话术。能检出的还有 ETC、医保、HPV 疫苗、额度提升、银行卡密码、短信验证码。
敏感词替换成了”测试账号””演示系统”,重要文字渲染在 Canvas 上。普通 DOM 关键词扫描扫不到 Canvas 里的内容。HTML 里还混了跟业务完全无关的隐藏小说段落,像是从别的模板复制粘贴没清干净的残留。
身份页重复加载旧的银行卡流程脚本,好几个页面留着没清理的历史字段。典型的通用模板换皮。今天高温补贴,明天 ETC,后天医保。标题和金额改一下,脚本哈希不变,commands 接口不变,轮询结构不变。
套件级检测指纹
稳定脚本哈希commands 接口tk / order_id指令版本去重多维设备分流
页面标题和补贴金额随便改。脚本哈希、接口路径、存储键和轮询行为才是同源站点的身份证。网关看到 commands.html 轮询和 tk 参数同时出现,不管页面上写的是什么标题,先封。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:MessFreeSecurity MessFeel MessFeel《我的同事”被组织”了一场钓鱼会议》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论