一、不安全的文件上传漏洞概述

        因为业务功能需要,很多 web 站点都有文件上传的接口,比如:注册时上传头像图片(比如 jpg,png,gif 等)、上传文件附件(doc,xls 等)

        而在后台开发时并没有对上传的文件功能进行安全考虑或者采用了有缺陷的措施,导致攻击者可以通过一些手段绕过安全措施从而上传一些恶意文件(如:一句话木马)从而通过对该恶意文件的访问来控制整个 web 后台

二、文件上传漏洞测试流程

(1)对文件上传的地方按照要求上传文件,查看返回结果(路径,提示等)

(2)尝试上传不同类型的 “恶意” 文件,比如 xx.php 文件,分析结果

(3)查看 html 源码,看是否通过 js 在前端做了上传限制,可以绕过

(4)尝试使用不同方式进行绕过:黑白名单绕过 / MIME 类型绕过 / 目录 0x00 截断绕过等

(5)猜测或者结合其他漏洞(比如敏感信息泄露等)得到木马路径,连接测试

三、文件上传漏洞--客户端验证

(1)基本原理

        客户端验证主要依靠 前端 JavaScript 代码 实现,在文件实际发送到服务器前,先对文件后缀名、类型等进行检查。若不符合预设规则(比如限定只能传 jpg、png 等图片格式),就阻止文件上传操作,且后端代码未做额外检测 ,因此,绕过客户端验证的要点在于绕过前端代码的检测

(2)操作步骤

        1、通过win10虚拟机进入pikachu靶场,进入 Unsafe Fileupload -->client check,选择一个文件上传(这里选择上传之前的yijuhua.php)

出现报错,打开开发者工具-->控制台,查看页面代码:

以此可以分析该网站的执行逻辑:通过在前端执行函数 checkFileExt()来判断文件上传的内容,并对此进行限制,因此,只要对该函数中的参数(即文件名)进行修改,便可绕过前端,达到上传我们想要的文件的目的

        2、将文件修改为 yijuhua.png,打开burpsuite监听,选择上传,burpsuite会将其截获:

        3、点击Action-->Send to Repeater,将文件名字修改为yijuhua.php,点击send:

        4、上传成功

四、文件上传漏洞--MIME

(1)MIME简介

        MIME (Multipurpose Internet Mail Extensions) 多用途互联网邮件扩展类型,是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开,多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式,

          每个 MIME 类型由两部分组成,前面是数据的大类别,例如声音 audio、图象 image 等,后面定义具体的种类常见的 MIME 类型,比如:

超文本标记语言文本 .html,.html text/html
普通文本 .txt text/plain
RTF 文本 .rtf application/rtf
GIF 图形 .gif image/gif
JPEG 图形 .ipeg,.jpg image/jpeg

(2)MIME漏洞

而漏洞的形成是通过以下函数进行实现的:$_FILES()函数

通过使用 PHP 的全局数组 $_FILES,便在从客户计算机向远程服务器上传文件时,获取文件的信息

第一个参数是表单的 input name,第二个下标可以是 "name", "type", "size", "tmp_name" 或 "error"。

就像这样:

- $_FILES["file"]["name"] - 被上传文件的名称

- $_FILES["file"]["type"] - 被上传文件的类型

- $_FILES["file"]["size"] - 被上传文件的大小,以字节计

- $_FILES["file"]["tmp_name"] - 存储在服务器的文件的临时副本的名称

- $_FILES["file"]["error"] - 由文件上传导致的错误代码

(2)操作步骤

        1、通过win10虚拟机进入pikachu靶场,进入 Unsafe Fileupload -->MIME type,选择一个文件上传(这里选择上传之前的yijuhua.png)

2、打开burpsuite监听,选择上传,burpsuite会将其截获:

3、将文件名修改为yijuhua.php,点击 Forward

4、成功

五、文件上传漏洞--getimagesize

(1)getimagesize()简介

        getimagesize()返回结果中有文件大小和文件类型,可以用这个函数来获取类型:通过读取文件十六进制代码的前几个字符串,来判断该文件是否为图片(同一格式的图片如png、jpg,其头部字符串是相同的)

        通过getimagesize()来判断是否是图片的话,会存在问题,我们可以为伪造图片片头(即在我们所发送文件的十六进制代码中,修改开头,使得其被该函数识别为图片)

(2)漏洞解析

1、下载一张.png的图片,使用十六进制查看器查看(这里我使用的是HexViewer)

可以看到,该图片的第一行十六进制字符串为:8950 4e47 0d0a 1a0a 0000 000d 4948 4452

实际上,.png图片的第一行十六进制字符串均为这个,这便是.png图片的片头

只要我们文件是以 8950 4e47开头的, getimagesize()函数就会将我们的文件识别为图片

(3)利用漏洞制作图片木马

方法 1:直接伪造头部 GIF89A
方法 2(在window下)CMD: copy /b test.png + muma.php cccc.png
方法 3. 使用 GIMP(开源的图片修改软件),通过增加备注,写入执行命令

(4)操作(使用方法2)

1、在桌面上准备文件:boy.jpg 、 phpinfo.php

2、在桌面打开shell终端,输出cmd,进入cmd模式:

3、输入以下命令,生成包含木马的恶意图片  phpboy.jpg:

copy /b boy.jpg + phpinfo.php phpboy.jpg

此时,桌面上会多出一个文件:

4、使用十六进制查看器查看(这里我使用的是HexViewer)

可以看到,该恶意图片前面的十六进制代码与先前的boy.jpg没有区别,但在末尾加上了我们添加的恶意代码

5、进入pikachu靶场,进入 Unsafe Fileupload -->getimagesize,将该恶意图片上传成功

6、验证

为了验证我们添加的恶意代码会起到作用,我们进行以下步骤:

首先,我们记录下恶意文件的路径:

将上级目录:localhost:81/pikachu/vul/unsafeupload

和保存路径:uploads/2025/06/24/917452685a30041c3d9354923935.jpg

结合,就得到了该恶意图片的绝对路径

然后,我们返回到File Inclusion-->File Inclusion(local),先选择任意NBA player提交:

然后将filename修改为恶意文件的相对路径:

经此比对,可得相对路径为:unsafeupload/uploads/2025/06/24/917452685a30041c3d9354923935.jpg

修改后回车,发现报错:

这是说明路径还是有问题,这时通过以下措施来解决:

在相对路径前加上若干个 ../  层层回溯目录

最终在回溯额两层目录后,路径正确:

可以看到,包含了的这个恶意图片,除了显示自身的代码外,还执行了我们加入的phpinfo.php中的恶意代码,说明成功

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