了解一个安全漏洞丨文件上传漏洞
概述
文件上传功能本身不是漏洞,漏洞在于对用户上传文件的内容、类型、大小、存储位置、访问方式缺乏足够的安全校验。
常见后果
Webshell 植入:上传脚本文件,远程执行系统命令,彻底控制服务器。
钓鱼/挂马:上传 HTML/JS 文件,对访问者进行钓鱼或植入恶意代码。
存储型 XSS:上传包含恶意脚本的 SVG、HTML 等,触发跨站脚本攻击。
服务器资源耗尽:上传超大文件或压缩炸弹(zip bomb),造成拒绝服务。
覆盖关键文件:结合路径穿越,覆盖系统配置文件或计划任务,实现提权或持久化。
常见检查点
前端JS校验
在上传前用 JavaScript 校验文件扩展名、大小,不合法就阻止表单提交。
绕过方法:
若只依靠前端JS,则可以抓包直接发送恶意文件,从而绕过前端校验。
Content-Type校验
后端读取 HTTP 请求头中Content-Type字段,判断是否为允许的类型。(如image/jpeg)
绕过方法:
同样可以抓包绕过,将Content-Type修改成允许的类型即可
文件扩展名校验
黑名单
这是最容易被绕过的校验之一。黑名单机制是列出不允许的扩展名,但名单很难全面覆盖。
绕过方法:
主要通过黑名单漏过的禁用通过。比如大小写(Windows不区分,Linux区分)、双扩展名、特殊后缀(.pht、.php3等等)、末尾加点或者空格、空字节截断(适用早期PHP)
白名单
白名单本是最安全的后缀管控方式,但若仅单纯校验后缀,而服务器存在“解析漏洞”,依然会沦陷。
白名单的绕过配合解析漏洞实现
Apache .htaccess覆盖:上传.htacccess文件,内容为"AddType application/x-httpd-php.jpg",使该目录下所有.jpg文件都当做PHP文件执行。
Apache位置扩展名解析:碰到不识别的扩展名,Apache 可能从右往左查找已知类型。
......
文件头校验
读取文件最开头的几个字节,与预定义的签名比较,判断真实类型。
若后端通过读取文件前几个字节来验证类型,可以在 Webshell 代码前附加合法文件头。这样既通过文件头检查,又保留了可执行内容。
文件内容校验
这是更深的防线,检查文件内容本身是否包含恶意代码。
常见:基于正则/关键字匹配、杀毒软件扫描、二次渲染
对于绕过二次渲染,可以在不破坏原始图像数据区域的前提下,将恶意代码隐藏在注释段或未被处理的数据块中,确保重渲染后依然存在
存储路径与访问控制
路径穿越
如果后端将用户上传的用户名直接拼入存储路径,则攻击者可用../来跳出预定目录
存储位置
若在Web根目录内:攻击者直接通过URL访问,一旦执行条件具备就被拿下
若在Web根目录外:无法通过 URL 直接访问,必须由专门脚本读取并输出。这能极大降低风险
其他绕过方式
压缩包上传绕过
上传恶意的包.zip、.tar,服务器自动解压后恶意文件就完成落地。如果解压逻辑没有对目录穿越(../)进行过滤,则可以安装到任意目录。
XML实体注入
上传 SVG 或 XLSX 等 XML 结构文件,若解析器未禁用外部实体,可导致 SSRF、文件读取等。
典型的SVG注入:
<?xml version="1.0"?> <!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]> <svg>&xxe;</svg>无文件Webshell
上传配置文件(如 Nginx 配置、.htaccess),配合内存马技术,不落地脚本文件也能维持控制。
