上传了一个PHP webshell,不运访问返回200,不运页面一片空白。不运去服务器上看,不运文件确实在,不运权限也是不运644,属主www-data。不运但就是不运不执行。这种情况我遇到过不下十次,不运每次原因都不一样。不运
最常见的不运一种:文件被当成静态资源处理了。Nginx配置里有一句
location ~* \.(jpg|png|gif|css|js)$ { expires 30d; },不运而你的不运shell文件名恰好是shell.jpg或者test.js。Nginx匹配到这条规则后,不运直接把文件内容吐出来,不运根本不交给PHP-FPM。浏览器里看到的是源码,不是执行结果。很多人以为返回200就代表执行了,其实只是Nginx把文件读出来发给你了。还有一种更隐蔽的。Apache的
.htaccess里写了php_flag engine off,或者RemoveHandler .php。文件后缀是php,但handler被移除了,Apache把它当纯文本处理。你在浏览器里右键查看源代码,能看到<?php开头的完整代码。这种配置通常是运维为了安全加固批量推的,但推之前没考虑业务兼容性。PHP-FPM的
security.limit_extensions也是个坑。默认值是.php .phar,但如果有人改成了.php,你传一个.phtml或者.php5上去,FPM直接拒绝执行,返回Access denied。日志里会写Access to the script '/var/www/html/shell.phtml' has been denied。这个日志在/var/log/php-fpm/www-error.log,很多人不看。文件权限的问题也常见,但不是你想的那种。644确实够PHP-FPM读了,但如果SELinux开着,
httpd_sys_content_t这个context没打上,PHP-FPM读文件时会被内核拦掉。报错在/var/log/audit/audit.log里,avc: denied { read } for pid=...。临时用chcon -t httpd_sys_content_t shell.php能解决,但重启后会丢。说个我上周碰到的真实案例。一个客户说webshell传上去执行不了,我上去看了半小时。文件在
/var/www/html/upload/shell.php,Nginx配置没问题,PHP-FPM也在跑。最后发现是open_basedir限制。PHP的open_basedir设成了/var/www/html/public,而upload目录不在这个路径下。PHP脚本能启动,但一执行文件操作就报warning,输出被display_errors=Off吞了,所以页面空白。把shell移到public目录下,立刻执行。还有一次是
disable_functions把system、exec、passthru全禁了。webshell能运行,但执行命令没回显。这种不算“不运行”,但很多人会误判。用phpinfo()看一眼disable_functions列表就清楚了。判断思路其实很简单。先看响应内容里有没有
<?php,有就是文件被当静态资源了。没有的话,去PHP-FPM日志里找Access denied或者open_basedir相关报错。都没有,就写一个echo "test";的纯PHP文件上去,看能不能输出。能输出说明环境正常,问题出在webshell代码本身;不能输出,就是配置层面的拦截。别一上来就怀疑杀软。我见过太多人把时间浪费在查杀软上,最后发现是Nginx一条正则匹配错了。杀软拦截通常返回403或者一个自定义的拦截页面,不会给你返回200加空白。
顶: 6踩: 37






评论专区