文件上传漏洞

admin
3
2025-05-24

文件上传漏洞

文件上传漏洞原理

一些web应用程序中允许上传图片、视频、头像和许多其他类型的文件到服务器中。

文件上传漏洞就是利用服务端代码对文件上传路径变量过滤不严格将可执行的文件上传到一个到服务器中 ,再通过URL去访问以执行恶意代码。

危害

非法用户可以利用上传的恶意脚本文件控制整个网站,甚至控制服务器。这个恶意的脚本文件,又被称为WebShell,也可以将WebShell脚本称为一种网页后门,WebShell脚本具有非常强大的功能,比如查看服务器目录、服务器中的文件,执行系统命令等。

检测与绕过

无验证

直接上传一句话木马或者WebShell脚本即可。

客户端检测(Javascript检测)

在网页上写一段Javascript脚本,效验文件上传的后缀名,有白名单形式也有黑名单形式。如果上传文件的后缀不被允许,则会弹窗告知,此时文件上传的数据包并没有发送到服务端,只是在客户端浏览器使用Javascript对数据包进行检测。

这时有两种方法可以绕过客户端Javascript的检测:

  • 使用浏览器插件,删除检测文件后缀的Javascript代码,然后上传文件即可绕过

  • 首先把需要上传的文件后缀改成允许上传的文件类型,如jpg、png、gif等,绕过Javascript检测,再抓包,把后缀名改成可执行文件的后缀即可上传成功

服务端检测

检查后缀

MINE类型检测-白名单

MIME (Multipurpose Internet Mail Extensions) 是描述消息内容类型的因特网标准。

服务器代码判断$_FILES”file“是不是图片格式(image/jpegimage/pngimage/gif),如果不是,则不允许上传该文件。

绕过方法:

抓包后更改Content-Type为允许的类型绕过该代码限制,比如将php文件的Content-Type:application/octet-stream修改为image/jpegimage/pngimage/gif等就可以

常见MIMETYPE

MIME TYPE

中文解释

audio/mpeg -> .mp3

音频/MPEG -> .mp3

application/msword -> .doc

应用程序/msword -> .doc

application/octet-stream -> .exe

应用程序/八位字节流 -> .exe

application/pdf -> .pdf

应用程序/pdf -> .pdf

application/x-javascript -> .js

应用程序/x-javascript -> .js

application/x-rar -> .rar

应用程序/x-rar -> .rar

application/zip -> .zip

应用程序/zip -> .zip

image/jpeg -> .jpg / .jpeg

图像/jpeg -> .jpg / .jpeg

image/gif -> .gif

图像/gif -> .gif

image/png -> .png

图像/png -> .png

text/plain -> .txt

文本/纯文本 -> .txt

text/html -> .html

文本/html -> .html

video/mp4 -> .mp4

视频/mp4 -> .mp4

同意义后缀绕过-黑名单

绕过方法:

语言

可解析后缀

asp/aspx

asp、aspx、asa、asax、ascx、ashx、asmx、cer

php

php、php5、php4、php3、php2、phtml、pht

jsp

jsp、jspa、jspx、jsw、jsv、jspf、jhtml

上传.htaccess让-黑名单

绕过方法:

重写文件解析规则绕过。上传先上传一个名为 .htaccess 文件,内容如下

<FiileMatch "04.jpg">
SetHandler application/x-httpd-php
</FiileMatch>

再上传一个4.jpg文件,即以 PHP 文件进行解析。

后缀大小写绕过-黑名单

绕过方法: .phP

空格绕过-黑名单

利用 Windows 系统的文件名特性。文件名最后增加点和空格,写成06.php[空格] ,

上传后保存在 Windows 系统上的文件名最后的一个 . 会被去掉,实际上保存的文件名就是 06.php

点绕过-黑名单

原理同 Pass-06,文件名后加点,改成 07.php.

::$DATA绕过-黑名单

Windows 文件流特性绕过,文件名改成 08.php::$DATA,上传成功后保存的文件名其实是 08.php

php 在 window 环境下,如果文件名 + ::$DATA 会把 ::$DATA 之后的数据当成文件流处理,不会检测后缀名,且保持 ::$DATA 之前的文件名

双写文件名绕过-黑名单

双写文件名绕过,文件名改成 10.pphphp

%00 截断-白名单

设置上传路径为upload/12.php%00 ,添加12.php%00内容为了控制路径,上传文件后缀为白名单即可 例:12.png,保存后为/upload/12.php%00*****.png,但服务端读取到%00时会自动结束,将文件内容保存至12.php中

0x00截断-白名单

但因为是POST型,需要对%00进行解码或在16进制中修改,POST不会像GET那样对%00进行自动解码。

检查内容

文件头检查

Png图片文件包括8字节:89 50 4E 47 0D 0A 1A 0A。即为 .PNG Jpg图片文件包括2字节:FF D8。 Gif图片文件包括6字节:47 49 46 38 39|37 61 。即为 GIF89(7)a。 Bmp图片文件包括2字节:42 4D。即为 BM

图片马制作: 在cmd里执行 copy logo.jpg/b+test.php/a test.jpg

getimagesize()检查

getimagesize() 函数用于获取图像大小及相关信息,成功返回一个数组,失败则返回 FALSE 并产生一条 E_WARNING 级的错误信息。 主要是针对*.php直接更改文件后缀为图片后缀,上一题创建的图片马仍然可以使用。

exif_imagetype()检查

exif_imagetype()读取一个图像的第一个字节并检查其后缀名。 返回值与getimage()函数返回的索引2相同,但是速度比getimage快

二次渲染

条件竞争

动物装饰