PHP文件上传中fileinfo出现的安全问题

什么是fileinfo

fileinfo的函数通过在文件的给定位置查找特定的魔术字节序列 来猜测文件的内容类型以及编码,也就是说我们可以获得上传文件的MIME信息

在windows中我们可以在php.ini中开启
在这里插入图片描述

extension=fileinfo

在linux中开启fileinfo

找到fileinfo的路径
执行命令:find / -name fileinfo,查询到fileinfo所在目录
执行phpsize命令
执行命令:/usr/local/php/bin/phpize
执行configure配置
执行命令:./configure --with-php-config=/usr/local/php/bin/php-config
注意:如果提示php-config命令不存在,则需要先安装php-devel,执行命令:yum install php-devel。
编译安装
命令:make && make install
修改php.ini文件
在php.ini文件中添加extension=fileinfo.so

在打开fileinfo后我们就可以使用fileinfo扩展了
那fileinfo包括哪些呢
在这里插入图片描述
像如图红圈中的那些都是fileinfo扩展。

fileinfo预定义常量

常量名作用
FILEINFO_NONE无特殊处理
FILEINFO_SYMLINK跟随符号链接
FILEINFO_MIME_TYPE返回 mime 类型。 自 PHP 5.3.0 可用
FILEINFO_MIME_ENCODING返回文件的 mime 编码。 自 PHP 5.3.0 可用
FILEINFO_MIME按照 RFC 2045 定义的格式返回文件 mime 类型和编码
FILEINFO_COMPRESS解压缩压缩文件。 由于线程安全问题,自 PHP 5.3.0 禁用
FILEINFO_DEVICES查看设备的块内容或字符
FILEINFO_CONTINUE返回全部匹配的类型
FILEINFO_PRESERVE_ATIME如果可以的话,尽可能保持原始的访问时间
FILEINFO_RAW对于不可打印字符不转换成 \ooo 八进制表示格式
FILEINFO_EXTENSION根据 MIME 类型返回适当的文件扩展名。 有的文件类型具有多种扩展名,例如 JPEG 将会返回多个扩展名,以斜杠分隔,比如 “jpeg/jpg/jpe/jfif”。如果在 magic.mime 数据库里类型未知,则返回的是 “???”。 PHP 7.2.0 起有效

如何使用fileinfo去过滤上传文件

首先我们要创建一个 fileinfo 资源,然后就可以调用 fileinfo 资源了

$file = $_FILES;
$finfor = finfo_open(FILEINFO_MIME_TYPE);
$info = finfo_file($finfor, $file['jpg']['tmp_name']); //拿上传文件的MIME头与finfo_open()返回mime类型进行比较返回真实的mime头

此时若上传文件是txt文件伪造后的jpg等图片文件则会返回一个txt文件的mime头
那修改掉数据包中的mime头可以绕过吗?
在这里插入图片描述
上面这图就是直接上传的一个txt改jpg图片文件的,可以看到他的mime类型为image/jpeg

POST /study/wjsc/sc.php HTTP/1.1
Host: 192.168.0.106
Content-Length: 199
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://192.168.0.106
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarymrijfqP5su2sSW5Y
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://192.168.0.106/study/wjsc/sc.php
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

------WebKitFormBoundarymrijfqP5su2sSW5Y
Content-Disposition: form-data; name="jpg"; filename=".jsp.jpg"
Content-Type: image/jpeg

<?php phpinfo();?>
------WebKitFormBoundarymrijfqP5su2sSW5Y--

看一下上传后的效果
在这里插入图片描述
提示不合法,可以看一下返回的mime类型
在这里插入图片描述
返回为text/x-php类型。

如何去绕过fileinfo检测

这样写看似安全,但是由于fileinfo的检测原理恰恰会出现安全漏洞。
首先,先上传一个正常的图片
在这里插入图片描述
提示合法。
那接下来若上传的是一个图片马呢
图片马的合成
在这里插入图片描述
提示合法,可以看到mime类型也是image/png,那由此可见fileinfo也不是无敌的。
在这里插入图片描述
接下来就是思考正常的图片与伪造过后的图片有哪些不一样,在一张图片中大概是由文件头和内容组成那伪造的图片除了内容以外就是文件头的问题了
在伪造的文件中加上GIF89a,然后上传。
在这里插入图片描述
可以看到提示合法
在这里插入图片描述
就这样就绕过了fileinfo的检测
方便实验我将文件后缀改成了.php
在这里插入图片描述
执行成功!
在墨者学院的在线靶场中也存在一样的漏洞靶场可以帮助快速了解这个漏洞

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
<?php /**  * Upload  *  * @author      Josh Lockhart <info@joshlockhart.com>  * @copyright   2012 Josh Lockhart  * @link        http://www.joshlockhart.com  * @version     2.0.0  *  * MIT LICENSE  *  * Permission is hereby granted, free of charge, to any person obtaining  * a copy of this software and associated documentation files (the  * "Software"), to deal in the Software without restriction, including  * without limitation the rights to use, copy, modify, merge, publish,  * distribute, sublicense, and/or sell copies of the Software, and to  * permit persons to whom the Software is furnished to do so, subject to  * the following conditions:  *  * The above copyright notice and this permission notice shall be  * included in all copies or substantial portions of the Software.  *  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */ namespace Upload; /**  * FileInfo Interface  *  * @author  Josh Lockhart <info@joshlockhart.com>  * @since   2.0.0  * @package Upload  */ interface FileInfoInterface {     public function getPathname();     public function getName();     public function setName($name);     public function getExtension();     public function setExtension($extension);     public function getNameWithExtension();     public function getMimetype();     public function getSize();     public function getMd5();     public function getDimensions();     public function isUploadedFile(); } File Upload 是一款非常强大的文件上传处理插件,支持多文件上传,拖拽上传,进度条,文件验证及图片音视频预览,跨域上传等等。可以说你能想到的功能它都有。你没想到的功能它也有。。不过由于功能太强大,使用起来还是需要点基本功,否则调试开发会遇到困难。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值