PHPCSv960任意文件上传漏洞修复
作者:百科 来源:休闲 浏览: 【大 中 小】 发布时间:2026-10-17 06:42:31 评论数:
PHPCSv960这个版本号听着挺正经,任意实际上就是文件一套被人扒了底裤的老旧后台系统。我上周刚帮一个客户收拾烂摊子,上传他们的漏洞服务器被人塞了个webshell,日志里全是修复POST请求,目标路径清一色指向/public/upload/。任意查了半天,文件罪魁祸首就是上传那个文件上传接口——它只校验了Content-Type头,没校验文件内容,漏洞也没限制扩展名。修复
攻击者用Burp Suite改了包,任意把image/jpeg改成text/plain都不需要,文件直接上传一个.php文件,上传后端就傻乎乎地收下了。漏洞更蠢的修复是,上传目录居然有执行权限。这种漏洞修复起来其实不复杂,但得动几处关键代码。
先把入口文件upload.php里那段正则找出来。原来写的是if(preg_match('/jpg|jpeg|png|gif/', $ext)),这玩意儿只匹配扩展名,攻击者改成.php.jpg就能绕过。改成白名单校验,用in_array()配合strtolower(),把允许的扩展名列死。别用黑名单,黑名单永远堵不全。
再处理文件内容。用getimagesize()检查文件头,这函数对图片会返回数组,对PHP脚本返回false。但注意,有些图片马会伪造文件头,所以还得配合exif_imagetype()看真实MIME类型。我见过有人只加getimagesize(),结果被一个GIF89a头骗过去,照样执行代码。
上传目录的执行权限也得改。在Apache配置里对/upload/目录加上php_admin_flag engine off,或者用Nginx的location ~ \.php$ { deny all; }。这步很多人忽略,觉得前面校验够了。实际上纵深防御才是正道,就算上传接口被绕过,脚本也跑不起来。
还有个小坑,PHPCSv960的老版本会把上传文件名直接拼到路径里,没做随机化处理。攻击者能预测文件名,直接访问/upload/shell.php。改成用uniqid()或md5(time())生成随机名,别用原始文件名。这个改动成本极低,但能挡掉一大半自动化扫描。
最后,改完代码得重启PHP-FPM,不然旧配置还在内存里。我见过有人改完文件不重启,然后一脸懵地说“没用”。另外,把上传目录里的历史垃圾文件清一遍,那些残留的shell可能还挂在上面。用find /upload -name "*.php" -delete这种命令过一遍,别心疼,该删就删。
这套修复下来,半小时就能搞定。但真正的教训是,别迷信版本号,PHPCSv960这种老古董,漏洞多得跟筛子似的,能升级就升级,不能升级就老老实实把入口管死。
