游客发表
一个网站如果允许用户上传文件,任意却没把上传后的文件处理逻辑做严实,攻击者就能往服务器里塞一个后门脚本。上传这个脚本可能是漏洞 PHP、JSP、任意ASP 或者 Python,文件具体取决于服务器跑什么环境。上传传上去之后,漏洞攻击者只需要在浏览器里访问这个文件的任意 URL,服务器就会老老实实执行它——相当于把服务器的文件控制权拱手让人。
这事听起来像个低级错误,上传但每年都在发生。漏洞2023 年某国内中型电商平台被拖库,任意起因就是文件一个促销活动页面的图片上传接口。开发图省事,上传前端只检查了文件扩展名,后端压根没验证。攻击者把 shell.php 改成 shell.jpg 上传,服务端存的时候又没重命名,直接按原始文件名落盘。更巧的是那个上传目录恰好可以被 Web 服务器解析 PHP。一个请求下去,whoami 直接返回 www-data。从上传到拿到服务器权限,前后不到三分钟。
拿到 WebShell 只是第一步。攻击者通常会先看 /etc/passwd,确认系统版本和用户情况。然后翻网站配置文件,找数据库连接字符串——很多开发者把数据库密码明文写在 config.php 里。数据库一旦失守,用户表、订单表、支付记录全部暴露。2022 年某招聘网站泄露 800 万条简历数据,溯源结果就是上传漏洞导致 WebShell 被植入,攻击者在内网横向移动了将近两周才被发现。
更麻烦的是,上传漏洞往往不是孤立存在的。它像一个入口,进去之后能做的事情取决于服务器权限配置有多松懈。有些服务器跑着老版本的 Linux 内核,本地提权 exp 一打一个准。有些服务器上还跑着 Redis 或者 MySQL,攻击者可以直接用 WebShell 连上去,不需要额外密码——因为 bind 了 127.0.0.1 就以为安全了,但 WebShell 本身就在本机。这种“内网信任”的假设在真实攻防里基本等于不设防。
还有一种情况容易被忽略:攻击者不一定要传 WebShell。传一个 .htaccess 文件,把 .jpg 文件当 PHP 解析,一样能执行代码。或者传一个巨大的文件把磁盘塞满,导致服务不可用。甚至传一个包含恶意宏的 Office 文档,等着管理员下载打开。上传接口的滥用方式比大多数人想象的要多。
我见过一个案例,某政府单位门户网站的上传功能只允许 jpg|png|gif,前端 JavaScript 校验,后端也校验了 MIME 类型。看起来挺严。但后端校验逻辑写的是 if content_type in ['image/jpeg', ...],而 MIME 类型是客户端发过来的,攻击者用 Burp Suite 抓包改一下 Content-Type 头就绕过了。文件内容还是 PHP 代码,扩展名改成 .php 照样传上去了。这种“校验了但没完全校验”的情况,比完全不校验更危险——因为开发者觉得自己已经做了防护,后续运维就不再关注这个接口。
修复上传漏洞不是加一个白名单就完事。文件要重命名,不能保留用户提供的文件名。上传目录要禁止脚本执行权限,Nginx 里加一条 location ~* /uploads/.*\.(php|jsp|asp)$ { deny all; } 就能挡掉大部分低级攻击。文件内容要做魔数校验,不能只看扩展名和 MIME。上传后的文件最好存到对象存储或者独立域名下,跟主站完全隔离。这些措施叠在一起,才能把风险压到可接受的范围。
但现实是,很多团队连第一步都没做到。上传接口写完能跑通就上线了,安全测试排在功能测试后面,功能测试又排在性能测试后面。等漏洞被利用、数据被拖走、勒索信出现在服务器桌面上,才想起来回头查代码。那时候损失已经发生了,补漏洞只是亡羊补牢。
友情链接