Erlo

文件上传漏洞

2025-03-06 22:29:02 发布   5 浏览  
页面报错/反馈
收藏 点赞

文件上传漏洞

文件上传漏洞是Web应用程序中常见的一种安全漏洞,它允许攻击者上传可以执行的文件到服务器上,从而可能控制整个服务器

以下是文件上传漏洞的基本原理:

  1. 正常的文件上传功能
    • 在很多Web应用中,如论坛、博客、在线编辑器等,都需要提供文件上传功能,允许用户上传图片、文档等文件
  2. 文件上传漏洞的产生
    • 当Web应用没有正确处理用户上传的文件时,就可能产生安全漏洞。以下是几个常见的漏洞点:
      • 缺乏有效的文件类型检查:应用没有检查或错误地检查了上传文件的MIME类型或文件扩展名
      • 不正确的文件名处理:应用在保存上传文件时没有正确处理文件名,可能允许攻击者通过在文件名中插入恶意代码来改变文件类型
      • 文件内容未检查:即使限制了文件类型,攻击者也可能上传含有恶意代码的文件,如图片中嵌入的Webshell
      • 目录遍历:攻击者可能利用目录遍历漏洞,将文件上传到Web目录之外的位置,例如服务器的系统目录
      • 不安全的文件存储:文件存储在服务器上时,如果权限设置不当,攻击者可能通过上传的文件获得对服务器其他部分的访问权限
  3. 利用文件上传漏洞
    • 攻击者通过上传一个可以执行的脚本文件(如PHP、ASP、JSP脚本)到服务器上
    • 如果服务器配置不当,允许执行上传的脚本文件,攻击者就可以通过该脚本执行任意命令,控制服务器
    • 攻击者可能会上传Webshell(一种网页形式的Shell),通过浏览器来执行系统命令

一句话木马

可执行脚本的文件后缀名,可被网站目录解析。以下是常见的后缀名

asp
asa
cdx
cer
php
aspx
ashx
jsp
php3
php.a
shtml
phtml
有些网站会对 asp 或者 php 进行过滤转成空可用这些后缀名。
aspasp asaspp
phpphp

一句话木马可以让服务器执行入侵者指定的命令

php的一句话木马: 
asp的一句话是:   
aspx的一句话是:   

木马文件的上传及绕过

绕过前端JS检测上传

​ 文件上传时,用户选择文件时,或者提交时,有些网站会对前端文件名进行验证,一般检测后缀名,是否为上传的格式。如果上传的格式不对,则弹出提示文字。此时数据包并没有提交到服务器,只是在客户端通过 js 文件进行校验,验证不通过则不会提交到服务器进行处理

绕过JS检测方法

  1. 按 F12 使用网页审计元素,把校验的上传文件后缀名文件删除,即可上传
  2. 把恶意文件改成 js 允许上传的文件后缀,如 jpg、gif、png 等,再通过抓包工具抓取 post 的数据包,把后缀名改成可执行的脚本后缀如php 、asp、jsp、net 等,即可绕过上传

绕过contnet-type检测上传

​ 有些上传模块,会对 http 的类型头进行检测,如果是图片类型,允许上传文件到服务器,否则返回上传失败。因为服务端是通过content-type 判断类型,content-type 在客户端可被修改。则此文件上传也有可能被绕过的风险

黑名单绕过上传

​ 上传模块,有时候会写成黑名单限制,在上传文件的时获取后缀名,再把后缀名与程序中黑名单进行检测,如果后缀名在黑名单的列表内,文件将禁止文件上传

​ 上传图片时,如果提示不允许 php、asp 这种信息提示,可判断为黑名单限制,上传黑名单以外的后缀名即可。 在 iis 里 asp 禁止上传了,可以上传 asa cer cdx 这些后缀,如在网站里允许.net执行 可以上传 ashx 代替 aspx。如果网站可以 执行这些脚本,通过上传后门即可获取 webshell。 在不同的中间件中有特殊的情况,如果在apache可以开启application/x-httpd-php, 在 AddType application/x-httpd-php .php .php3 .phtml后缀名为.phtml、.php3均被解析成php,有的apache版本默认开启。 上传目标中间件可支持的环境的语言脚本即可,如.phtml、php3

.htaccess重写解析绕过上传

