WebWall-09.Unsafe file uploads(不安全的文件上传)
概述
文件上传功能在web应用系统很常见,比如很多网站注册的时候需要上传头像,附件等等。当用户点击上传按钮后,后台会对上传的文件进行判断,比如是否是指定的类型、后缀名、大小等等,然后将其按照设计的格式重命名后存储在指定的目录,如果说后台对上传的文件没有进行任何的安全判断或者判断的条件不够严谨,则攻击者可能会上传一些恶意的文件,从而导致服务器权限被获取。
文件上传漏洞测试流程
- 对文件上传的地方按照要求上传文件,查看返回结果(路径,提示);
- 尝试上传不同类型的“恶意”文件,比如xx.php文件,分析结果;
- 查看html源码,看是否通过js在前端做了限制,可以绕过;
- 尝试使用不同方式进行绕过:黑名单绕过/MIME类型绕过/目录0x00截断绕过
- 猜测或者结合其他的漏洞得到程序路径,连接测试
实验测试
chient check
如果上传其他文件,会提示我们只允许上传图片
但是我们打开F12看到,这里的JS调用了一个checkFileExt的方法
这个方法在后面也找得到,大致的意思就是判断文件的扩展名是不是为jpg、png、gif。我们知道这种前端的限制只能起到辅助作用,起不到实质性的作用,我们只需要把之前那个input标签的onchange的属性删除,让上传的时候触发不了这个方法,就可以达到我们上传的目的
补充:新版本的浏览器屏蔽了一下非法的操作,我们可以使用其他的老浏览器实现这个功能
然后我们上传我们的php一句话脚本
上传的脚本内容
<?php
/**
* Created by runner.han
* There is nothing new under the sun
*/
phpinfo();
?>
访问路径,测试一下我们的脚本是否能执行
http://127.0.0.1/pikachu/vul/unsafeupload/uploads/phpinfo.php
MIME
MIME意为多目Internet邮件扩展,它设计的最初目的是为了在发送电子邮件时附加多媒体数据,让邮件客户程序能根据其类型进行处理。然而当它被HTTP协议支持之后,它的意义就更为显著了。它使得HTTP传输的不仅是普通的文本,而变得丰富多彩。
每个MIME类型由两部分组成,前面是数据的大类别,例如声音audio、图象image等,后面定义具体的种类。
常见的MIME类型
超文本标记语言文本 .html,.html text/html
普通文本 .txt text/plain
RTF文本 .rtf application/rtf
GIF图形 .gif image/gif
JPEG图形 .ipeg,.jpg image/jpeg
php里有一个$_files函数来获取请求头里面的Content-Type
因此,我们只需要用抓包修改请求头里Content-Type的值
$_FILES数组内容如下:
$_FILES['myFile']['name'] 客户端文件的原名称。
$_FILES['myFile']['type'] 文件的 MIME 类型,需要浏览器提供该信息的支持,例如"image/gif"。
$_FILES['myFile']['size'] 已上传文件的大小,单位为字节。
$_FILES['myFile']['tmp_name'] 文件被上传后在服务端储存的临时文件名,一般是系统默认。可以在php.ini的upload_tmp_dir 指定,但 用 putenv() 函数设置是不起作用的。
$_FILES['myFile']['error'] 和该文件上传相关的错误代码。
修改为
Content-Type: image/png
就可以绕过验证
getimagesize
getimagesize()这个函数返回结果中有文件大小和文件类型,如果用这个函数来获取类型,从而判断是否是图片的话,会存在问题
我们可以伪造图片头
[root@template ~]# ll
1.png phpinfo.php 2.png
先查看一下他们的图片头
用linux的xxd命令
[root@template ~]# xxd 1.png | head -n 1
0000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452 .PNG........IHDR
[root@template ~]# xxd 2.png | head -n 1
0000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452 .PNG........IHDR
发现png图片的头部十六进制都一样
那我们可以用windows的cmd命令把一张图片和一个php文件合起来变成一个文件
安排一手
D:>copy /b 1.png + phpinfo.php xxx.png
1.png
phpinfo.php
已复制 1 个文件。
选择两个文件,合成一个新的文件叫xxx.png , 表面上看还是这个图片
发现前面还是正常的图片,但是在最后跟上了我们的一句话木马
还需要了解的是
PHP的文件包含
include在发现错误的时候会继续执行后面的代码
当遇到我们的png的时候,会一直往下读取,执行到我们的一句话的时候就会正确执行
测试后把这半条代码删除就可以正常上传
成功上传了我们的xxx.png,我们来访问一下,发现可以正常访问,但是,他是一个png
那么我们要这么才能让他执行里面的php代码呢
就要用到我们之前的文件包含漏洞
那就要让本地文件包含漏洞找到我们的png图片
http://127.0.0.1/pikachu/vul/fileinclude/fi_local.php?filename=../../unsafeupload/uploads/2022/08/26/9160096307a32e090b992237754.png&submit=%E6%8F%90%E4%BA%A4
这里使用windows达不到实验效果,需要使用liunx部署,需要猜测哪个目录能访问我们图片所在的路径,经测试我们可以用这个路径访问到我们的phpinfo
防范文件上传漏洞的方法
- 不要再前端进行限制
- 再服务端验证文件类型、后缀名、大小,文件完整,文件类型
- 验证文件的上传方式
- 对文件进行一定复杂的重命名
- 不要暴露文件上传后的路径