游客发表
凌晨两点,我的洞修服务器警报响了。日志里躺着一条异常的传漏上传记录——一个伪装成图片的PHP文件,成功落进了`/uploads/avatar/`目录。洞修那一刻我意识到,传漏FineCMS的洞修某个上传接口又被“问候”了。这不是传漏第一次,也绝不会是洞修最后一次。
FineCMS的传漏上传漏洞,核心问题从来不在“上传”本身,洞修而在“信任”。传漏系统默认信任了文件名、洞修信任了MIME类型、传漏信任了Content-Type头。洞修攻击者只需要把`shell.php`改名成`shell.jpg.php`,传漏再手动改一下HTTP请求里的Content-Type为`image/jpeg`,就能骗过那些只做表面校验的过滤器。更狠的是,有些版本连文件扩展名白名单都没写全,直接放行`.php5`、`.phtml`这种冷门后缀。
修复第一刀,必须砍向扩展名校验。别再用黑名单了,那玩意儿永远堵不完。改成白名单,只允许`.jpg`、`.jpeg`、`.png`、`.gif`这四个。代码写死,别从数据库读配置——万一后台被入侵,配置早就被改得面目全非。同时,强制用`pathinfo()`函数取真实扩展名,别信用户提交的`filename`参数。有人会问,那上传图片马怎么办?图片马要执行,还得配合解析漏洞,只要服务器Nginx/Apache配置正确,不让图片目录解析PHP脚本,就断了这条路。
第二刀,切掉文件内容校验。光看扩展名还不够,得读文件头。JPEG的`FF D8 FF`,PNG的`89 50 4E 47`,这些二进制特征骗不了人。用`getimagesize()`函数,它不仅能返回图片尺寸,还会验证文件是否真的是一张图。如果返回false,直接拒绝。这一招能挡掉90%的简单伪造。但别高兴太早,有些攻击者会把PHP代码藏在图片的EXIF信息里,配合其他漏洞触发。所以,上传后必须重命名文件,用`uniqid()`加随机串生成新名字,彻底打乱攻击者对文件路径的预判。
第三刀,也是最容易忽略的一刀——目录执行权限。很多站长把上传目录和站点根目录混在一起,或者给`/uploads`开了`ExecCGI`权限。正确的做法是,上传目录要放在Web根目录之外,或者至少用Nginx的`location`规则单独禁止该目录执行PHP。写一段配置:`location ~* /uploads/.*\.(php|php5|phtml)$ { deny all; }`。这行配置,比你在代码里写一百个if判断都管用。我见过太多人死磕代码,却忘了服务器层面的基础防护。
修复完代码,别急着收工。去翻FineCMS的官方GitHub仓库,看看最新的commit里有没有针对上传类的补丁。这个系统已经停止维护了,但历史上爆出的CVE列表还在。把已知的漏洞编号挨个对照,比如CVE-2020-12345这种,确认自己的版本是否中招。如果官方没修,那就自己写补丁——直接在入口文件`index.php`里加一段全局拦截,检查所有`$_FILES`变量,过滤掉可疑扩展名和内容。虽然粗暴,但有效。
最后说个真实案例。上个月我帮一个客户修站,他的FineCMS被植入了一个后门文件,藏在`/cache/`目录下,文件名是`cache_2024.php`。这文件怎么进去的?就是通过后台的模板上传功能——那个接口根本没做任何校验。我清掉后门后,顺手把整个`/cache`目录的写权限去掉,改成只读。攻击者再想上传,连权限都没有。这提醒我们,修复漏洞不能只看单个接口,要顺藤摸瓜,把所有能写文件的入口全部过一遍筛子。
漏洞修完,不代表万事大吉。FineCMS这种老系统,就像漏水的旧船,补好一个洞,旁边可能又锈穿一个。最稳妥的方案,是把它换成还在维护的现代CMS,或者至少用WAF(Web应用防火墙)挡在前面。如果实在换不了,那就定期扫描上传目录,看有没有突然多出来的可疑文件。我用一个简单的cron任务,每天凌晨把上传目录的文件列表发到自己邮箱,扫一眼,安心。
别指望一次修复就能永绝后患。安全是个持续对抗的过程,你得比攻击者多想一步——他们今天能打穿上传,明天就可能盯上别的入口。保持警惕,勤打补丁,才是正经事。
友情链接