find wp-content/uploads -name '*.php' 数出四十个,文件名像 a8f3c.php,修改时间集中在凌晨两点到四点。文件内容是一行 eval 加一段 base64。日志里能对上时间点,这种反而好排。

插件或主题的上传接口没有校验扩展名,php 被直接写进可写目录。文件在不等于能执行,要看 nginx 有没有在该目录禁掉 PHP 解析,两件事得分开确认。这一点先确认清楚,后面就不用反复试。

find wp-content/uploads -name '*.php' -printf '%T+ %p\n' | sort
awk '$6 ~ /POST/ && $7 ~ /upload/ {print $1, $7}' access.log | sort | uniq -c | sort -rn | head

「uploads 目录 php 文件」改完先别急着全量,挑一台机器放半天,真有问题这段时间就能看出来。偶发问题先统计频率,一小时几次和一天一次,查法完全不同。

改完顺手把文档补一句,省得下次自己重新推一遍。监控和日志的时间要对上,时区不一致会多绕很大一圈。

处理上按这个顺序:先按 mtime 排序,把最早出现的那一批单独打包留证,再删除;对照同一时段的 access.log,找 POST 打到了哪个上传接口,入口才是要补的地方;uploads 目录单独加 location,php 请求一律返回 403。

结果对不对很好判断,uploads 下再查不到 php 文件,访问其中一个旧地址返回 403。

作者 9823189