Webshell查杀实战:河马、D盾与find命令定位一句话木马 核心要点图解,一句话木马本质是几行接收外部参数的PHP/JSP代码,体积小、隐蔽性强,靠人工翻目录几乎查不完。;河马适合快速全量扫描与在线规则比对,D盾擅长静态特征与变形木马识别,两者互补而非替代。;find 命令按修改时间、权限位与特征字符串三条件组合,能在分钟级缩小可疑文件范围。;查杀后必须同步做入口封堵与权限收敛,否则清理完仍会被同一漏洞重新写入。
Webshell查杀实战:河马、D盾与find命令定位一句话木马 · 核心要点一图读懂(AegisX)

核心要点(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,按下面顺序处理:

  1. 记录证据:ls -l 看权限与属主,stat 看三个时间戳,复制一份到非 Web 目录留存样本。
  2. 隔离文件:移动到站点外的隔离目录,或改名为 .bak_quarantine 并去掉执行权限。
  3. 回溯入口:查 Web 访问日志中该文件的请求记录,定位是哪个上传点或漏洞被利用。
  4. 清理同源:用同样的 find 条件再扫一遍同目录,木马通常成组出现。
  5. 验证:刷新页面与关键功能,确认业务正常后再删除隔离样本。
经验提示:一次入侵往往写入多个文件,且可能留下计划任务或 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 入侵检测能力,对目录变更与异常请求做持续告警,把被动查杀变成主动拦截。