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.1Host: 192.168.0.106Content-Length: 199Cache-Control: max-age=0Upgrade-Insecure-Requests: 1Origin: http://192.168.0.106Content-Type: multipart/form-data; boundary=----WebKitFormBoundarymrijfqP5su2sSW5YUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36Accept: 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.9Referer: http://192.168.0.106/study/wjsc/sc.phpAccept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9Connection: close------WebKitFormBoundarymrijfqP5su2sSW5YContent-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
执行成功!
在墨者学院的在线靶场中也存在一样的漏洞靶场可以帮助快速了解这个漏洞
来源地址:https://blog.csdn.net/m0_52361291/article/details/125902327
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341