介绍
Joomla是一套全球知名的内容管理系统。 Joomla是使用PHP语言加上MySQL数据库所开发的软件系统,最新版本是4.2.8 。可以在Linux、Windows、MacOSX等各种不同的平台上执行。
影响版本
漏洞复现
文档下载地址,当前选择的版本为4.2.5
小皮搭建
Apache+mysql

配置数据

设置数据库,完成安装

后台路径administrator
,安装时要求php版本为7.2
以上。
漏洞路径
/api/index.php/v1/config/application?public=true
/api/index.php/v1/xxxxx/xxx/xxx?public=true //未授权的路径为v1下的多个url

泄露数据库账号密码以及数据库名称和前缀

分析
选择适合自己的php版本的xdebug安装调式即可,直接下断点,没啥需要必坑的,只是joomla的安装版本要求大于7.2.x,所以安装xdebug的时候注意使用xdebug3
[XDebug]
zend_extension = "D:\phpstudy_pro\Extensions\php\php7.3.4nts\ext\php_xdebug-3.1.6-7.3-vc15-nts-x86_64.dll"
xdebug.mode=debug
xdebug.start_with_request=default
xdebug.client_host=localhost
;;;特别注意这个地方是client_port,而xdebug2中是remote_port
xdebug.client_port=9001
xdebug.remote_handler=dbgp
xdebug.idekey="PHPSTORM"
\api\index.php

includes/app.php
按步调试

F7跟进libraries\src\Application\CMSApplication.php

调用CMSApplication
的execute方法

跟进F7\libraries\src\Application\ApiApplication.php

107行调用了route方法

在这里控制层的路由一起请求方法开始传入,一直往下跟就行了,239行F7

在ApiApplication.php
的route方法开始查询路由,在方法parseApiRoute
中获取到url以及对应的路由信息

上图可以看到当调试到$route->getDefaults
位置的时候默认的Public=>false
,在102行看到通过方法getQuery
获取到url中的public=true

111行的时候获取的也是默认的false

调试之后发现在执行玩116行的时候,public的默认值false
就被覆盖掉变为了true

这里需要了解函数array_merge
array_merge():将两个或多个数组的单元合并起来,一个数组中的值附加在前一个数组的后面。返回作为结果的数组。如果输入的数组中有相同的字符串键名,则该键名后面的值将覆盖前一个值。然而,如果数组包含数字键名,数字键名对应的值将不会覆盖原来的值,而是按照值对数字索引部分重新排序。
这里返回的为字符串,不是数字键名,所以产生了传入的true
覆盖掉了false
值。
而当public=true
时,调式发现在ApiApplication.php
的296行就是对身份做校验,验证是否public为false

而当public=true
时,直接满足第一层if
条件完成Authentication
。所以这里未授权的api路径不唯一,满足public=true绕过鉴权。