文件上传漏洞绕过方法

一、什么是文件上传漏洞

应用程序存在文件上传功能点,但是后台对用户上传的文件没有进行任何的安全校验或者校验机制不够严谨,导致攻击者可以上传恶意文件(Webshell、病毒)到服务器,进而执行恶意代码、获取服务器权限或进行其他恶意操作。

二、常见安全机制及绕过

为防御文件上传漏洞,开发者通常会实施以下检查:

1-客户端检查

许多开发者为了方便,使用JavaScript在浏览器校验文件类型,如.jpg.png.gif等。这种安全机制能减轻服务器压力,但是容易被绕过

常见绕过方法:

(1)禁用JavaScript

这是最直接的方法,在浏览器设置中直接禁用JS,能够直接关闭客户端检查,上传恶意文件

操作步骤:

  1. 先尝试上传php文件,浏览器弹窗不允许上传

  2. 判断是客户端检查,直接在浏览器禁用JavaScript

  3. 成功上传,执行命令

2-抓包再修改文件名

我们上传一个合法文件绕过客户端检查,burpsuite拦截数据包修改文件名为.php后缀。由于服务器后端没有二次验证,就会直接上传成功

  1. 我们将.php文件修改为.jpg,正常上传一个合法文件

  2. burpsuite拦截数据包,修改文件名

  3. 上传成功,回显phpinfo界面

2-MIME类型检测

服务器有时会通过检查HTTP请求头中的Content-Type字段来验证文件类型。例如,一个图片的Conent-Type字段为image/jpegimage/png

绕过方法:

(1)修改Content-Type

上传一个.php文件,同时使用burpsuite拦截数据包,看到Content-Typeapplication/octet-stream

将其修改为image/jpegimage/png

成功上传

3-文件内容检查

  • 检查文件头(Magic Number)是否匹配预期类型(如图片的FF D8 FF)。
  • 使用函数如getimagesize()验证图片有效性。
  • 使用exif_imagetype()检查是否为图片文件。

绕过方法

(1)伪造文件头

在文件开头添加预期格式的幻数(如GIF89a),使内容检查误判为GIF。

上传成功,访问链接为/upload/6420260312145040.gif,配合文件包含漏洞解析

(2)图片马绕过

使用工具将恶意代码附加到合法图片末尾,仍能通过getimagesize()等检查。
操作步骤

  1. 准备一张正常的图片(1.jpg)和一个包含恶意代码的文本文件(shell.php)

  2. 使用cmd命令将两者合并:copy /b 1.jpg shell.php webshell.jpg

  3. 上传文件,复制图片路径,配合文件包含漏洞来解析我们上传的图片马

图片马的制作方法:

  1. 文本方式打开图片直接粘贴一句话木马:将一个图片以文本格式打开(这里用的记事本方式打开修改,不过修改后图片无法正常显示了),后面粘贴上一句话木马

  2. cmd 命令行执行:在windows的cmd中执行,准备好一个jpg 图片 和一个 有恶意代码的php文件,执行命令

  3. 16进制编辑器打开图片,在末尾添加恶意代码:用winhex 打开图片,添加一句话木马 保存成功

4-文件扩展名黑名单

服务器通常会有一份黑名单或白名单来限制可上传的文件扩展名。

  • 黑名单 是禁止上传危险扩展名,如:.php.asp.jsp

(1)大小写绕过

原理 :未统一转换为小写,允许大小写混合绕过

上传一个shell.php恶意文件,我们可以使用大小写混淆的方法修改文件扩展名来绕过黑名单

复制代码
shell.Php
shell.pHp
shell.PHp

组合不止这些,可以自行补全

(2)特殊扩展名

某些服务器或脚本引擎支持非标准的扩展名,例如:

  • PHP:.php3.php4.php5.phtml.php7.phps(可能泄露源码)、.php-s等。
  • ASP:.asp.aspx.cer.asa.cdx
  • JSP:.jsp.jspx.jspf
  • Perl:.pl.cgi
    如果黑名单只列出了常见的.php.asp,而忽略了这些变体,攻击者可以利用它们上传可执行脚本。

    成功上传

(3)%00截断漏洞

此漏洞存在于PHP 5.3.4之前版本且magic_quotes_gpc关闭时。

攻击者在文件名后插入空字节(URL编码为%00),导致服务器在C语言级别处理文件名时截断后续内容。

  1. 上传shell.php%00.jpg
  2. 服务器解析时为:shell.php
  3. 文件系统保存为:shell.php

(4).htaccess 绕过

若允许上传.htaccess文件,可重写配置使图片文件被当作脚本解析。内容如下

复制代码
AddType application/x-httpd-php .png
  1. 攻击者上传:.htaccess
  2. 上传shell.png即可执行。

(5)双写后缀

如果过滤逻辑只是简单地将php字符串替换为空,双写会导致过滤后剩下php

复制代码
shell.pphphp

(6)利用文件系统特性