上传模块,黑名单过滤了所有的能执行的后缀名,如果允许上传.htaccess。htaccess文件的作用是可以帮我们实现包括文件夹密码保护、用户自动重定向、自定义错误页面、改变你的文件扩展名、封禁特定 IP 地址的用户、只允许特定 IP 地址的用户、禁止目录列表,以及使用其他文件作为index文件等一些功能。在.htaccess里写入SetHandler application/x-httpd-php,则可以文件重写成php文件。 要 htaccess 的规则生效,则需要在apache开启rewrite 重写模块,因为apache是多数都开启这个模块,所以规则一般都生效

上传攻击

上传.htaccess到网站里,.htaccess 内容是


SetHandler application/x-httpd-php

再上传恶意的jpg到.htaccess相同目录里,访问图片即可获取执行脚本,当图片上传成功之后,即使格式是jpg的,也一样会被当成php脚本执行

大小写绕过上传

有的上传模块后缀名采用黑名单判断,但是没有对后缀名的大小写进行严格判断,导致可以更改后缀大小写可以被绕过

.user.ini绕过

自 PHP 5.3.0 起,PHP 支持基于每个目录的 .htaccess 风格的 INI 文件。此类文件仅被 CGI/FastCGI SAPI 处理。此功能使得 PECL 的 htscanner 扩展作废。如果使用 Apache,则用 .htaccess 文件有同样效果

.user.ini原理

.user.ini中两个中的配置就是_auto_prepend_file_和_auto_append_file_。这两个配置的意思就是:我们指定一个文件(如1.jpg),那么该文件就会被包含在要执行的php文件中(如index.php),相当于在index.php中插入一句:require(./1.jpg)。这两个设置的区别只是在于auto_prepend_file是在文件前插入,auto_append_file在文件最后插入。

利用.user.ini的前提是服务器开启了CGI或者FastCGI,并且上传文件的存储路径下有index.php可执行文件

利用.user.ini的环境

​ 有时候我们进行文件上传的时候,站点不仅在前端做了白名单处理,还在后端做了黑名单处理以及文件类型的检验且服务器没有配置"AddType application/x-httpd-php .php .phtml",这时我们就不能通过简单的绕过前端验证修改数据包的 Content-Type 并将文件后缀改为 phtml 以此来利用文件上传漏洞

​ 这时我们就需要利用.user.ini进行配合,使得我们上传的图片格式的webshell也能够被解析,以此成功利用漏洞拿到shell权限

auto_append_file=demo.jpg

该文件意思是无论访问当前目录下哪个 PHP 文件都会自动去包含 demo.jpg 这个文件

空格绕过上传

在上传模块里,采用黑名单上传,如果没有对空格进行去掉可能被绕过

利用 windows 系统特征绕过

在 windows 中文件后缀名的点“.”,系统会自动忽略。所以shell.php.和shell.php的效果一样。可以在文件名后面加上.绕过

NTFS 交换数据流::$DATA 绕过上传

如果后缀名没有对::$DATA 进行判断,利用 windows 系统 NTFS 特征可以绕过上传。 在window的时候如果文件名+::$DATA会把::$DATA之后的数据当成文件流处理,不会检测后缀名,且保持::$DATA之前的文件名,他的目的就是不检查后缀名

例如:phpinfo.php::$DATAWindows会自动去掉末尾的::$DATA变成phpinfo.php

利用 windows 环境的叠加特征绕过

在Windows操作系统中,文件系统有一定的规则来处理文件名。当一个文件以特定的方式命名时,比如 phpinfo.php:.jpg,Windows可能会截断或忽略文件名中某些特殊字符后面的部分。这是因为 : 在Windows中是一个用于表示卷标或驱动器的特殊字符,而在文件名中通常不被允许。当你尝试上传一个名为 phpinfo.php:.jpg 的文件时,Windows可能会将文件名截断为 phpinfo.php,因为 : 后面的部分被视为对文件系统的指令,而不是文件名的一部分。这样,就会在目录下创建一个名为 phpinfo.php 的空白文件

Windows的文件系统中,以下符号在正则匹配时可能被视为相等:

  • 双引号 " 等于 点号 .
  • 大于符号 > 等于 问号 ?
  • 小于符号 等于 星号 *

文件名.、文件名.、文件名.>>>文件名.>> 时,这些是在尝试利用Windows文件系统的特性来创建特殊的文件名,这些文件名会在文件系统中被解释为不同的东西,或者导致文件名的一部分被忽略

