您现在的位置是:首页 > cms教程 > phpcms教程phpcms教程
PHPCMSv9.6.1任意文件读取漏洞分析
春雁2025-05-15phpcms教程已有6人查阅
导读PHPCMS使用教程介绍PHPCMSv9.6.1任意文件读取漏洞的挖掘看到网上说出了这么一个漏洞,所以抽空分析了下,得出本篇分析。1.准备工作&漏洞关键点快速扫描
PHPCMS使用教程介绍PHPCMSv9.6.1任意文件读取漏洞的挖掘
看到网上说出了这么一个漏洞,所以抽空分析了下,得出本篇分析。
1.准备工作&漏洞关键点快速扫描
1.1前置知识
这里把本次分析中需要掌握的知识梳理了下:
php原生parse_str方法,会自动进行一次urldecode,第二个参数为空,则执行类似extract操作。
原生empty方法,对字符串""返回true。
phpcms中sys_auth是对称加密且在不知道auth_key的情况下理论上不可能构造出有效密文。
1.2快速扫描
先diff下v9.6.0和v9.6.1,发现phpcms/modules/content/down.php中有如下修改:
---a/phpcms/modules/content/down.php
+++b/phpcms/modules/content/down.php 主要修改了两个方法init()和download(),大胆的猜想估计是这两个函数出问题了。 safe_replace函数如下 1.2content/down模块大致流程分析
init方法中根据原始的$a_k(包含了file_down的文件的基本信息),进行一次验证,并且生成,调用
download方法的url,url的schema为$downurl='?m=content&c=down&a=download&a_k='.$a_k(必须符合条件。)
download方法接收到$a_k,进行解码,解出文件信息,调用file_down($fileurl,$filename)(必须符合条件)
我们来看下file_down函数,头一个参数$filepath,才是实际控制readfile的文件名的变量,readfile可以读取本地文件,所以我们构造符合条件的$fileurl绕过上述的限制就可以完成本地文件的读取功能! 1.2.1$fileurl变量构造分析
如果我们要读取站点的.php结尾文件,由于有关键点11存在,$fileurl中不能出现php,不过从关键点17可以看到进行了替换 那么可以想到我们构造出符合.ph([]+)p的文件后缀,最后会被替换成.php。而且这句话是9.6.1新增的,更加确定了,这个漏洞是9.6.1特有的。
再向上上看 变量$m为真,那么我们可以通过引入变量$s来构造$fileurl,且$fileurl由变量$f控制。 通过parse_str来extract变量,很容易的得出控制$i,$m,$f,$t,$s,$d,$modelid变量,看到这里我们可以构造$a_k来控制这些变量。
1.2.2$a_k变量分析
再向上看 这个关键点6很重要,因为这里的$pc_auth_key几乎是不可能暴力出来的,然而得到这个加密的$a_k只有在init()方法中使用了相同的$pc_auth_key。所以我们只能通过init()方法来构造$a_k。
我们现在来看下init方法 这里可以发现sys_auth的auth竟然是使用系统默认的auth_key,直觉告诉我可能问题出在这里了,除了这个区别,init方法别的逻辑就不再赘述。
1.2.3小结
总结一下:
index.php?m=content&c=down&a=init&a_k=想办法构造出符合条件的。
然后init方构造出符合download方法中能够解密的$a_k。
通过对$a_k进行控制,间接控制$i,$f,$m,$s,$d等变量完成漏洞的利用。
2.漏洞挖掘过程2.1init方法所接受的$a_k构造2.1.1探索正常流程中的$a_k构造过程
对源码进行快速扫描,看看哪些地方能够生产对init方法的调用,其实就是常规的下载模型的逻辑。
phpcms/modules/content/fields/downfile和phpcms/modules/content/fields/downfiles中会生成init方法的$a_k 但是分析发现,content_input和content_output逻辑中权限验证和限制逻辑比较完善,基本不存在利用可能。
2.1.2黑科技构造$a_k
由于是sys_auth是对称加密,那么能不能找个使用相同密钥生成的地方来生成,对sys_auth进行全文搜索,我们找找有没有符合下列条件的上下文
方式是ENCODE
Auth_key是系统默认的即:pc_base::load_config('system','auth_key')
且待加密内容是可控的(可以是我们$_REQUEST的数据,或者可以构造的)
加密后的数据有回显的。
共找到58个匹配项,但是没有符合上下文的,不过我们可以注意到 param::set_cookieparam::get_cookie对cookie加密是使用默认的auth_key的。
马上对set_cookie进行全文搜索,并且查找符合下列条件的上下文。
set_cookie的内容是可控的。
set_cookie的触发条件尽可能的限制小。
一共找到122个匹配项,找到了两个比较好的触发点。
phpcms/moduels/attachment/attachments.php中的swfupload_json/swfupload_del方法和phpcms/modules/video/video.php中的swfupload_json/del方法
video模块需要管理员权限,就不考虑了,attachment模块只要是注册用户即可调用。
我们来看下swfupload_json 我们可以通过src和filename来构造,最终我选的是src,最终形式会是一个json串,当然有多个会以"||"分割。
我们注册个用户登录之后,调用 产生的数据会是 然后我们得到response.header中的set-cookie["att_json"]。 我们修改下down.php->init方法,把DECODE之后的$a_k输出来。
然后我们调用 激动人心,init方法成功DECODE了$a_k
好了目前验证了我们的想法可行,接下来应该构造可用的payload了。
2.2json和parse_str
目前要解决的就是从json中parse_str并且能够解析出$i,$m,$f等变量。 解析 说明parse_str还是解析还是可以实现的,前后闭合一下,中间填充我们需要的变量即可,例如 那么fobnn和p1就是正常解析的,src需要URLENCODE提交,这样不会导致php解析错误。
2.3构造符合init方法的$a_k
我们先构造一个符合init方法的$a_k使得能完成正常的流程。 构造pad=x&i=1&modelid=1&m=1&catid=1&f=fobnn&pade=用来满足条件。 得到 然后提交 成功!页面已经生成了调用download方法的url 2.4绕过限制构造最终payload
目前正常流程已经走通,把目光集中在如何构造出符合的$fileurl,来看下init方法中 对f的限制还是蛮多的,包括常规黑名单检测php,asp等。也不能出现"..",":"
还好我们看到download函数中 我们可以通过控制$m就可以通过$s来构造了,而$m和$s参与了$a_k的构造。
在init方法中我们可以构造m=1&s=.php&f=index类似的来绕过init方法的检测,我们把目光聚焦到download方法。 通过这样的构造上面这个检测肯定可以绕过,但发现下面检测就会出问题,最后$fileurl还是会变成index.php 好在快速扫描中看到的 另外又看到 2.4.1urlencode编码“”
那么构造出 最终 由于safe_replce的存在所以
所以可以构造
d=1&m=1&f=.p%3chp&s=index
我们发现在init方法中会safe_replace一次,和parse_str一次。
那么最终编码到download$a_k中的数据实际还是
所以我们要确保在init方法编码的时候是%3c即可,对%3c进行一次urlencode,构造 当然要读取别的目录的,那同样对目录路径进行编码。
2.4.2最终payload
以读取首页index.php为例 最终提示下载文件,文件下载成功,打开来看确实是index.php内容。
2.5绕过attachment模块权限限制完成制利用 可以发现 可控制$this->userid且没有复杂的权限校验,而且又是默认AUTH_KEY加密的。
全文找下制可以set_cookie的,发现WAP模块可以利用 没有任何条件限制我们可以$_GET['siteid']来控制param::set_cookie('siteid',$this->siteid),且默认都有WAP模块的文件,但不需要开启。
3.EXP编写
流程如下:
index.php?m=wap&c=index&siteid=1获取名称为siteid的cookie。
访问index.php?m=attachment&c=attachments&a=swfupload_json&aid=1
&src=想要读取文件的payload,并且访问的时候设置post字段userid_flash为步骤一获取的cookie.
响应成功之后,获取名称为att_json的cookie
访问index.php?m=content&c=down&a=init&a_k=获取到的att_json,来构造最终漏洞利用路径,
可以直接截取生成的$a_k
访问index.php?m=content&c=download&a=init&a_k=截取的$a_k.完成利用。
4.修案
init方法中的$a_k加解密sys_auth不要采用默认密钥。
file_down之前对$fileurl再做一次过滤。
看到网上说出了这么一个漏洞,所以抽空分析了下,得出本篇分析。
1.准备工作&漏洞关键点快速扫描
1.1前置知识
这里把本次分析中需要掌握的知识梳理了下:
php原生parse_str方法,会自动进行一次urldecode,第二个参数为空,则执行类似extract操作。
原生empty方法,对字符串""返回true。
phpcms中sys_auth是对称加密且在不知道auth_key的情况下理论上不可能构造出有效密文。
1.2快速扫描
先diff下v9.6.0和v9.6.1,发现phpcms/modules/content/down.php中有如下修改:
---a/phpcms/modules/content/down.php
+++b/phpcms/modules/content/down.php 主要修改了两个方法init()和download(),大胆的猜想估计是这两个函数出问题了。 safe_replace函数如下 1.2content/down模块大致流程分析
init方法中根据原始的$a_k(包含了file_down的文件的基本信息),进行一次验证,并且生成,调用
download方法的url,url的schema为$downurl='?m=content&c=down&a=download&a_k='.$a_k(必须符合条件。)
download方法接收到$a_k,进行解码,解出文件信息,调用file_down($fileurl,$filename)(必须符合条件)
我们来看下file_down函数,头一个参数$filepath,才是实际控制readfile的文件名的变量,readfile可以读取本地文件,所以我们构造符合条件的$fileurl绕过上述的限制就可以完成本地文件的读取功能! 1.2.1$fileurl变量构造分析
如果我们要读取站点的.php结尾文件,由于有关键点11存在,$fileurl中不能出现php,不过从关键点17可以看到进行了替换 那么可以想到我们构造出符合.ph([]+)p的文件后缀,最后会被替换成.php。而且这句话是9.6.1新增的,更加确定了,这个漏洞是9.6.1特有的。
再向上上看 变量$m为真,那么我们可以通过引入变量$s来构造$fileurl,且$fileurl由变量$f控制。 通过parse_str来extract变量,很容易的得出控制$i,$m,$f,$t,$s,$d,$modelid变量,看到这里我们可以构造$a_k来控制这些变量。
1.2.2$a_k变量分析
再向上看 这个关键点6很重要,因为这里的$pc_auth_key几乎是不可能暴力出来的,然而得到这个加密的$a_k只有在init()方法中使用了相同的$pc_auth_key。所以我们只能通过init()方法来构造$a_k。
我们现在来看下init方法 这里可以发现sys_auth的auth竟然是使用系统默认的auth_key,直觉告诉我可能问题出在这里了,除了这个区别,init方法别的逻辑就不再赘述。
1.2.3小结
总结一下:
index.php?m=content&c=down&a=init&a_k=想办法构造出符合条件的。
然后init方构造出符合download方法中能够解密的$a_k。
通过对$a_k进行控制,间接控制$i,$f,$m,$s,$d等变量完成漏洞的利用。
2.漏洞挖掘过程2.1init方法所接受的$a_k构造2.1.1探索正常流程中的$a_k构造过程
对源码进行快速扫描,看看哪些地方能够生产对init方法的调用,其实就是常规的下载模型的逻辑。
phpcms/modules/content/fields/downfile和phpcms/modules/content/fields/downfiles中会生成init方法的$a_k 但是分析发现,content_input和content_output逻辑中权限验证和限制逻辑比较完善,基本不存在利用可能。
2.1.2黑科技构造$a_k
由于是sys_auth是对称加密,那么能不能找个使用相同密钥生成的地方来生成,对sys_auth进行全文搜索,我们找找有没有符合下列条件的上下文
方式是ENCODE
Auth_key是系统默认的即:pc_base::load_config('system','auth_key')
且待加密内容是可控的(可以是我们$_REQUEST的数据,或者可以构造的)
加密后的数据有回显的。
共找到58个匹配项,但是没有符合上下文的,不过我们可以注意到 param::set_cookieparam::get_cookie对cookie加密是使用默认的auth_key的。
马上对set_cookie进行全文搜索,并且查找符合下列条件的上下文。
set_cookie的内容是可控的。
set_cookie的触发条件尽可能的限制小。
一共找到122个匹配项,找到了两个比较好的触发点。
phpcms/moduels/attachment/attachments.php中的swfupload_json/swfupload_del方法和phpcms/modules/video/video.php中的swfupload_json/del方法
video模块需要管理员权限,就不考虑了,attachment模块只要是注册用户即可调用。
我们来看下swfupload_json 我们可以通过src和filename来构造,最终我选的是src,最终形式会是一个json串,当然有多个会以"||"分割。
我们注册个用户登录之后,调用 产生的数据会是 然后我们得到response.header中的set-cookie["att_json"]。 我们修改下down.php->init方法,把DECODE之后的$a_k输出来。
然后我们调用 激动人心,init方法成功DECODE了$a_k
好了目前验证了我们的想法可行,接下来应该构造可用的payload了。
2.2json和parse_str
目前要解决的就是从json中parse_str并且能够解析出$i,$m,$f等变量。 解析 说明parse_str还是解析还是可以实现的,前后闭合一下,中间填充我们需要的变量即可,例如 那么fobnn和p1就是正常解析的,src需要URLENCODE提交,这样不会导致php解析错误。
2.3构造符合init方法的$a_k
我们先构造一个符合init方法的$a_k使得能完成正常的流程。 构造pad=x&i=1&modelid=1&m=1&catid=1&f=fobnn&pade=用来满足条件。 得到 然后提交 成功!页面已经生成了调用download方法的url 2.4绕过限制构造最终payload
目前正常流程已经走通,把目光集中在如何构造出符合的$fileurl,来看下init方法中 对f的限制还是蛮多的,包括常规黑名单检测php,asp等。也不能出现"..",":"
还好我们看到download函数中 我们可以通过控制$m就可以通过$s来构造了,而$m和$s参与了$a_k的构造。
在init方法中我们可以构造m=1&s=.php&f=index类似的来绕过init方法的检测,我们把目光聚焦到download方法。 通过这样的构造上面这个检测肯定可以绕过,但发现下面检测就会出问题,最后$fileurl还是会变成index.php 好在快速扫描中看到的 另外又看到 2.4.1urlencode编码“”
那么构造出 最终 由于safe_replce的存在所以
所以可以构造
d=1&m=1&f=.p%3chp&s=index
我们发现在init方法中会safe_replace一次,和parse_str一次。
那么最终编码到download$a_k中的数据实际还是
所以我们要确保在init方法编码的时候是%3c即可,对%3c进行一次urlencode,构造 当然要读取别的目录的,那同样对目录路径进行编码。
2.4.2最终payload
以读取首页index.php为例 最终提示下载文件,文件下载成功,打开来看确实是index.php内容。
2.5绕过attachment模块权限限制完成制利用 可以发现 可控制$this->userid且没有复杂的权限校验,而且又是默认AUTH_KEY加密的。
全文找下制可以set_cookie的,发现WAP模块可以利用 没有任何条件限制我们可以$_GET['siteid']来控制param::set_cookie('siteid',$this->siteid),且默认都有WAP模块的文件,但不需要开启。
3.EXP编写
流程如下:
index.php?m=wap&c=index&siteid=1获取名称为siteid的cookie。
访问index.php?m=attachment&c=attachments&a=swfupload_json&aid=1
&src=想要读取文件的payload,并且访问的时候设置post字段userid_flash为步骤一获取的cookie.
响应成功之后,获取名称为att_json的cookie
访问index.php?m=content&c=down&a=init&a_k=获取到的att_json,来构造最终漏洞利用路径,
可以直接截取生成的$a_k
访问index.php?m=content&c=download&a=init&a_k=截取的$a_k.完成利用。
4.修案
init方法中的$a_k加解密sys_auth不要采用默认密钥。
file_down之前对$fileurl再做一次过滤。
本文标签:
很赞哦! (2)
上一篇:phpcms安全漏洞归类整理
下一篇:PHPCMS常用调用语法总结示例
暂无内容 |
暂无内容 |
相关源码
-
(自适应)黑色摄影作品工作室pbootcms模板网站源码下载为风景摄影、个人工作室打造的高端网站模板,基于PbootCMS开源内核开发,采用HTML5自适应架构,PC与移动端实时数据同步,完美适配各类拍摄作品展示需求。查看源码
-
pbootcms网站模板响应式全屏旅游景区网站源码本模板为风景民宿、旅游景区等企业设计,基于PbootCMS内核开发,具备响应式布局与专业SEO优化功能,助力企业低成本高效获客。以下是核心特点:查看源码
-
响应式艺考培训学校机构pbootcms模板html5源码基于PbootCMS免费开源内核开发,官方授权可商业使用无授权费用。为艺考培训学校与艺术机构设计,替换图文即可快速适配全行业需求。响应式布局完美兼容手机/PC端查看源码
-
快递物流公司pbootcms网站模板html响应式自适应源码下载基于HTML5+CSS3前沿技术开发,实现PC、平板、手机多端完美自适应。采用弹性布局与媒体查询技术,确保不同设备均有流畅视觉体验,企业形象统一。查看源码
-
(pc+wap)pbootcms网站模板蓝色小程序网站开发公司基于PbootCMS内核开发的营销型门户模板,为小程序开发公司、电商软件企业打造。采用HTML5自适应架构,实现PC与手机端数据实时同步展示查看源码
-
(PC+WAP)生活资讯百科新闻门户类pbootcms网站模板为生活资讯、百科门户类企业打造的高性能网站模板,基于PbootCMS开源内核开发,采用HTML5响应式架构,PC与手机端实时数据同步,覆盖全终端用户浏览场景。查看源码
相关教程
暂无内容 |
暂无内容 |
图文教程
phpcms可以进入主页却进不了后台管理的修改方法
phpcms v9成功安装,安装过程中也没有错误,但是能进入主页却进不了后台管理。解决方法如下:1、打开项目文件夹\caches\configs里的system.php文件中;phpcms v9安装失败报错Message : Can not connect to MySQL server
在安装PHPCMS V9的时候,要求设置caches目录权限为777。首先需要用FTP选择caches目录,然后右击属性,把:应用到所有子文件夹和子文件勾选,权限都777。设置完成以后PHPCMS搬家的方法教程
首先打开“caches/configs/database.php”;然后修改里边配置信息;接着也将“phpsso_server/cache/configs/database.php”也进行修改;phpcmsv9怎么修改域名
网站在发展的过程中,很可能多次的修改域名。那么在phpcms v9中我们要怎么进行设置呢?请进行以下步骤的修改:
分享笔记 (共有 0 篇笔记) |