当前位置: 当前位置:首页 > 百科 > 文件上传漏洞实验正文

文件上传漏洞实验

作者:知识 来源:探索 浏览: 【大 中 小】 发布时间:2026-10-17 06:11:21 评论数:

我把一个PHP文件改名成shell.jpg,文件上传到目标站点的上传实验头像功能里。服务器没有报错,漏洞文件静静躺在/uploads/目录下。文件我访问它,上传实验浏览器把它当图片渲染——一片空白。漏洞但当我用Burp Suite拦截请求,文件把Content-Type改成text/php再发一次,上传实验服务器就乖乖执行了里面的漏洞代码。

这个实验我做了不下二十次。文件每次看到那个空白页面变成一串uid=33(www-data)的上传实验输出,我都会想:就这么简单?漏洞是的,就这么简单。文件文件上传漏洞不是上传实验高深莫测的魔法,它就是漏洞服务器对用户太信任,把“看起来像图片”的文件当成了图片。

漏洞的核心在于三个环节的脱节。前端只检查了文件扩展名——这是最脆弱的防线。用十六进制编辑器在图片末尾追加一段PHP代码,扩展名保持.jpg,前端检查直接通过。后端如果只依赖getimagesize()验证图片头,依然能骗过——因为文件开头确实是FF D8 FF E0,真正的JPEG头。真正致命的是服务器配置,Apache的AddType指令可能把.jpg也解析成PHP,或者Nginx的错误配置让/uploads/1.jpg/xxx.php这种路径直接命中FastCGI。

我试过更刁钻的方式。把文件命名为shell.php.jpg,Apache的mod_mime会从右往左匹配,优先识别.jpg,安全。但换到IIS 6.0,分号截断漏洞让shell.php;.jpg直接被当作PHP执行——老系统就像漏水的船,每个裂缝都能进海水。

那次实验最让我意外的是,目标站点的开发者其实做了防护。他们用白名单限制扩展名,还重命名了文件。但上传目录没有关闭脚本执行权限——就这么一个疏忽,我上传的.php文件直接落地生根。重命名?我用../shell.php路径穿越绕过了目录限制,文件最终写到了web根目录。

防御手段其实不复杂。最有效的是随机化文件名并存储到独立域名,让用户无法预测路径。其次,上传目录必须SetHandler None,彻底禁止脚本执行。还有一招是服务端二次渲染——重新编码图片,剥离所有非图像数据。但这招会破坏动图,所以很多站点宁可不做。

实验做完,我删掉了所有测试文件。但那个空白页面变成代码输出的瞬间,像一道光劈进脑子里:安全不是靠某个环节的严防死守,而是整条链路每个节点都默认“用户不可信”。你堵住扩展名,他绕路径;你堵住路径,他上传图片马;你连图片马都堵住,他还能用phar://协议触发反序列化。这场猫鼠游戏永远没有终点,但至少,把最基本的脚本执行权限关掉,就能挡住九成攻击者。