如果目标站点是Windows系统,可以利用文件系统的特性尝试绕过

  • 点绕过 :在Windows系统中,文件后缀名的最后一个点会自动去除,例如上传shell.php.(末尾带点),保存后可能变成shell.php
  • 空格绕过 :Windows系统也会自动去除文件名末尾的空格。例如,上传shell.php (末尾有空格),保存后变为shell.php,同样可能绕过黑名单检查。
  • 点绕过和空格绕过结合a.php . 一些黑名单实现可能只检查最后一个点之后的字符串,但遇到点和空格组合时,可能因空格而导致解析异常(如php. 被当作普通字符串),从而绕过检测。
  • ::data 绕过:在普通情况下,我们使用的文件只有一个默认的数据流,可以通过文件名访问。但是,在windows NT文件系统(NTFS)支持在文件内部创建额外的数据流,以存储其他信息。这些额外的数据流可以通过在文件名后面添加::$DATA来访问。

(7)双重扩展名绕过

双重扩展名(double extension),即文件名包含两个或多个点,如shell.php.jpg。双重扩展名绕过能否成功取决于两个阶段的不匹配

  • 过滤阶段:仅检查最后一个扩展名,忽略了前面的危险扩展名。

  • 执行阶段 :服务器或应用解析文件时,考虑了文件名中的其他部分,导致恶意代码被执行。
    模拟情景:

    1.我们上传一个shell.php.jpg
    2.校验机制只检查最后一个扩展名.jpg,成功上传文件到服务器
    3.某些Web服务器(如Apache的mod_mime模块)可能根据扩展名的出现顺序决定内容类型。若第一个扩展名(如.php)被识别为可执行脚本,而后续扩展名被忽略,则文件可能被解析为PHP。
    4.shell.php.jpg成功被解析为php文件执行

5-文件扩展名白名单

白名单 是允许上传安全扩展名,如:.jpg.png

(1)服务器解析漏洞

Apache

如果Apache的mime.types配置错误或开启了MultiViews,可能导致文件名如test.php.jpg被当作PHP解析(服务器可能从左至右匹配MIME类型,若第一个扩展名无法识别则尝试后续)。

IIS 6.0

目录解析漏洞,例如/xx.asp/shell.jpg,服务器会把shell.jpg当作ASP脚本执行

IIS 7.0/7.5

web.config配置文件解析漏洞。攻击者可以上传一个恶意的web.config文件来改变目录的解析规则

(2)竞争条件

一些服务器在处理文件是,会将文件临时保存,然后进行安全检查,最后再重命名或移动到目录
利用方法: 攻击者可以利用这个时间差,在文件被检查并删除之前迅速访问该文件
步骤:

  1. 上传个包含恶意代码的文件,其中恶意代码会创建一个新的Webshell文件
  2. 在文件上传成功后,但在服务器删除它之前,通过个脚本循环快速访问该文件
  3. 恶意文件被执行,并创建一个新的、无法被删除的Webshell文件

(3)配合文件包含漏洞

如果应用存在本地文件包含(LFI)漏洞,攻击者可上传一个扩展名安全的文件(如.jpg),但其内容包含PHP代码。随后通过LFI漏洞包含该文件,触发代码执行。

  • 利用方法: 上传shell.jpg,内容为<?php phpinfo(); ?>,并通过LFI访问/includes/index.php?page=uploads/shell.jpg(假设LFI可包含任意文件)。
  • 条件:应用中存在LFI漏洞,且上传目录在包含路径内。

(4)%00截断存储路径

%00截断(Null Byte Injection) 这是一个经典的漏洞,主要影响PHP 5.3.4之前的版本。

  • 条件: 服务端代码拼接文件路径和文件名,且路径信息可控。
  • 步骤:
    • 上传个包含恶意代码的shell.png,拦截数据包
    • 如果在数据包中存储路径可控,将path=../uploads/修改为path=../uploads/shell.php%00
    • 发送数据包到服务器
  • 执行过程
    • 服务端拼接出的最终保存路径是 ../uploads/shell.php%00image.jpg
    • 在C/C++等底层语言中,字符串以空字节(\0)作为结束符。
    • move_uploaded_file()函数在处理这个路径时,遇到空字节就认为路径已经结束,后面的image.jpg被忽略。
    • 最终,文件被保存为../uploads/shell.php,成功绕过了白名单对.jpg后缀的检查。
相关推荐
乐迪信息6 小时前
乐迪信息:AI算法盒子实时识别船舶烟雾与火焰异常
大数据·人工智能·算法·安全·目标跟踪
汤愈韬6 小时前
IPSec-NAT穿越原理和配置
网络·网络协议·安全·网络安全·security
JoyCong19988 小时前
ToDesk AI 正式登场:您的智能远程助手,积分新玩法科普
人工智能·安全·电脑·远程工作·远程操作
大方子8 小时前
【PolarCTF】导航栏
网络安全·polarctf
vortex59 小时前
AI Skill 设计:网络安全审计中的自主性与规范化博弈
人工智能·安全·web安全
zhangfeng113310 小时前
那nvidia orim车载gpu tee安全飞地 和天垓 100 gpgpu的 飞地 ,大概有多大存储量 ,解密流程
人工智能·深度学习·安全·语言模型·gpu算力·芯片
吹个口哨写代码10 小时前
前后端分离的安全补救措施
安全
网络研究院11 小时前
中国网络安全与数据保护领域政策与执法动态回顾(2026年4月)
网络安全·数据保护·执法·政策·回顾
网络研究院11 小时前
中国网络安全与数据保护领域政策与执法动态回顾(2026年2月)
网络安全·数据保护·法规·政策·回顾
zhangfeng113312 小时前
天数智芯天垓 100 加密大模型分布式部署安全方案
人工智能·分布式·安全·transformer·gpu算力·芯片