双写后缀名绕过

在上传模块,有的代码会把黑名单的后缀名替换成空,例如 a.php 会把 php 替换成空,但是可以使用双写绕过例如 asaspp,pphphp,即可绕过上传

目录可控 %00 截断绕过

目录可控是指在文件上传功能中,我们可以控制文件上传的目录路径。在某些情况下,即使服务器使用了白名单来验证上传文件的扩展名,攻击者仍然可能通过目录控制来绕过安全措施

截断原理:在C语言和许多基于C的编程语言中,字符串以空字符(NULL,即 %00)结尾。如果服务器端的代码在处理文件名时没有正确处理空字符,攻击者可以在文件名的某个位置插入 %00,使得服务器在处理文件名时只看到 %00 字符之前的部分

绕过白名单: 假设服务器使用白名单验证上传文件的扩展名,只允许 .jpg.png 等图片格式。如果攻击者可以控制上传路径,并且服务器在处理路径时没有正确地过滤 %00 字符,攻击者可以构造一个特殊的文件名,例如 malicious.php%00.jpg

上传攻击:

  • 攻击者上传文件 malicious.php%00.jpg
  • 服务器在处理文件名时,可能会将文件名截断为 malicious.php,因为它在 %00 字符处停止读取字符串
  • 如果服务器只检查文件名的扩展名部分(即 .jpg),它可能会认为这是一个合法的图片文件,并将其保存到服务器上
  • 由于文件名被截断,实际上保存的文件是 malicious.php,这是一个PHP脚本文件,而不是图片

目录可控的POST绕过

上面是 GET 请求的,可以直接在 url 输入%00 即可截断,但是在 post 下直接注入%00 是不行的,需要把%00 解码变成空白符,截断才有效。才能把目录截断成文件名

文件头检测绕过

有的文件上传,上传时候会检测头文件,不同的文件,头文件也不尽相同。常见的文件上传图片头检测,它检测图片是两个字节的长度,如果 不是图片的格式,会禁止上传,常见的文件头:

  1. JPEG (JPG) 文件
    • 文件头: FF D8 FF
  2. PNG 文件
    • 文件头: 89 50 4E 47 0D 0A 1A 0A
  3. GIF 文件
    • 文件头: 47 49 46 38 (GIF89a) 或者 47 49 46 38 37 61 (GIF87a)
  4. PDF 文件
    • 文件头: %PDF-
  5. ZIP 文件
    • 文件头: 50 4B 03 04 (压缩的ZIP文件) 或者 50 4B 05 06 (未压缩的ZIP文件)
  6. Microsoft Office 文件
    • Word文档 (.doc): D0 CF 11 E0 A1 B1 1A E1
    • Word文档 (.docx): 50 4B 03 04 14 00 06 00
    • Excel电子表格 (.xls): D0 CF 11 E0 A1 B1 1A E1
    • Excel电子表格 (.xlsx): 50 4B 03 04 14 00 06 00
    • PowerPoint演示文稿 (.ppt): D0 CF 11 E0 A1 B1 1A E1
    • PowerPoint演示文稿 (.pptx): 50 4B 03 04 14 00 06 00
  7. TIFF 文件
    • 文件头: 49 49 2A 00 (小端) 或者 4D 4D 00 2A (大端)
  8. MP3 文件
    • 文件头: 49 44 33 后面通常跟着 2E 00 或者其他标识版本和层的信息
  9. AVI 文件
    • 文件头: 52 49 46 46 (RIFF) 紧接着是 41 56 49 20 (AVI )
  10. BMP 文件
    • 文件头: 42 4D

图片检测函数绕过

getimagesize 是获取图片的大小,如果头文件不是图片会报错直接可以用图片马绕过检测

绕过图片二次渲染

有些图片上传,会对上传的图片进行二次渲染后在保存,体积可能会更小,图片会模糊一些,但是符合网站的需求。例如新闻图片封面等可能需要二次渲染,因为原图片占用的体积更大。访问人数太多时候会占用很大带宽。二次渲染后的图片内容会减少,如果里面包含后门代码,可能会被省略。导致上传的图片马,恶意代码被清除

绕过方式:

首先判断图片是否允许上传 gif,gif 图片在二次渲染后,与原图片差别不会太大。所以二次渲染攻击最好用 gif图片马。 制作图片马: 将原图片上传,下载渲染后的图片进行对比,找相同处,覆盖字符串,填写一句话后门,或者恶意指令。 使用工具:HxDHexEditor2.3.0.0

