宝塔“一键查杀”不可全信,它仅基于特征匹配扫描小体积php文件,无法识别深度混淆webshell、数据库js注入、nginx二进制劫持等高级威胁,需人工验证+目录精准扫描+加固disable_functions与open_basedir。

宝塔“一键查杀”能信吗?先看它查什么
宝塔的「木马查杀」功能本质是特征匹配扫描,不是行为沙箱分析。它靠关键词(比如 eval、base64_decode、gzinflate)和文件体积(默认筛
- 它不会查数据库里被注入的 JS 代码,也不会识别
.user.ini里被篡改的open_basedir配置 - 它不分析
access.log中异常 POST 请求的时间线,更不比对 Nginx 二进制文件是否被替换 - 扫描结果里标“低危”的条目,可能是你自己的加密配置或合法压缩函数调用,别见红就删
真要靠它,得配合人工确认:点开每条结果,用 head -n 20 文件路径 看开头逻辑,而不是只信文件名。
Webshell 查杀必须指定目录,别漏掉 upload/cache 这些重灾区
宝塔默认不自动遍历全站,你得手动填路径。攻击者九成以上把木马丢在可写目录里:/www/wwwroot/your-site.com/upload/、/cache/、/images/、/data/ —— 这些地方往往权限宽松、更新频繁、审查最少。
- 在「木马查杀 → 目录查杀」中,必须逐个站点填写根目录下的可写子目录,不能只扫
/www/wwwroot/一级 - 如果用了 ThinkPHP、DedeCMS 或 WordPress,额外加扫
/www/wwwroot/your-site.com/data/和/www/wwwroot/your-site.com/wp-content/uploads/ - 切忌勾选「递归扫描所有子目录」却不设白名单——会扫到 Composer 缓存、Node 模块里的合法
eval,导致大量误报
扫描前建议先执行这条命令快速过一遍高危小文件:find /www/wwwroot -name "<em>.php" -type f -size -50k -exec grep -l "eval|base64_decode|gzinflate|file_get_contents.</em>http" {} \; 2>/dev/null
查完木马,立刻验证 Nginx 是否被劫持
挂马不止发生在 PHP 文件里。2025 年底起大规模爆发的宝塔 Nginx 挂马事件,是直接替换 /www/server/nginx/sbin/nginx 二进制,让所有响应自动注入 JS(如含 _0xd4d9 或 waf_sc 字样的解密脚本)。
- 登录服务器后第一件事:运行官方检测脚本
curl -sSO <a href="https://www.php.cn/link/8dda4f8ad13f00fbc214ee90dbcd2665">https://www.php.cn/link/8dda4f8ad13f00fbc214ee90dbcd2665</a> && btpython w_check.py && rm -rf w_check.py - 手动比对 Nginx MD5:
md5sum /www/server/nginx/sbin/nginx和/www/server/panel/data/nginx_md5.pl里的记录是否一致 - 检查是否存在异常配置文件:
/www/server/nginx/conf/btwaf/config(非官方插件路径,大概率是后门) - 如果发现异常,别重启 Nginx —— 先停面板(
bt stop),再从干净镜像重装 Nginx,否则重启等于重新加载恶意逻辑
disable_functions 空着就是开门揖盗
PHP 7.4+ 版本在宝塔里默认 disable_functions 是空的,意味着 system、exec、shell_exec、proc_open 全部可用。一个带 eval 的木马上传上来,三秒就能反弹 shell。
- 进「软件商店 → PHP → 设置 → 配置修改」,在
disable_functions栏补全:system,exec,passthru,shell_exec,proc_open,popen,assert,call_user_func,file_put_contents - 改完必须点「服务 → 重启」对应 PHP 版本,否则配置完全不生效
- 同时检查每个站点根目录下是否有
.user.ini,内容是否被改成open_basedir=/或清空 —— 这种配置会覆盖 php.ini,让上面的禁用函数全部失效
真正的防护不在“查出来”,而在“根本跑不起来”。木马文件删一百遍,只要 disable_functions 是空的、open_basedir 没锁死、Nginx 二进制被替换了,它明天就能自己复活。










