页面篡改事件中的文件差异与发布链回溯
页面篡改事件中的文件差异与发布链回溯
页面篡改是应急响应中最容易被“看见”的事件类型之一。首页跳转、博彩内容、黑页挂马、SEO 污染、隐蔽 JS 跳转,往往一眼就能发现。但真正困难的部分并不是“看到了被改的页面”,而是如何在短时间内回答:
- 到底哪些文件被改了?
- 是前端静态资源被植入,还是后端模板、网关、CDN、发布链出了问题?
- 篡改是手工改动、批量脚本投放,还是自动化发布流程被污染?
- 受影响的是一台机器、一个目录,还是整个站点集群?
你在 0x03取证分析/页面篡改分析 子目录里已经有多篇具体案例,例如 页面篡改分析-首次会话跳转菠菜页面篡改分析。本文不重复具体样本,而是抽象出一套通用分析方法论。
0x01 页面篡改分析先回答四个问题
在页面篡改事件里,建议先按以下顺序定问题:
- 用户看到的异常内容来自哪里? 是 HTML 本体、JS 动态加载、服务端模板、反向代理,还是 CDN 缓存。
- 改动发生在哪一层? 文件层、发布层、服务层、网络层,还是外部供应链。
- 改动是什么时候发生的? 是一次性人工改动,还是持续反复被写回。
- 谁有能力完成这次改动? 是 WebShell、运维账号、发布系统、CI/CD、宿主机,还是第三方组件。
只有先把层级和时间确定下来,后面的差异比对才不会盲目。
0x02 页面篡改不等于“首页文件被改”
很多应急现场一看到首页跳转,就马上去找 index.php、index.html。这当然没错,但页面异常可能来自多种位置:
- 首页模板被改
- 公共 JS / CSS 被植入
- CDN 缓存被污染
- 反向代理层做了重定向
- Nginx / Apache / IIS 配置被改
- 站点某处被插入远程加载脚本
- 上游发布包本身就已经带毒
这也是为什么单靠肉眼找首页文件很容易漏掉真正入口。实际分析应先从页面渲染路径倒推。
0x03 文件差异分析是页面篡改的主轴
页面篡改事件里,最核心的动作仍然是做差异比对。
1. 应优先比对哪些对象
建议至少比对以下几类:
- 当前生产目录 vs 最近已知正常备份
- 当前文件 vs Git / 发布包基线
- 当前节点 vs 同集群其他正常节点
- 当前静态资源 vs CDN 源站资源
2. 为什么差异比对比“全盘搜马”更快
全盘搜关键字适合辅助定位,但真正能快速缩小范围的通常是:
- 哪些文件近期新增
- 哪些文件内容发生变化
- 哪些文件哈希与基线不同
- 哪些目录存在批量异常改动
例如篡改常见的几个信号:
jquery.min.js、common.js、app.js被插入跳转代码- 模板文件中新增
iframe,script,eval,atob - 头尾模板、公共组件被加远程资源引用
- 同一时刻多个目录出现相似代码片段
3. 公共文件优先级最高
页面篡改最喜欢动的是“影响面最大”的位置,例如:
- 公共 JS
- 公共页头页尾
- 全站模板
- 中间件层重定向配置
因为攻击者希望改最少的点,影响最多的页面。
0x04 时间线回溯决定你能否找到入口
光知道哪些文件被改还不够,更重要的是弄清楚“它们是怎么被改进去的”。
1. 先看改动时间分布
重点观察:
- 被改文件是否集中在同一分钟
- 是否跨多个目录同步变化
- 是否先有一个脚本落地,再批量修改文件
- 是否存在周期性重复改写
如果多个模板和静态文件在几秒内同时被修改,通常意味着:
- 脚本批量投放
- 发布包覆盖
- 自动化任务写入
2. 再找前置事件
向前回看同时间窗:
- WebShell 访问
- SSH / RDP 登录
- 发布系统操作
- Git pull / rsync / scp / ftp
- CI/CD 执行日志
很多篡改看起来像“页面问题”,其实真正入口是:
- Web 上传漏洞
- 运维账号被盗
- 发布机被控
- 源码仓库被污染
3. 关注“被修复后又被改回”的场景
这是实战里非常常见的一类现象。若刚恢复页面,过一会儿又被篡改,通常说明:
- 后门仍在
- 发布链仍有污染源
- 定时任务或守护进程在回写恶意内容
这类场景若只删当前恶意代码,而不追根溯源,事件会无限复发。
0x05 如何区分文件层篡改和发布链污染
这是页面篡改取证中最关键的判断之一。
1. 文件层篡改的典型特征
常见表现:
- 单台或少数节点受影响
- 文件修改时间集中
- 目录中存在 WebShell、后门脚本、异常上传文件
- 直接在生产目录看到恶意代码
说明攻击者大概率是“进了机器再改文件”。
2. 发布链污染的典型特征
常见表现:
- 多台节点几乎同时出现相同篡改
- 恢复后再次通过正常发布流程被写回
- Git 仓库、制品包或发布脚本内本身带有恶意改动
- 发布服务器、CI Runner、同步脚本存在异常
说明攻击者大概率是“进了发布链再污染全站”。
3. CDN / 缓存层问题的典型特征
常见表现:
- 源站文件正常,用户访问异常
- 某些地区或某些节点异常
- 清缓存后短暂恢复
这类情况如果误判成源站文件被改,会白白浪费时间。
0x06 页面篡改中最常见的几类恶意改动
1. 跳转型
特点:
- 首次访问跳转
- 按 UA、来源、地域、Referer 条件跳转
- 利用 Cookie 做“只跳一次”
这一类和你现有的菠菜跳转案例高度相关。
2. 挂马型
特点:
- 插入远程 JS
- 动态加载恶意资源
- 条件触发下载或浏览器利用链
3. SEO 污染型
特点:
- 面向搜索引擎返回另一套页面
- 只对爬虫或特定 UA 展示垃圾内容
- 利用隐藏目录、伪静态、模板注入
4. 后门伴生型
特点:
- 页面只是表象
- 同时存在 WebShell、计划任务、批量脚本
- 篡改是攻击者维持收益或引流的手段
这类最需要和 WebShell落地与文件时间线分析.md 一起看。
0x07 如何快速收敛影响范围
页面篡改的应急处置往往要求非常快,因此分析上要能迅速判断影响面。
1. 从入口文件向公共组件扩散检查
优先排查:
- 全局模板
- 公共 JS
- 公共头尾
- 路由入口
- 站点配置文件
2. 从单机向集群扩散检查
重点判断:
- 其他节点是否同样存在差异
- 负载均衡后端是否全部受影响
- 同一发布链下的其他站点是否同步异常
3. 从站点向发布系统扩散检查
若怀疑发布链污染,立即检查:
- Git 提交记录
- 打包产物
- CI/CD Job 日志
- 同步脚本
- 发布账号登录记录
这一步直接决定你是“修一台机”还是“封整个发布链”。
0x08 三个常见误区
1. 看到恶意 JS 就认为问题已经找到了
恶意 JS 可能只是结果,不一定是入口。真正入口可能是:
- WebShell
- 发布系统
- 运维凭据泄露
- 上游制品污染
2. 只恢复文件,不找回写源
如果不确认是谁、通过什么机制把内容写回来,那么恢复很可能只是暂时的。
3. 只看单台机器
现代站点通常有:
- 多节点
- 对象存储
- CDN
- 自动化发布
不看整体链路,很容易只修复了表面现象。
0x09 建议的交付结构
页面篡改事件建议整理为如下表格:
| 时间 | 证据源 | 事件 | 影响对象 | 结论 |
|---|---|---|---|---|
| 08:12:10 | 用户反馈 / 监测 | 首页首次访问跳转 | www.example.com | 事件暴露 |
| 08:16:43 | 文件差异 | common.js 被插入跳转代码 | 公共静态资源 | 篡改点定位 |
| 08:18:21 | 文件时间 | 多个模板同分钟改动 | 全站模板目录 | 疑似批量写入 |
| 08:20:55 | Web 日志 | 可疑后门访问 | /upload/a.php | 入口初步确认 |
| 08:24:03 | 发布日志 | 无合法发布记录 | 生产目录 | 排除正常上线 |
如果怀疑发布链污染,则再单独补一张:
| 时间 | 证据源 | 事件 | 对象 | 结论 |
|---|---|---|---|---|
| 08:30:10 | Git 提交 | 异常账号提交脚本 | 仓库 | 上游污染 |
| 08:32:41 | CI 日志 | 正常流水线发布恶意文件 | 发布任务 | 恶意内容由发布链下发 |
0x0A 总结
页面篡改分析真正的关键,不是“把那段恶意代码找出来”,而是完整回答:
- 哪些文件被改
- 为什么这些文件会被改
- 这次改动来自单机入侵还是发布链污染
- 是否存在回写源与更深层后门
当你能把文件差异、时间线、访问日志、发布记录和集群影响面连成同一条链时,页面篡改事件就不再只是“首页被黑”这么简单,而会变成一条可复盘、可回滚、可根治的完整攻击路径。