前言
CMS下载地址:http://down.chinaz.com/soft/39285.htm。
thinkphp5.1.* 反序列化漏洞
该CMS使用的thinkphp5.1.33进行的二次开发,我们知道thinkphp5.1.*和thinkphp5.2.*
存在反序列化漏洞。如果满足下面其中一个条件就会产生该漏洞:
- 需要一个二次开发反序列化的利用点
- 存在文件上传、文件名完全可控、使用了文件操作函数,例如: file_exists(‘phar://恶意文件’)
具体漏洞分析可以参考文章:https://xz.aliyun.com/t/6619#toc-0
这里就存在可控的反序列化点,我们全局搜索关键词unserialize
可以看到其在不少地方进行反序列,并且可以看出数据是在cookie中获取用户可操控。
认真查看发现其基本都在user
的模型中,这里挑其中一处来分析application/user/model/Recentread.php
,注意cookie键值前面有一个前缀lf_
,在config/cookie.php
可以查看。
1 | public function info($id){ |
可以看到符合我们的反序列的条件,这里我们使用thinkphp5.1.* 反序列化的payload试试:
1 |
|
首先需要在前台注册一个用户,然后发送我们的payload过去:
1 | GET /user/recentread/ HTTP/1.1 |
可以看到成功执行我们的命令:
权限认证绕过
该CMS权限认证这里非常容易绕过,我们来看看其权限认证代码application/common.php
1 | /** |
首先通过cookie中的lf_user_auth和lf_user_auth_sign
获取用户的基本信息($user
)和用户数据凭证($user_sign
),然后通过把用户信息使用data_auth_sign
函数处理出来的凭证和cookie取出的$user_sign
进行匹配看是否匹配,如果匹配成功放回用户的uid
表示已经登录,否则放回0表示未登录。
其中lf_user_auth
的格式为:think:{“uid”:”1”,”username”:”EASY”},明文可控制。
我们来看看数据签名认证方法data_auth_sign
1 | /** |
首先判断是否是数组,然后按照键名对关联数组进行升序排序,然后生成 URL-encode 之后的请求字符串。
此时$code的格式为:uid=1&username=EASY
然后使用sha1
进行加密。从上面分析我们可以得到以下结论:
- 1.只要获取uid和username我们就可以自已伪造签名
- 2.uid和username都是从cookie
lf_user_auth
中获取并且我们可控。 - 3.因为认证结果放回的是用户的
uid
所以其实我们甚至不需要知道用户名只需要尝试uid值构造对应的签名就可以登录到对应的账号中。
我们来测试一下上面的猜想:
首先构造lf_user_auth为think:{"uid":"1","username":"23333"}
其中username随意uid真实存在就行了(其实uid不存在也行不过登录后后台什么数据都没有罢了)。注意数据要进行URL编码
构建lf_user_auth_sign
值:只需要把字符uid=1&username=23333
使用sha1加密函数加密一下就好。payload如下:
1 | lf_user_auth=%74%68%69%6E%6B%3A%7B%22%75%69%64%22%3A%22%31%22%2C%22%75%73%65%72%6E%61%6D%65%22%3A%22%32%33%33%33%33%22%7D |
成功登录上EASY的账号中。
前台无限制RCE
结合起来即可前台RCE。最终payload:
1 | GET /user/recentread/ HTTP/1.1 |
- 本文作者: EASY
- 本文链接: http://example.com/2020/12/20/狂雨CMS前台RCE/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!