发现网站被篡改,尤其是根目录下的 .htaccess 文件被注入恶意代码,通常意味着服务器权限已经出现了严重漏洞。此时最致命的错误是只修改文件内容而不恢复权限,这会导致攻击者在几秒钟内重新夺回控制权。处理这类事件的核心逻辑是:先阻断写入通道,再清理恶意代码,最后加固防线。
立即隔离与备份现状通过 FTP 或 SSH 进入服务器后,不要直接打开 .htaccess 编辑。先将现有文件重命名或复制到安全位置,这是取证和后续分析攻击来源的关键证据。执行命令保留副本:
cp /var/www/html/.htaccess /root/forensics/htaccess_malware_backup.txt
如果网站处于生产环境,立刻将网站模式切换为只读或返回 503 状态码,防止恶意跳转或钓鱼页面继续扩散。这一步能切断攻击者利用篡改文件获取流量或窃取用户数据的渠道。
锁定文件写入权限大多数 .htaccess 篡改源于文件权限设置为 777 或 666,导致任意用户可写。在清理代码前,必须先将 .htaccess 权限重置为严格只读。标准安全权限是 644,即只有文件所有者可写,其他用户只读。执行:
chmod 644 /var/www/html/.htaccess
同时检查文件所有者是否正确。很多入侵场景中,攻击者通过上传漏洞创建了由 www-data 或 apache 用户拥有的恶意文件。确保 .htaccess 的所有者是 root 或特定非 Web 运行用户:
chown root:root /var/www/html/.htaccess
如果 Web 应用确实需要对 .htaccess 进行写入(如某些 SEO 插件或安全插件自动更新规则),务必确认这种需求的合理性,绝大多数情况下 Web 进程不应拥有该文件的写权限。
深度清理恶意代码攻击者常注入的代码类型包括:通过 RewriteRule 将搜索引擎流量重定向到恶意网站、使用 FilesMatch 执行后门脚本、利用 ErrorDocument 劫持 404 页面注入病毒、或通过 php_value 开启危险函数。清理时不能仅靠肉眼,因为很多恶意代码使用了混淆手段。
典型的恶意跳转代码通常长这样,需要全部移除:
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} (googlebot|bingbot) [NC]
RewriteRule ^(.*)$ http://malicious-site.com/$1 [R=301,L]
还要检查是否存在通过 mod_rewrite 加载外部配置文件的行为,例如:
RewriteOptions inherit
这行代码会让子目录继承父级规则,攻击者可能在上级目录埋下后门。清理完毕后,逐行核对与原始备份的差异。如果没有备份,可以对照同版本 CMS 的默认 .htaccess 模板进行比对。
递归排查所有子目录攻击者很少只篡改根目录的一个 .htaccess 文件。他们通常会在 /images、/uploads、/wp-content 等可写目录中植入隐藏的 .htaccess 文件,这些文件可能将图片目录当作 PHP 执行目录,从而运行伪装成图片的 webshell。执行全盘扫描:
find /var/www/html/ -name ".htaccess" -type f
逐一检查这些文件的内容,特别关注包含 AddHandler、AddType、php_value、Options +ExecCGI 等指令的文件。任何出现在上传目录中的 .htaccess 都应视为高危文件,除非业务有特殊需求,否则直接删除。
修复被篡改的服务器配置如果攻击者获得了 root 或 sudo 权限,他们可能修改了 Apache 主配置文件 httpd.conf 或 apache2.conf,将 AllowOverride 从 None 改为 All,从而让 .htaccess 中的恶意指令生效。检查主配置中相关目录的权限覆盖设置,确保敏感目录禁止重写:
<Directory /var/www/html/uploads>
AllowOverride None
</Directory>
同时确认 mod_rewrite、mod_security 等模块是否被恶意加载或篡改。重启 Apache 服务前,使用语法检查命令避免因配置错误导致服务中断:
apachectl configtest清除 Web 应用缓存与残留
很多 CMS 框架(如 WordPress、Drupal、Magento)拥有自己的缓存机制,攻击代码可能被缓存在数据库或文件系统中。清理 .htaccess 后,必须清空应用层缓存。对于 WordPress,需要删除 /wp-content/cache/ 下的所有内容;对于使用 Redis 或 Memcached 的站点,执行缓存刷新命令。如果使用了 CDN 服务,还需清除 CDN 边缘节点的缓存,否则用户仍可能被缓存的恶意重定向规则影响。
溯源并修复入侵入口恢复文件只是治标,堵住漏洞才是治本。检查服务器日志 /var/log/apache2/access.log 和 error.log,重点排查 .htaccess 被修改时间点前后的 POST 请求。常见的入侵入口包括:使用弱口令的 FTP 账号、存在 SQL 注入或文件上传漏洞的插件、未及时更新的 CMS 核心程序、以及配置不当的 XML-RPC 接口。
如果日志被清除,说明攻击者已经获得了较高权限,此时应通过文件修改时间戳来反推入侵时间:
stat /var/www/html/.htaccess
根据 Modify 时间,结合系统登录日志 /var/log/auth.log 或 /var/log/secure,查找该时间段的异常登录会话。对于 WordPress 站点,立即检查 /wp-admin/user-edit.php 中是否存在不明管理员账号,并重置所有用户的密码和应用程序密码。
部署预防性免疫策略在 .htaccess 文件本身中加入防护规则,可以阻止部分自动化攻击工具直接访问该文件。添加以下指令拒绝外部 HTTP 请求读取 .htaccess:
<Files .htaccess>
Require all denied
</Files>
同时,利用 Linux 的 chattr 命令将 .htaccess 设置为不可变文件。即使攻击者拿到了 root 权限,在未解除该属性前也无法修改或删除文件:
chattr +i /var/www/html/.htaccess
需要更新规则时,先执行 chattr -i 解除锁定。这种机制结合文件完整性监控工具(如 AIDE 或 Tripwire),可以在文件被篡改的第一时间发出告警,将应急响应时间从数小时缩短到秒级。
验证恢复效果与持续监控完成上述步骤后,使用 curl 命令模拟不同 User-Agent 访问网站,检查是否存在异常跳转:
curl -A "Mozilla/5.0 (compatible; Googlebot/2.1)" -I https://yourdomain.com
观察返回的 HTTP 状态码和 Location 头部信息。同时,通过第三方安全扫描平台对网站进行黑盒检测,确认恶意代码已被彻底清除且没有遗留的后门文件。最后,建立定期比对 .htaccess 文件哈希值的监控任务,一旦哈希值发生变化,立即触发告警并自动将该文件权限锁定为只读,防止事态扩大。