条件竞争绕过文件删除

条件竞争漏洞(Race condition)官方概念是——竞争条件发生在多个线程同时访问同一个共享代码、变量、文件等没有进行锁操作或者同步操作的场景中。服务器对上传文件的操作大多数都是单线程处理,当我们执行多个线程时可以绕过一些服务器端的防御。 这里使用了unlink函数来删除不符合的文件,但代码执行的过程是需要耗费时间的。如果我们能在上传的一句话被删除之前访问就可以了。这个也就叫做条件竞争上传绕过

通用检测方法

判断是否为黑白名单,如果是白名单 寻找可控参数。如果是黑名单禁止上传,可以用有危害的后缀名批量提交测试,寻找遗留的执行脚本

.php
.php5
.php4
.php3
.php2
.html
.htm
.phtml
.pht
.pHp
.phP
.pHp5
.pHp4
.pHp3
.pHp2
.Html
.Htm
.pHtml
.jsp
.jspa
.jspx
.jsw
.jsv
.jspf
.jtml
.jSp
.jSpx
.jSpa
.jSw
.jSv
.jSpf
.jHtml
.asp
.aspx
.asa
.asax
.ascx
.ashx
.asmx
.cer
.aSp
.aSpx
.aSa
.aSax
.aScx
.aShx
.aSmx
.cEr
.sWf
.swf
.htaccess

使用 burpsuite 抓包上传将后缀名设置成变量,把这些文件设置成一个字典批量提交

数组绕过

在PHP中,如果程序不严格验证用户输入,攻击者可能会通过提供非预期的数组结构来绕过安全限制。在该PHP代码示例中,存在一个安全漏洞,因为它直接使用了用户通过GET请求提供的save_name参数,而没有进行适当的验证


  1. 直接使用用户输入
    • 代码没有对$file变量进行任何形式的验证,直接使用用户输入可能会导致安全问题
  2. 数组处理
    • reset($file)函数返回数组的第一个元素
    • $file[count($file) - 1]尝试获取数组的最后一个元素

如果攻击者控制了$file数组,他们可以通过以下方式绕过文件类型检查:

  • 攻击者可以发送一个数组,其第一个元素是期望的文件名,最后一个元素是.php(或其他可执行文件扩展名)
  • 由于Windows系统会自动删除文件名末尾的.,攻击者可以利用这一点来绕过文件扩展名的限制

假设攻击者发送以下GET请求:

http://example.com/upload.php?save_name[0]=image-20240128185152767&save_name[2]=php

在这个例子中,reset($file)将返回image-20240128185152767,而$file[count($file) - 1]将返回php。生成的文件名将是image-20240128185152767.php

在Windows中,如果文件名以.结尾,系统会自动删除这个.,所以如果攻击者发送:

http://example.com/upload.php?save_name[0]=image-20240128185152767&save_name[2]=

生成的文件名将是image-20240128185152767.,Windows会将其保存为image-20240128185152767,没有扩展名。

中间件特性

  • nginx 0.83 /1.jpg%00php
  • apahce 1x 或者 2x
    • 当 apache 遇见不认识的后缀名,会从后向前解析例如 1.php.rar 不认识 rar 就向前解析,直到知道它认识的后缀名
  • phpcgi 漏洞(nginx iis7 或者以上) 上传图片后 1.jpg。访问 1.jpg/1.php 也会解析成php
  • Apache HTTPD 换行解析漏洞(CVE-2017-15715)apache 通过 mod_php 来运行脚本,其 2.4.0-2.4.29 中存在 apache 换行解析漏洞,在解析 php 时 xxx.phpx0A 将被按照 PHP 后缀进行解析,导致绕过一些服务器的安全策略

文件上传漏洞的防御方法

  1. 服务端使用白名单防御
  2. 修复web中间件的漏洞
  3. 禁止客户端存在可控参数
  4. 存放文件目录禁止脚本执行
  5. 限制后缀名,一定要设置图片格式 jpg、git、png
  6. 文件名是随机的不可预测

登录查看全部

参与评论

评论留言

还没有评论留言,赶紧来抢楼吧~~

手机查看

返回顶部

给这篇文章打个标签吧~

棒极了 糟糕透顶 好文章 PHP JAVA JS 小程序 Python SEO MySql 确认