
核心要点(TL;DR)
- 一句话木马本质是几行接收外部参数的PHP/JSP代码,体积小、隐蔽性强,靠人工翻目录几乎查不完。
- 河马适合快速全量扫描与在线规则比对,D盾擅长静态特征与变形木马识别,两者互补而非替代。
- find 命令按修改时间、权限位与特征字符串三条件组合,能在分钟级缩小可疑文件范围。
- 查杀后必须同步做入口封堵与权限收敛,否则清理完仍会被同一漏洞重新写入。
凌晨收到告警说网站被搜索引擎标红,登录服务器一看目录里多了几个陌生文件,名字像正常缓存,打开却是几行接收参数的代码——这是典型的一句话木马场景。很多运维和站长在这一步会卡住:不知道该用什么工具扫、扫出来一堆结果不敢删、删完过几天又被写回来。本文按「先定位、再确认、后清理、最后加固」的顺序,给出河马、D盾与 find 命令的具体用法和可直接执行的命令,让你在一小时内把可疑范围压缩到可人工确认的程度。
一句话木马长什么样,为什么难查
一句话木马的核心结构非常短,通常只有一行:接收外部传入的参数,交给执行函数运行。以 PHP 为例,常见形态是 <?php @eval($_POST['cmd']); ?>,变形后可能拆成多行、用变量拼接函数名、用 base64 或 gzinflate 包裹,甚至伪装成图片文件里的注释段。
它难查的原因有三个:体积小,混在几万个文件里不显眼;不改页面输出,站点表面完全正常;命名和权限常模仿正常文件,比如叫 cache.php、index_bak.php,时间戳也可能被回拨。因此靠肉眼翻目录不现实,必须借助工具做特征比对,再用命令行做时间线与权限维度的交叉筛选。
第一步:用河马做全量快速扫描
河马(Hippo)适合做第一轮全量扫描,优势是规则更新快、支持多站点批量、结果按风险等级排序。部署方式通常是上传到站点根目录外的一个独立目录,通过浏览器或命令行触发扫描。
实操建议:
- 扫描范围先选网站根目录,不要一上来扫整块磁盘,避免超时和噪声。
- 开启「仅扫描脚本文件」选项,排除图片、压缩包,减少误报。
- 对结果按「高危」优先处理,中低危结果集中看文件路径是否落在上传目录、缓存目录。
- 扫描完成后导出报告,保留一份基线,便于下次对比新增文件。
河马的价值在于快速缩小范围,但它给出的是「可疑」,不是「确认」。凡是被标记的文件,都要打开看内容,确认是否包含参数接收与执行函数。
第二步:用 D盾复核高风险目录
D盾偏向本地静态特征识别,对变形木马、免杀马、图片马有较好的检出能力,适合对河马标记的目录做二次复核。安装后添加站点目录,选择「深度扫描」,重点看它对「可疑代码段」的定位结果。
使用要点:
- 优先扫
upload、uploads、data、cache、runtime这类高写入目录。 - 关注 D盾提示的「变量函数」「编码执行」「文件包含」三类特征,这三类是一句话木马的高频手法。
- 对报出的文件逐个查看上下文,正常框架代码也可能触发规则,不要批量删除。
| 工具 | 擅长方向 | 适用阶段 | 注意事项 |
|---|---|---|---|
| 河马 | 全量快速扫描、云端规则比对 | 第一轮缩小范围 | 结果需人工复核,避免误删 |
| D盾 | 静态特征、变形与免杀识别 | 高风险目录复核 | 框架代码可能误报 |
| find 命令 | 时间线、权限、字符串组合筛选 | 精准定位与溯源 | 需熟悉正则与权限位 |
第三步:用 find 命令做精准定位
工具扫完后,用 find 从时间线、权限和内容三个维度做交叉验证,这一步最能把范围压到几十个文件。以下命令均在网站根目录下执行,执行前先 cd 到目标目录。
按修改时间锁定近期变动文件
find . -type f -name "*.php" -mtime -7 -ls
列出 7 天内修改过的 PHP 文件。木马往往在入侵当天写入,这个条件能过滤掉绝大部分历史文件。若已知大致时间,用 -newermt "2024-05-01" 更精确。
按权限位找异常可执行文件
find . -type f -name "*.php" -perm -111 -ls
正常 PHP 文件一般是 644,带可执行位(755、777)的脚本值得警惕,尤其是上传目录里出现的可执行脚本。
按特征字符串匹配
grep -rIl --include="*.php" -E "eval\(|assert\(|base64_decode\(|gzinflate\(" .只列出包含高危函数的文件名,不打印内容,避免终端被大段代码刷屏。命中后逐个用 grep -n 定位行号再查看。
组合条件一步到位
find . -type f -name "*.php" -mtime -30 -perm -111 -exec grep -lE "eval\(|assert\(" {} \;同时满足「30 天内修改」「带可执行位」「含高危函数」三个条件的文件,基本就是重点怀疑对象。把结果记下来,进入人工确认环节。
确认、隔离与清理的正确顺序
确认一个文件是不是木马,看三点:是否接收外部参数、是否把参数送进执行函数、是否与业务逻辑无关。确认后不要直接 rm,按下面顺序处理:
- 记录证据:
ls -l看权限与属主,stat看三个时间戳,复制一份到非 Web 目录留存样本。 - 隔离文件:移动到站点外的隔离目录,或改名为
.bak_quarantine并去掉执行权限。 - 回溯入口:查 Web 访问日志中该文件的请求记录,定位是哪个上传点或漏洞被利用。
- 清理同源:用同样的 find 条件再扫一遍同目录,木马通常成组出现。
- 验证:刷新页面与关键功能,确认业务正常后再删除隔离样本。
经验提示:一次入侵往往写入多个文件,且可能留下计划任务或 SSH 公钥。清理文件后务必检查crontab -l、/etc/cron.d与~/.ssh/authorized_keys。
加固清单:让木马写不进来
查杀只是止损,加固才是根治。按以下清单逐项落实:
- 升级 CMS、插件与框架到最新版本,修复已知上传与反序列化漏洞。
- 上传目录禁止脚本执行:Nginx 用
location ~* /uploads/.*\.(php|jsp)$ { deny all; }拦截。 - Web 进程降权运行,网站目录属主与运行用户分离,去掉多余写权限。
- 关闭危险函数:在 php.ini 中禁用
eval、assert、system等(确认业务不受影响)。 - 建立文件完整性基线,对目录新增与修改做持续监控。此处可借助 AegisX 的文件完整性监控与 Web 入侵检测能力,对异常写入和可疑请求实时告警,把事后查杀前移为事中拦截。
- 保留至少 30 天访问日志,便于事后溯源。
行动建议:今天就按本文顺序跑一遍——先用河马全量扫,再用 D盾复核上传与缓存目录,最后用 find 组合条件交叉验证。把命中的文件路径、时间与处理结果记成一份清单,作为下次巡检的基线。查杀不是一次性动作,把它固化成每月例行任务,配合目录权限收敛与实时监控,才能真正把一句话木马挡在门外。
常见问题(FAQ)
网站没有明显异常,还需要做 Webshell 查杀吗?
需要。一句话木马通常不改变页面展示,只在你或攻击者访问特定参数时执行命令,因此站点看起来完全正常。建议至少每月做一次全量扫描,并在每次代码上线、插件更新、目录权限变更后补做一次定向排查,重点是上传目录与缓存目录。
河马和 D盾应该选哪个?
两者定位不同,建议都装。河马偏向快速全量扫描与云端规则比对,适合日常巡检;D盾偏向本地静态特征与变形木马识别,适合对可疑目录做深度复查。实战中先用河马扫全站缩小范围,再用 D盾复核高风险目录,误报率更低。
find 命令查木马最有效的条件是什么?
最有效的是组合条件:按修改时间锁定近期变动文件,再叠加权限位异常(如644以外的可执行位)与特征字符串匹配。单用时间会漏掉老木马,单用字符串会漏掉混淆变形,三者叠加能把候选文件压缩到几十个以内,便于人工确认。
发现一句话木马后可以直接删除吗?
不建议直接删除。应先隔离到非 Web 目录并保留样本,记录文件路径、修改时间、权限与所属用户,再回溯访问日志确认入口。直接删除会丢失溯源证据,也无法判断是否还有其他同源文件,容易反复中招。
清理完 Webshell 后如何防止再次被写入?
核心是封堵入口与收敛权限:升级存在漏洞的 CMS 与插件,上传目录禁止脚本执行,Web 进程降权运行,关闭不必要的写权限。可配合 AegisX 的文件完整性监控与 Web 入侵检测能力,对目录变更与异常请求做持续告警,把被动查杀变成主动拦截。